Skip to content

Commit

Permalink
fix: always generate themes in frontend 'generated' directory subfold…
Browse files Browse the repository at this point in the history
…er (#14144) (CP: 23.0) (#14156)

Forces generated themes files to be stored in 'generated' folder under
frontend directory, instead of using the 'generatedTsFolder' setting.
Also fixes relative paths assuming frontend directory to be './frontend',
and maven and gradle plugins to clean the 'frontendDirectory/generated' folder.

Fixes #12880
  • Loading branch information
vaadin-bot committed Jul 11, 2022
1 parent f9cd173 commit 998e208
Show file tree
Hide file tree
Showing 44 changed files with 1,208 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.vaadin.gradle

import com.vaadin.flow.server.Constants
import com.vaadin.flow.server.InitParameters
import elemental.json.JsonObject
import elemental.json.impl.JsonUtil
Expand Down Expand Up @@ -168,4 +167,114 @@ class VaadinSmokeTest : AbstractGradleTest() {
expect(false) { tsconfigJson.exists() }
expect(false) { typesDTs.exists() }
}

/**
* Tests that VaadinClean task removes default fronted/generated directory
*/
@Test
fun vaadinCleanDeletesGeneratedFolder() {
val generatedFolder = testProject.newFolder("frontend/generated")
val generatedFile = testProject.newFile("frontend/generated/index.ts")
testProject.build("vaadinClean")
expect(false) { generatedFile.exists() }
expect(false) { generatedFolder.exists() }
}

/**
* Tests that VaadinClean task removes custom fronted/generated directory
*/
@Test
fun vaadinCleanDeletesGeneratedFolderForCustomFrontendFolder() {
testProject.buildFile.writeText("""
plugins {
id 'war'
id 'com.vaadin'
}
repositories {
mavenLocal()
mavenCentral()
maven { url = 'https://maven.vaadin.com/vaadin-prereleases' }
}
dependencies {
compile("com.vaadin:flow:$flowVersion")
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
compile("org.slf4j:slf4j-simple:1.7.30")
}
vaadin {
frontendDirectory = file("src/main/frontend")
}
""")
val generatedFolder = testProject.newFolder("src/main/frontend/generated")
val generatedFile = testProject.newFile("src/main/frontend/generated/index.ts")
testProject.build("vaadinClean")
expect(false) { generatedFile.exists() }
expect(false) { generatedFolder.exists() }
}

/**
* Tests that VaadinClean task removes custom fronted/generated directory
*/
@Test
fun vaadinCleanDeletesGeneratedTsFolder() {
testProject.buildFile.writeText("""
plugins {
id 'war'
id 'com.vaadin'
}
repositories {
mavenLocal()
mavenCentral()
maven { url = 'https://maven.vaadin.com/vaadin-prereleases' }
}
dependencies {
compile("com.vaadin:flow:$flowVersion")
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
compile("org.slf4j:slf4j-simple:1.7.30")
}
vaadin {
generatedTsFolder = file("api")
}
""")
val generatedTsFolder = testProject.newFolder("api/generated")
val generatedFile = testProject.newFile("api/generated/endpoint.ts")
testProject.build("vaadinClean")
expect(false) { generatedFile.exists() }
expect(false) { generatedTsFolder.exists() }
}

/**
* Tests that build works with a custom frontend directory
*/
@Test
fun testCustomFrontendDirectory() {
testProject.buildFile.writeText("""
plugins {
id 'war'
id 'com.vaadin'
}
repositories {
mavenLocal()
mavenCentral()
maven { url = 'https://maven.vaadin.com/vaadin-prereleases' }
}
dependencies {
compile("com.vaadin:flow:$flowVersion")
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
compile("org.slf4j:slf4j-simple:1.7.30")
}
vaadin {
frontendDirectory = file("src/main/frontend")
}
""")
val result: BuildResult = testProject.build("vaadinPrepareFrontend")
// let's explicitly check that vaadinPrepareFrontend has been run.
result.expectTaskSucceded("vaadinPrepareFrontend")

expect(false) {
File(testProject.dir, "frontend/generated/index.ts").exists()
}
expect(true) {
File(testProject.dir, "src/main/frontend/generated/index.ts").exists()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import org.gradle.api.tasks.TaskAction
* Cleans everything Vaadin-related. Useful if npm fails to run after Vaadin
* version upgrade. Deletes:
*
* * `${frontendDirectory}/generated`
* * `${generatedTsFolder}`
* * `node_modules`
* * `package.json`
* * `package-lock.json`
Expand All @@ -42,15 +44,20 @@ import org.gradle.api.tasks.TaskAction
public open class VaadinCleanTask : DefaultTask() {
init {
group = "Vaadin"
description = "Cleans the project completely and removes node_modules, webpack.generated.js, " +
"tsconfig.json, types.d.ts, pnpm-lock.yaml, pnpmfile.js and package-lock.json"
description = "Cleans the project completely and removes 'generated' folders, node_modules, webpack.generated.js, " +
"tsconfig.json, types.d.ts, pnpm-lock.yaml, pnpmfile.js and package-lock.json"

dependsOn("clean")
}

@TaskAction
public fun clean() {
project.delete("${project.projectDir}/node_modules",
val extension: VaadinFlowPluginExtension =
VaadinFlowPluginExtension.get(project)
project.delete(
extension.generatedTsFolder.absolutePath,
extension.frontendDirectory.resolve("generated").absolutePath,
"${project.projectDir}/node_modules",
"${project.projectDir}/package-lock.json",
"${project.projectDir}/webpack.generated.js",
"${project.projectDir}/pnpm-lock.yaml", // used by Vaadin 14.2+ pnpm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ public void execute() throws MojoFailureException {
}
}

// cleanup hard-coded frontend generated folder
// usually it is the same as generatedTsFolder, but if a custom fronted
// folder is set all frontend generated files goes under
// ${frontendDirectory}/generated
File frontendGeneratedFolder = new File(frontendDirectory(),
FrontendUtils.GENERATED);
if (frontendGeneratedFolder.exists()) {
try {
FileUtils.deleteDirectory(frontendGeneratedFolder);
} catch (IOException exception) {
throw new MojoFailureException("Failed to remove folder'"
+ frontendGeneratedFolder.getAbsolutePath() + "'",
exception);
}
}

try {
// Clean up package json framework managed versions.
File packageJsonFile = new File(npmFolder(), "package.json");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,30 @@ public void should_removeFrontendGeneratedFolder()
frontendGenerated.exists());
}

@Test
public void should_removeGeneratedFolderForCustomFrontendFolder()
throws MojoFailureException, IOException, IllegalAccessException {

File customFrontendFolder = new File(projectBase, "src/main/frontend");
File customFrontendGenerated = new File(customFrontendFolder,
"generated");
Assert.assertTrue("Failed to create 'src/main/frontend/generated'",
customFrontendGenerated.mkdirs());
FileUtils.fileWrite(new File(customFrontendFolder, "my_theme.js"),
"fakeThemeFile");

ReflectionUtils.setVariableValueInObject(mojo, "frontendDirectory",
customFrontendFolder);

mojo.execute();
Assert.assertTrue(
"Custom frontend folder 'src/main/frontend' has been removed.",
customFrontendFolder.exists());
Assert.assertFalse(
"Generated frontend folder 'src/main/frontend/generated' was not removed.",
customFrontendGenerated.exists());
}

@Test
public void should_removeNpmPackageLockFile()
throws MojoFailureException, IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -835,8 +835,7 @@ private NodeTasks(Builder builder) {
builder.resourceOutputDirectory,
new File(builder.generatedFolder, IMPORTS_NAME),
builder.useLegacyV14Bootstrap, builder.flowResourcesFolder,
pwaConfiguration, builder.frontendGeneratedFolder,
builder.buildDirectory));
pwaConfiguration, builder.buildDirectory));
}

