From 8939461887331caf1d23d6bcd0f36f8aad1a5b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sun, 13 Oct 2024 22:58:47 +0200 Subject: [PATCH] fix: lazily run npm install when applying 'prettier' and client modules If a package-lock.json is detected, and npm command is present, run npm install. Fixes #11106 --- .../application/VueApplicationService.java | 7 +- .../vue/core/domain/VueModulesFactory.java | 6 +- .../PrettierApplicationService.java | 9 +- .../domain/PrettierModuleFactory.java | 6 +- .../module/domain/npm/NpmLazyInstaller.java | 10 ++ .../npm/FileSystemNpmLazyInstaller.java | 92 +++++++++++++++++++ .../secondary/npm/NpmErrorKey.java | 18 ++++ .../secondary/npm/NpmInstallException.java | 16 ++++ .../secondary/NpmInstallationType.java | 7 -- .../ProjectFormatterConfiguration.java | 1 + .../secondary/NpmInstallationReader.java | 4 +- .../secondary/NpmInstallationType.java | 7 ++ .../lite/shared/npmdetector/package-info.java | 2 + .../generator-errors-messages.properties | 3 + .../generator-errors-messages_fr.properties | 3 + .../core/domain/VueModulesFactoryTest.java | 22 ++++- .../domain/PrettierModuleFactoryTest.java | 19 +++- .../ProjectFormatterConfigurationTest.java | 6 +- 18 files changed, 215 insertions(+), 23 deletions(-) create mode 100644 src/main/java/tech/jhipster/lite/module/domain/npm/NpmLazyInstaller.java create mode 100644 src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/FileSystemNpmLazyInstaller.java create mode 100644 src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmErrorKey.java create mode 100644 src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmInstallException.java delete mode 100644 src/main/java/tech/jhipster/lite/project/infrastructure/secondary/NpmInstallationType.java rename src/main/java/tech/jhipster/lite/{project => shared/npmdetector}/infrastructure/secondary/NpmInstallationReader.java (91%) create mode 100644 src/main/java/tech/jhipster/lite/shared/npmdetector/infrastructure/secondary/NpmInstallationType.java create mode 100644 src/main/java/tech/jhipster/lite/shared/npmdetector/package-info.java diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java index 26bd495b4b9..06b2068ac0f 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/application/VueApplicationService.java @@ -3,19 +3,22 @@ import org.springframework.stereotype.Service; import tech.jhipster.lite.generator.client.vue.core.domain.VueModulesFactory; import tech.jhipster.lite.module.domain.JHipsterModule; +import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; @Service public class VueApplicationService { private final VueModulesFactory factory; + private final NpmLazyInstaller npmLazyInstaller; - public VueApplicationService() { + public VueApplicationService(NpmLazyInstaller npmLazyInstaller) { factory = new VueModulesFactory(); + this.npmLazyInstaller = npmLazyInstaller; } public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { - return factory.buildVueModule(properties); + return factory.buildVueModule(properties, npmLazyInstaller); } public JHipsterModule buildPiniaModule(JHipsterModuleProperties properties) { diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index 4e4e03664bf..3054690d374 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -22,6 +22,7 @@ import tech.jhipster.lite.module.domain.JHipsterModule; import tech.jhipster.lite.module.domain.file.JHipsterDestination; import tech.jhipster.lite.module.domain.file.JHipsterSource; +import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer; import tech.jhipster.lite.shared.error.domain.Assert; @@ -51,7 +52,7 @@ public class VueModulesFactory { app.use(pinia); """; - public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { + public JHipsterModule buildVueModule(JHipsterModuleProperties properties, NpmLazyInstaller npmLazyInstaller) { //@formatter:off return moduleBuilder(properties) .preCommitActions(stagedFilesFilter("{src/**/,}*.{ts,vue}"), preCommitCommands("eslint --fix", "prettier --write")) @@ -80,6 +81,9 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .addScript(scriptKey("start"), scriptCommand("vite")) .addScript(scriptKey("watch:tsc"), scriptCommand("npm run build:tsc -- --watch")) .and() + .postActions() + .add(context -> npmLazyInstaller.runInstallIn(context.projectFolder())) + .and() .files() .add(SOURCE.file("tsconfig.build.json"), to("tsconfig.build.json")) .batch(SOURCE, to(".")) diff --git a/src/main/java/tech/jhipster/lite/generator/prettier/application/PrettierApplicationService.java b/src/main/java/tech/jhipster/lite/generator/prettier/application/PrettierApplicationService.java index cbf47520902..0d4be486277 100644 --- a/src/main/java/tech/jhipster/lite/generator/prettier/application/PrettierApplicationService.java +++ b/src/main/java/tech/jhipster/lite/generator/prettier/application/PrettierApplicationService.java @@ -3,18 +3,21 @@ import org.springframework.stereotype.Service; import tech.jhipster.lite.generator.prettier.domain.PrettierModuleFactory; import tech.jhipster.lite.module.domain.JHipsterModule; +import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; @Service public class PrettierApplicationService { private final PrettierModuleFactory factory; + private final NpmLazyInstaller npmLazyInstaller; - public PrettierApplicationService() { - factory = new PrettierModuleFactory(); + public PrettierApplicationService(NpmLazyInstaller npmLazyInstaller) { + this.npmLazyInstaller = npmLazyInstaller; + this.factory = new PrettierModuleFactory(); } public JHipsterModule buildModule(JHipsterModuleProperties properties) { - return factory.buildModule(properties); + return factory.buildModule(properties, npmLazyInstaller); } } diff --git a/src/main/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactory.java index 187b5d7b61e..66c57743493 100644 --- a/src/main/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactory.java @@ -13,6 +13,7 @@ import tech.jhipster.lite.module.domain.JHipsterModule; import tech.jhipster.lite.module.domain.file.JHipsterDestination; import tech.jhipster.lite.module.domain.file.JHipsterSource; +import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; public class PrettierModuleFactory { @@ -20,7 +21,7 @@ public class PrettierModuleFactory { private static final JHipsterSource SOURCE = from("prettier"); private static final JHipsterDestination DESTINATION = to("."); - public JHipsterModule buildModule(JHipsterModuleProperties properties) { + public JHipsterModule buildModule(JHipsterModuleProperties properties, NpmLazyInstaller npmLazyInstaller) { //@formatter:off return moduleBuilder(properties) .context() @@ -43,6 +44,9 @@ public JHipsterModule buildModule(JHipsterModuleProperties properties) { .addScript(scriptKey("prettier:check"), scriptCommand("prettier --check .")) .addScript(scriptKey("prettier:format"), scriptCommand("prettier --write .")) .and() + .postActions() + .add(context -> npmLazyInstaller.runInstallIn(context.projectFolder())) + .and() .preCommitActions(stagedFilesFilter("*.{md,json,yml,html,css,scss,java,xml,feature}"), preCommitCommands("['prettier --write']")) .build(); //@formatter:on diff --git a/src/main/java/tech/jhipster/lite/module/domain/npm/NpmLazyInstaller.java b/src/main/java/tech/jhipster/lite/module/domain/npm/NpmLazyInstaller.java new file mode 100644 index 00000000000..2f7052e39de --- /dev/null +++ b/src/main/java/tech/jhipster/lite/module/domain/npm/NpmLazyInstaller.java @@ -0,0 +1,10 @@ +package tech.jhipster.lite.module.domain.npm; + +import tech.jhipster.lite.module.domain.properties.JHipsterProjectFolder; + +/** + * Run npm install if a previous npm install has already been done. + */ +public interface NpmLazyInstaller { + void runInstallIn(JHipsterProjectFolder folder); +} diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/FileSystemNpmLazyInstaller.java b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/FileSystemNpmLazyInstaller.java new file mode 100644 index 00000000000..fcbe0e9aa96 --- /dev/null +++ b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/FileSystemNpmLazyInstaller.java @@ -0,0 +1,92 @@ +package tech.jhipster.lite.module.infrastructure.secondary.npm; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller; +import tech.jhipster.lite.module.domain.properties.JHipsterProjectFolder; +import tech.jhipster.lite.shared.error.domain.Assert; +import tech.jhipster.lite.shared.npmdetector.infrastructure.secondary.NpmInstallationReader; +import tech.jhipster.lite.shared.npmdetector.infrastructure.secondary.NpmInstallationType; + +/** + * Launches npm install if the npm command is detected and if an existing package-lock.json is present. + */ +@Service +class FileSystemNpmLazyInstaller implements NpmLazyInstaller { + + private static final Logger log = LoggerFactory.getLogger(FileSystemNpmLazyInstaller.class); + private final NpmInstallationReader npmInstallationReader = new NpmInstallationReader(); + + public void runInstallIn(JHipsterProjectFolder folder) { + Assert.notNull("folder", folder); + + if (!folder.fileExists("package-lock.json")) { + log.info("No package-lock.json found, npm install skipped"); + return; + } + + NpmInstallationType npmInstallationType = npmInstallationReader.get(); + switch (npmInstallationType) { + case UNIX: + execute(folder, "npm", "install"); + break; + case WINDOWS: + execute(folder, "npm.cmd", "install"); + break; + case NONE: + log.info("No npm installed, can't install project"); + break; + } + } + + private void execute(JHipsterProjectFolder path, String... commands) { + try { + Process process = new ProcessBuilder(commands).directory(folderFile(path)).start(); + + if (failedExecution(process)) { + throw new NpmInstallException("Error during formatting, process failed"); + } + + traceProcess(String.join(" ", commands), process); + } catch (IOException e) { + throw new NpmInstallException("Error during formatting: " + e.getMessage(), e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + + throw new NpmInstallException("Error during formatting: " + e.getMessage(), e); + } + } + + private File folderFile(JHipsterProjectFolder path) { + return new File(path.get()); + } + + private boolean failedExecution(Process process) throws InterruptedException { + return !process.waitFor(1, TimeUnit.MINUTES); + } + + private void traceProcess(String command, Process process) throws IOException { + if (log.isTraceEnabled()) { + log.trace("{}: {}", command, read(process.getInputStream())); + } + + if (log.isErrorEnabled()) { + String errors = read(process.getErrorStream()); + + if (StringUtils.isNotBlank(errors)) { + log.error("Error during {}: {}", command, errors); + } + } + } + + private String read(InputStream stream) throws IOException { + return new String(stream.readAllBytes(), StandardCharsets.UTF_8).intern(); + } +} diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmErrorKey.java b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmErrorKey.java new file mode 100644 index 00000000000..66a0b6e6e0a --- /dev/null +++ b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmErrorKey.java @@ -0,0 +1,18 @@ +package tech.jhipster.lite.module.infrastructure.secondary.npm; + +import tech.jhipster.lite.shared.error.domain.ErrorKey; + +enum NpmErrorKey implements ErrorKey { + INSTALL_ERROR("install-error"); + + private final String key; + + NpmErrorKey(String key) { + this.key = key; + } + + @Override + public String get() { + return key; + } +} diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmInstallException.java b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmInstallException.java new file mode 100644 index 00000000000..dadcf67ceaf --- /dev/null +++ b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/npm/NpmInstallException.java @@ -0,0 +1,16 @@ +package tech.jhipster.lite.module.infrastructure.secondary.npm; + +import tech.jhipster.lite.shared.error.domain.GeneratorException; +import tech.jhipster.lite.shared.generation.domain.ExcludeFromGeneratedCodeCoverage; + +@ExcludeFromGeneratedCodeCoverage +class NpmInstallException extends GeneratorException { + + public NpmInstallException(String message) { + super(internalServerError(NpmErrorKey.INSTALL_ERROR).message(message)); + } + + public NpmInstallException(String message, Throwable cause) { + super(internalServerError(NpmErrorKey.INSTALL_ERROR).message(message).cause(cause)); + } +} diff --git a/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/NpmInstallationType.java b/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/NpmInstallationType.java deleted file mode 100644 index f8189d12365..00000000000 --- a/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/NpmInstallationType.java +++ /dev/null @@ -1,7 +0,0 @@ -package tech.jhipster.lite.project.infrastructure.secondary; - -enum NpmInstallationType { - NONE, - UNIX, - WINDOWS, -} diff --git a/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfiguration.java b/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfiguration.java index 83434baa01a..1ea2bd43d91 100644 --- a/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfiguration.java +++ b/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfiguration.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportRuntimeHints; +import tech.jhipster.lite.shared.npmdetector.infrastructure.secondary.NpmInstallationReader; @Configuration @ImportRuntimeHints(NativeHints.class) diff --git a/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/NpmInstallationReader.java b/src/main/java/tech/jhipster/lite/shared/npmdetector/infrastructure/secondary/NpmInstallationReader.java similarity index 91% rename from src/main/java/tech/jhipster/lite/project/infrastructure/secondary/NpmInstallationReader.java rename to src/main/java/tech/jhipster/lite/shared/npmdetector/infrastructure/secondary/NpmInstallationReader.java index cfca65dd9fc..e76e434c6a0 100644 --- a/src/main/java/tech/jhipster/lite/project/infrastructure/secondary/NpmInstallationReader.java +++ b/src/main/java/tech/jhipster/lite/shared/npmdetector/infrastructure/secondary/NpmInstallationReader.java @@ -1,4 +1,4 @@ -package tech.jhipster.lite.project.infrastructure.secondary; +package tech.jhipster.lite.shared.npmdetector.infrastructure.secondary; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -9,7 +9,7 @@ @Service @ExcludeFromGeneratedCodeCoverage(reason = "Cases can only be tested by using different computers") -class NpmInstallationReader { +public class NpmInstallationReader { private static final Logger log = LoggerFactory.getLogger(NpmInstallationReader.class); diff --git a/src/main/java/tech/jhipster/lite/shared/npmdetector/infrastructure/secondary/NpmInstallationType.java b/src/main/java/tech/jhipster/lite/shared/npmdetector/infrastructure/secondary/NpmInstallationType.java new file mode 100644 index 00000000000..e29ba3fe69e --- /dev/null +++ b/src/main/java/tech/jhipster/lite/shared/npmdetector/infrastructure/secondary/NpmInstallationType.java @@ -0,0 +1,7 @@ +package tech.jhipster.lite.shared.npmdetector.infrastructure.secondary; + +public enum NpmInstallationType { + NONE, + UNIX, + WINDOWS, +} diff --git a/src/main/java/tech/jhipster/lite/shared/npmdetector/package-info.java b/src/main/java/tech/jhipster/lite/shared/npmdetector/package-info.java new file mode 100644 index 00000000000..b89e1072408 --- /dev/null +++ b/src/main/java/tech/jhipster/lite/shared/npmdetector/package-info.java @@ -0,0 +1,2 @@ +@tech.jhipster.lite.SharedKernel +package tech.jhipster.lite.shared.npmdetector; diff --git a/src/main/resources/messages/errors/generator-errors-messages.properties b/src/main/resources/messages/errors/generator-errors-messages.properties index ecc31ebf203..485b1c41df5 100644 --- a/src/main/resources/messages/errors/generator-errors-messages.properties +++ b/src/main/resources/messages/errors/generator-errors-messages.properties @@ -103,3 +103,6 @@ error.unknown-slug.title=Unknown slug error.unmappable-enum.detail=Can't map enum value error.unmappable-enum.title=Unmappable enum + +error.install-error.detail=An error happened while installing npm dependencies +error.install-error.title=Error while installing npm dependencies diff --git a/src/main/resources/messages/errors/generator-errors-messages_fr.properties b/src/main/resources/messages/errors/generator-errors-messages_fr.properties index 88a78bbd15c..fbebb5e1d38 100644 --- a/src/main/resources/messages/errors/generator-errors-messages_fr.properties +++ b/src/main/resources/messages/errors/generator-errors-messages_fr.properties @@ -103,3 +103,6 @@ error.unknown-slug.title=Slug inconnu error.unmappable-enum.detail=Valeur d'enum non mappable error.unmappable-enum.title=Enum in-mappable + +error.install-error.detail=Une erreur s'est produite lors de l'installation des dépendances npm +error.install-error.title=Erreur lors de l'installation des dépendances npm diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index a0ba30e1cb3..0d4a4709831 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -1,19 +1,36 @@ package tech.jhipster.lite.generator.client.vue.core.domain; -import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.*; +import static org.mockito.Mockito.verify; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.ModuleFile; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.assertThatModuleWithFiles; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.eslintConfigFile; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.lintStagedConfigFile; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.nodeDependency; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.nodeScript; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.packageJsonFile; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.tsConfigFile; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.vitestConfigFile; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import tech.jhipster.lite.TestFileUtils; import tech.jhipster.lite.UnitTest; import tech.jhipster.lite.module.domain.JHipsterModule; import tech.jhipster.lite.module.domain.JHipsterModulesFixture; +import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; @UnitTest +@ExtendWith(MockitoExtension.class) class VueModulesFactoryTest { private static final VueModulesFactory factory = new VueModulesFactory(); + @Mock + private NpmLazyInstaller npmLazyInstaller; + @Test void shouldCreateVueModule() { JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(TestFileUtils.tmpDirForTest()) @@ -21,7 +38,7 @@ void shouldCreateVueModule() { .basePackage("tech.jhipster.jhlitest") .build(); - JHipsterModule module = factory.buildVueModule(properties); + JHipsterModule module = factory.buildVueModule(properties, npmLazyInstaller); //@formatter:off assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile(), tsConfigFile(), vitestConfigFile(), eslintConfigFile()) @@ -80,6 +97,7 @@ void shouldCreateVueModule() { .hasFiles("src/test/webapp/unit/shared/http/infrastructure/secondary/AxiosStub.ts") .hasFiles("src/test/webapp/unit/router/infrastructure/primary/HomeRouter.spec.ts"); //@formatter:on + verify(npmLazyInstaller).runInstallIn(properties.projectFolder()); } @Test diff --git a/src/test/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactoryTest.java index 9d2bbb6aab5..88b864e72d3 100644 --- a/src/test/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/prettier/domain/PrettierModuleFactoryTest.java @@ -1,15 +1,23 @@ package tech.jhipster.lite.generator.prettier.domain; -import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.*; +import static org.mockito.Mockito.verify; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.assertThatModuleWithFiles; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.emptyLintStagedConfigFile; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.lintStagedConfigFileWithoutPrettier; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.nodeDependency; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.nodeScript; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.packageJsonFile; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; +import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import tech.jhipster.lite.TestFileUtils; import tech.jhipster.lite.UnitTest; import tech.jhipster.lite.module.domain.JHipsterModule; import tech.jhipster.lite.module.domain.JHipsterModulesFixture; +import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; @UnitTest @@ -19,12 +27,15 @@ class PrettierModuleFactoryTest { @InjectMocks private PrettierModuleFactory factory; + @Mock + private NpmLazyInstaller npmLazyInstaller; + @Test void shouldBuildModuleWithoutPrettierLintStaged() { String folder = TestFileUtils.tmpDirForTest(); JHipsterModuleProperties properties = properties(folder); - JHipsterModule module = factory.buildModule(properties); + JHipsterModule module = factory.buildModule(properties, npmLazyInstaller); assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFileWithoutPrettier()) .hasFiles(".prettierignore") @@ -56,6 +67,8 @@ void shouldBuildModuleWithoutPrettierLintStaged() { .containing(nodeDependency("prettier-plugin-packagejson")) .containing(nodeScript("prettier:check", "prettier --check .")) .containing(nodeScript("prettier:format", "prettier --write .")); + + verify(npmLazyInstaller).runInstallIn(properties.projectFolder()); } @Test @@ -63,7 +76,7 @@ void shouldBuildModuleWithEmptyLintStaged() { String folder = TestFileUtils.tmpDirForTest(); JHipsterModuleProperties properties = properties(folder); - JHipsterModule module = factory.buildModule(properties); + JHipsterModule module = factory.buildModule(properties, npmLazyInstaller); assertThatModuleWithFiles(module, packageJsonFile(), emptyLintStagedConfigFile()) .hasFile(".lintstagedrc.cjs") diff --git a/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfigurationTest.java b/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfigurationTest.java index c37c9b9fd16..f6b7a39cb7f 100644 --- a/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfigurationTest.java +++ b/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/ProjectFormatterConfigurationTest.java @@ -1,7 +1,7 @@ package tech.jhipster.lite.project.infrastructure.secondary; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; import ch.qos.logback.classic.Level; import org.junit.jupiter.api.Test; @@ -12,6 +12,8 @@ import tech.jhipster.lite.LogsSpy; import tech.jhipster.lite.LogsSpyExtension; import tech.jhipster.lite.UnitTest; +import tech.jhipster.lite.shared.npmdetector.infrastructure.secondary.NpmInstallationReader; +import tech.jhipster.lite.shared.npmdetector.infrastructure.secondary.NpmInstallationType; @UnitTest @ExtendWith({ MockitoExtension.class, LogsSpyExtension.class })