diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java b/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java index 30cd8924..1ea246f0 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java +++ b/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java @@ -48,15 +48,8 @@ void should_skip_task_when_package_json_file_is_not_a_file() throws IOException } @Test - void should_fail_when_corepack_executable_is_not_a_file() throws IOException { - // The fact that the corepack executable is not present is enough to simulate the following use cases: - // - The Node.js distribution is already provided, but the install directory was not set accordingly. - // - The Node.js distribution is already provided, but the install directory contains a non-supported release. - // - The Node.js distribution was downloaded but is a non-supported release. - // - The Node.js distribution was downloaded but was corrupted later so as the corepack executable is not - // present anymore. + void should_fail_when_node_install_directory_is_not_a_directory() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); - Files.createDirectory(projectDirectoryPath.resolve(FrontendGradlePlugin.DEFAULT_NODE_INSTALL_DIRECTORY_NAME)); createBuildFile(projectDirectoryPath, new FrontendMapBuilder().nodeDistributionProvided(true).toMap()); final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java index 369e43ca..d93fe8fa 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java @@ -390,7 +390,17 @@ protected void configureInstallPackageManagerTask(final InstallPackageManagerTas task.setGroup(TASK_GROUP); task.setDescription("Installs the package manager."); task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().getAsFile()); - task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); + task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().map(nodeInstallDirectory -> { + final Path nodeInstallDirectoryPath = nodeInstallDirectory.getAsFile().toPath(); + if (!Files.isDirectory(nodeInstallDirectoryPath)) { + // Performing this verification ahead of time avoids automatic creation of any parent directory by + // Gradle if the task is not skipped. This may be the case if the Node.js distribution is provided, but + // the install directory is not correctly configured and points to nowhere. + throw new GradleException( + "Node.js install directory is not a valid directory: " + nodeInstallDirectoryPath); + } + return nodeInstallDirectory.getAsFile(); + })); final Provider resolvePackageManagerTaskProvider = taskContainer.named( RESOLVE_PACKAGE_MANAGER_TASK_NAME, ResolvePackageManagerTask.class); task @@ -399,27 +409,26 @@ protected void configureInstallPackageManagerTask(final InstallPackageManagerTas ResolvePackageManagerTask::getPackageManagerSpecificationFile)); task .getPackageManagerExecutableFile() - .set(resolvePackageManagerTaskProvider + .fileProvider(resolvePackageManagerTaskProvider .flatMap(ResolvePackageManagerTask::getPackageManagerExecutablePathFile) .map(f -> { final Path filePath = f.getAsFile().toPath(); if (!Files.exists(filePath)) { - // Setting the output property to null avoids automatic creation of any parent directories by + // Setting the output property to null avoids automatic creation of any parent directory by // Gradle if the task is not skipped. If it is skipped, the file system would not have been // touched by Gradle. return null; } try { - return getBeanOrFail(beanRegistryId, FileManager.class).readString(filePath, - StandardCharsets.UTF_8); + return Paths + .get(getBeanOrFail(beanRegistryId, FileManager.class).readString(filePath, + StandardCharsets.UTF_8)) + .toFile(); } catch (final IOException e) { throw new GradleException( "Cannot read path to package manager executable from file: " + filePath, e); } - }) - .map(packageManagerExecutablePathFilePath -> () -> Paths - .get(packageManagerExecutablePathFilePath) - .toFile())); + })); task.setOnlyIf(t -> isTaskExecuted(taskContainer, RESOLVE_PACKAGE_MANAGER_TASK_NAME)); } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTask.java index 304bb8f4..0d3fdeb8 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTask.java @@ -53,12 +53,12 @@ public class ResolvePackageManagerTask extends DefaultTask { private final Property nodeInstallDirectory; /** - * File that will contain information about the package manager. + * File that will contain the specification of the package manager for the project. */ private final RegularFileProperty packageManagerSpecificationFile; /** - * File that will contain information about the package manager. + * File that will contain the path to the package manager executable file. */ private final RegularFileProperty packageManagerExecutablePathFile;