if (builder.enableImportsUpdate) {
Expand All @@ -851,8 +850,7 @@ private NodeTasks(Builder builder) {

commands.add(new TaskUpdateThemeImport(builder.npmFolder,
frontendDependencies.getThemeDefinition(),
builder.frontendDirectory,
builder.frontendGeneratedFolder));
builder.frontendDirectory));
}

if (builder.copyTemplates) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,14 @@ protected String getFileContent() throws IOException {
FrontendUtils.getUnixRelativePath(buildDirectory.toPath(),
generatedImports.toPath()));

String generatedDirRelativePathToBuildDir = FrontendUtils
.getUnixRelativePath(
getGeneratedFile().getParentFile().toPath(),
buildDirectory.toPath());

relativizedImport = relativizedImport
// replace `./` with `../../target/` to make it work
.replaceFirst("^./", "../../" + buildDirectory.getName() + "/")
.replaceFirst("^./", generatedDirRelativePathToBuildDir + "/")
// remove extension
.replaceFirst("\\.(ts|js)$", "");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.vaadin.flow.theme.ThemeDefinition;

import static com.vaadin.flow.server.Constants.APPLICATION_THEME_ROOT;
import static com.vaadin.flow.server.frontend.FrontendUtils.GENERATED;
import static com.vaadin.flow.server.frontend.FrontendUtils.THEME_IMPORTS_D_TS_NAME;
import static com.vaadin.flow.server.frontend.FrontendUtils.THEME_IMPORTS_NAME;

Expand Down Expand Up @@ -57,10 +58,11 @@ public class TaskUpdateThemeImport implements FallibleCommand {
private final File npmFolder;

TaskUpdateThemeImport(File npmFolder, ThemeDefinition theme,
File frontendDirectory, File frontendGeneratedFolder) {
File frontendDirectory) {
this.theme = theme;
this.frontendDirectory = frontendDirectory;
this.npmFolder = npmFolder;
File frontendGeneratedFolder = new File(frontendDirectory, GENERATED);
themeImportFile = new File(frontendGeneratedFolder, THEME_IMPORTS_NAME);
themeImportFileDefinition = new File(frontendGeneratedFolder,
THEME_IMPORTS_D_TS_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ public class TaskUpdateWebpack implements FallibleCommand {
* bootstrapping
* @param flowResourcesFolder
* relative path to `flow-frontend` package
* @param frontendGeneratedFolder
* the folder with frontend auto-generated files
* @param buildFolder
* build target folder
*/
Expand All @@ -91,7 +89,7 @@ public class TaskUpdateWebpack implements FallibleCommand {
File webpackOutputDirectory, File resourceOutputDirectory,
File generatedFlowImports, boolean useV14Bootstrapping,
File flowResourcesFolder, PwaConfiguration pwaConfiguration,
File frontendGeneratedFolder, String buildFolder) {
String buildFolder) {
this.frontendDirectory = frontendDirectory.toPath();
this.webpackOutputPath = webpackOutputDirectory.toPath();
this.resourceOutputPath = resourceOutputDirectory.toPath();
Expand All @@ -102,7 +100,8 @@ public class TaskUpdateWebpack implements FallibleCommand {
this.pwaConfiguration = pwaConfiguration;
this.resourceFolder = new File(webpackOutputDirectory,
VAADIN_STATIC_FILES_PATH).toPath();
this.frontendGeneratedFolder = frontendGeneratedFolder.toPath();
this.frontendGeneratedFolder = this.frontendDirectory
.resolve(GENERATED);
this.buildFolder = buildFolder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ public void replacedImport_should_beRelativeTo_targetAndFrontend()
String content = taskGenerateIndexTs.getFileContent();
Assert.assertTrue(content.contains(
"import('../../target/frontend/flow-generated-imports'"));

// custom frontend folder
taskGenerateIndexTs = new TaskGenerateIndexTs(
temporaryFolder.newFolder("src", "main", FRONTEND),
generatedImports, outputFolder);
content = taskGenerateIndexTs.getFileContent();
Assert.assertTrue(content.contains(
"import('../../../../target/frontend/flow-generated-imports'"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import com.vaadin.flow.theme.ThemeDefinition;

import static com.vaadin.flow.server.Constants.APPLICATION_THEME_ROOT;
import static com.vaadin.flow.server.frontend.FrontendUtils.DEFAULT_PROJECT_FRONTEND_GENERATED_DIR;
import static com.vaadin.flow.server.frontend.FrontendUtils.DEFAULT_FRONTEND_DIR;
import static com.vaadin.flow.server.frontend.FrontendUtils.FLOW_NPM_PACKAGE_NAME;
import static com.vaadin.flow.server.frontend.FrontendUtils.NODE_MODULES;
Expand All @@ -58,7 +57,6 @@ public class TaskUpdateThemeImportTest {
private File projectRoot;
private File npmFolder;
private File frontendDirectory;
private File frontendGeneratedDirectory;
private File themeImportFile;
private File themeImportTsFile;
private Class<? extends AbstractTheme> dummyThemeClass;
Expand All @@ -70,8 +68,6 @@ public void setUp() throws IOException {
projectRoot = temporaryFolder.getRoot();
npmFolder = temporaryFolder.getRoot();
frontendDirectory = new File(projectRoot, DEFAULT_FRONTEND_DIR);
frontendGeneratedDirectory = new File(projectRoot,
DEFAULT_PROJECT_FRONTEND_GENERATED_DIR);

File frontendFolder = new File(npmFolder,
FrontendUtils.DEFAULT_FRONTEND_DIR);
Expand All @@ -85,7 +81,7 @@ public void setUp() throws IOException {
customTheme = new ThemeDefinition(dummyThemeClass, CUSTOM_VARIANT_NAME,
CUSTOM_THEME_NAME);
taskUpdateThemeImport = new TaskUpdateThemeImport(npmFolder,
customTheme, frontendDirectory, frontendGeneratedDirectory);
customTheme, frontendDirectory);
}

@Test
Expand All @@ -95,8 +91,7 @@ public void taskExecuted_customThemeWithNonExistingThemeFolder_throwsException()
DEFAULT_FRONTEND_DIR);

TaskUpdateThemeImport taskUpdateThemeImportWithNonExistentThemeFolder = new TaskUpdateThemeImport(
npmFolder, customTheme, faultyFrontendDirectory,
frontendGeneratedDirectory);
npmFolder, customTheme, faultyFrontendDirectory);

ExecutionFailedException e = Assert.assertThrows(
ExecutionFailedException.class,
Expand Down Expand Up @@ -216,7 +211,7 @@ public void runTaskWithTheme_createsThemeFile_afterRunWithoutTheme_removesThemeF
assertThemeGeneratedDefinitionFilesExist(SHOULD_EXIST_AFTER_EXECUTION);

taskUpdateThemeImport = new TaskUpdateThemeImport(npmFolder, null,
frontendDirectory, frontendGeneratedDirectory);
frontendDirectory);

taskUpdateThemeImport.execute();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
import com.vaadin.flow.testutil.FrontendStubs;

import static com.vaadin.flow.server.Constants.TARGET;
import static com.vaadin.flow.server.frontend.FrontendUtils.DEFAULT_PROJECT_FRONTEND_GENERATED_DIR;
import static com.vaadin.flow.server.frontend.FrontendUtils.DEFAULT_FLOW_RESOURCES_FOLDER;
import static com.vaadin.flow.server.frontend.FrontendUtils.DEFAULT_GENERATED_DIR;
import static com.vaadin.flow.server.frontend.FrontendUtils.DEFAULT_PROJECT_FRONTEND_GENERATED_DIR;
import static com.vaadin.flow.server.frontend.FrontendUtils.IMPORTS_NAME;
import static com.vaadin.flow.server.frontend.FrontendUtils.SERVICE_WORKER_SRC;
import static com.vaadin.flow.server.frontend.FrontendUtils.SERVICE_WORKER_SRC_JS;
Expand Down Expand Up @@ -169,10 +169,9 @@ public void should_updateOnlyGeneratedWebpack() throws Exception {
TaskUpdateWebpack newUpdater = new TaskUpdateWebpack(frontendFolder,
baseDir, new File(baseDir, "baz"), new File(baseDir, "foo"),
new File(baseDir, "bar"), false,
new File(baseDir,
Paths.get(TARGET, DEFAULT_FLOW_RESOURCES_FOLDER)
.toString()),
pwaConfiguration, frontendGeneratedFolder, TARGET);
new File(baseDir, Paths
.get(TARGET, DEFAULT_FLOW_RESOURCES_FOLDER).toString()),
pwaConfiguration, TARGET);

newUpdater.execute();

Expand Down Expand Up @@ -317,7 +316,7 @@ protected void createWebpackUpdater() {
new File(baseDir,
Paths.get(Constants.TARGET,
DEFAULT_FLOW_RESOURCES_FOLDER).toString()),
pwaConfiguration, frontendGeneratedFolder, TARGET);
pwaConfiguration, TARGET);
}

private void assertWebpackGeneratedConfigContent(String entryPoint,
Expand Down
Loading

0 comments on commit 998e208

Please sign in to comment.