diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 72697711..1ce83b10 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-22.04, macos-12, windows-2022] + os: [ubuntu-22.04, macos-14, windows-2022] steps: - name: Init Ubuntu environment @@ -21,8 +21,8 @@ jobs: run: sudo rm -f /usr/local/bin/node /usr/local/bin/npm /usr/local/bin/pnpm /usr/local/bin/yarn - name: Init MacOS environment - if: matrix.os == 'macos-12' - run: sudo rm -f /usr/local/bin/node /usr/local/bin/npm /usr/local/bin/pnpm /usr/bin/yarn /Users/runner/.yarn/bin/yarn + if: matrix.os == 'macos-14' + run: sudo rm -f /opt/homebrew/bin/node /usr/local/bin/npm /usr/local/bin/pnpm /usr/bin/yarn /Users/runner/.yarn/bin/yarn - name: Init Windows environment if: matrix.os == 'windows-2022' @@ -31,26 +31,26 @@ jobs: Rename-Item "C:\npm" "npm.old" -Force - name: Git checkout for source code analysis - uses: actions/checkout@v3 + uses: actions/checkout@v4 if: matrix.os == 'ubuntu-22.04' with: fetch-depth: 0 - name: Git checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 if: matrix.os != 'ubuntu-22.04' with: fetch-depth: 1 - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: '11' architecture: x64 - name: Cache Gradle's cache and wrapper - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.gradle/caches/ @@ -60,7 +60,7 @@ jobs: ${{ runner.os }}-gradle- - name: Cache Sonar's cache - uses: actions/cache@v3 + uses: actions/cache@v4 if: matrix.os == 'ubuntu-22.04' with: path: | @@ -68,14 +68,14 @@ jobs: key: ${{ runner.os }}-sonar-${{ hashFiles('**/*.gradle*') }} - name: Grant executable permission - run: chmod +x gradlew plugin/src/intTest/resources/*/bin/* + run: chmod +x gradlew plugin/src/integrationTest/resources/*/bin/* - name: Build plugin on Linux (with test coverage) if: matrix.os == 'ubuntu-22.04' run: ./gradlew :plugin:jacocoTestReport --console=plain - name: Build plugin on MacOS - if: matrix.os == 'macos-12' + if: matrix.os == 'macos-14' run: ./gradlew :plugin:build --console=plain - name: Build plugin on Windows @@ -97,4 +97,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: ./gradlew :plugin:sonar --console=plain -Dorg.gradle.jvmargs=-Xmx512m -Dsonar.verbose=true + run: ./gradlew :plugin:sonar --console=plain -Dorg.gradle.jvmargs=-Xmx512m diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a484297d..068c7d4d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -113,8 +113,8 @@ The project relies on [GitHub Actions][github-actions] to integrate continuously repository. The configuration actually allows to build and test the plugin with Adoptium Temurin JDK 17 64 bits, on the environments below: -- Linux Ubuntu 22.04.2 -- Mac OS 12.6.5 +- Linux Ubuntu 22.04.4 +- Mac OS 14.5 - Windows Server 2022 Ubuntu is the reference O/S, used to analyze the source code with SonarCloud. Developments are frequently done on a diff --git a/README.md b/README.md index 815a04ee..2be37f12 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ With their feedback, plugin improvement is possible. Special thanks to: @[joschi](https://github.com/joschi), @[jorgheymans](https://github.com/jorgheymans), @[ludik0](https://github.com/ludik0), +@[marcospereira](https://github.com/marcospereira), +@[mgiorgino-iobeya](https://github.com/mgiorgino-iobeya), @[mhalbritter](https://github.com/mhalbritter), @[mike-howell](https://github.com/mike-howell), @[napstr](https://github.com/napstr), diff --git a/examples/application-with-preinstalled-nodejs-distribution/build.gradle.kts b/examples/application-with-preinstalled-nodejs-distribution/build.gradle.kts index 301292c6..d70ee558 100644 --- a/examples/application-with-preinstalled-nodejs-distribution/build.gradle.kts +++ b/examples/application-with-preinstalled-nodejs-distribution/build.gradle.kts @@ -17,6 +17,7 @@ frontend { } tasks.register("nodeVersion") { + dependsOn("installNode") script.set("-v") } diff --git a/examples/fullstack-war-application/frontend/build.gradle.kts b/examples/fullstack-war-application/frontend/build.gradle.kts index bb27de70..c363b01f 100644 --- a/examples/fullstack-war-application/frontend/build.gradle.kts +++ b/examples/fullstack-war-application/frontend/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } frontend { - nodeVersion.set("18.17.1") + nodeVersion.set("20.14.0") assembleScript.set("run build") cleanScript.set("run clean") checkScript.set("run check") diff --git a/examples/multiple-package-managers-with-shared-nodejs-distribution/node-subproject/build.gradle.kts b/examples/multiple-package-managers-with-shared-nodejs-distribution/node-subproject/build.gradle.kts index dfaef9ef..1fd4a360 100644 --- a/examples/multiple-package-managers-with-shared-nodejs-distribution/node-subproject/build.gradle.kts +++ b/examples/multiple-package-managers-with-shared-nodejs-distribution/node-subproject/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } frontend { - nodeVersion.set("18.17.1") + nodeVersion.set("20.14.0") nodeInstallDirectory.set(file(rootProject.ext.get("nodeInstallDirectory")!!)) } diff --git a/examples/npm-application/build.gradle.kts b/examples/npm-application/build.gradle.kts index d498b2d9..827c8fd1 100644 --- a/examples/npm-application/build.gradle.kts +++ b/examples/npm-application/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } frontend { - nodeVersion.set("18.17.1") + nodeVersion.set("20.14.0") assembleScript.set("run build") cleanScript.set("run clean") checkScript.set("run check") diff --git a/examples/pnpm-application/build.gradle.kts b/examples/pnpm-application/build.gradle.kts index f0be4bce..d9e748cb 100644 --- a/examples/pnpm-application/build.gradle.kts +++ b/examples/pnpm-application/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } frontend { - nodeVersion.set("18.17.1") + nodeVersion.set("20.14.0") assembleScript.set("run build") cleanScript.set("run clean") checkScript.set("run check") diff --git a/examples/yarn-application-with-node-modules-linker/build.gradle.kts b/examples/yarn-application-with-node-modules-linker/build.gradle.kts index 970c4cb4..88fcf497 100644 --- a/examples/yarn-application-with-node-modules-linker/build.gradle.kts +++ b/examples/yarn-application-with-node-modules-linker/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } frontend { - nodeVersion.set("18.17.1") + nodeVersion.set("20.14.0") assembleScript.set("run build") cleanScript.set("run clean") checkScript.set("run check") diff --git a/examples/yarn-application-with-pnp-linker/build.gradle.kts b/examples/yarn-application-with-pnp-linker/build.gradle.kts index 04f96683..80248b4c 100644 --- a/examples/yarn-application-with-pnp-linker/build.gradle.kts +++ b/examples/yarn-application-with-pnp-linker/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } frontend { - nodeVersion.set("18.17.1") + nodeVersion.set("20.14.0") assembleScript.set("run build") cleanScript.set("run clean") checkScript.set("run check") diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c4..7f93135c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d11cdd90..6f7a6eb3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index fcb6fca1..0adc8e1a 100644 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index daa48a8d..54752aa1 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -27,102 +27,63 @@ version = fgpVersion description = fgpDescription java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + toolchain { + languageVersion = JavaLanguageVersion.of(11) + } withJavadocJar() withSourcesJar() } sourceSets { - create("intTest") { + create("integrationTest") { compileClasspath += sourceSets.main.get().output + sourceSets.test.get().output runtimeClasspath += sourceSets.main.get().output + sourceSets.test.get().output } } -val intTestImplementation: Configuration by configurations.getting { +val integrationTestImplementation: Configuration by configurations.getting { extendsFrom(configurations.implementation.get()) extendsFrom(configurations.testImplementation.get()) } -configurations["intTestRuntimeOnly"] +configurations["integrationTestRuntimeOnly"] .extendsFrom(configurations.runtimeOnly.get()) .extendsFrom(configurations.testRuntimeOnly.get()) dependencies { implementation(gradleApi()) implementation("io.github.resilience4j:resilience4j-retry:1.7.1") - implementation("org.apache.httpcomponents.client5:httpclient5:5.2.1") - implementation("org.apache.commons:commons-compress:1.23.0") - implementation("org.json:json:20230618") - compileOnly("org.projectlombok:lombok:1.18.28") - annotationProcessor("org.projectlombok:lombok:1.18.28") - - testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0") - testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0") - testImplementation("org.mockito:mockito-core:5.4.0") - testImplementation("org.mockito:mockito-junit-jupiter:5.4.0") - testImplementation("org.junit-pioneer:junit-pioneer:2.0.1") - testImplementation("org.assertj:assertj-core:3.24.2") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0") - testCompileOnly("org.projectlombok:lombok:1.18.28") - testAnnotationProcessor("org.projectlombok:lombok:1.18.28") - - intTestImplementation("com.github.tomakehurst:wiremock:2.27.2") -} - -tasks.named("wrapper") { - distributionType = Wrapper.DistributionType.ALL -} - -tasks.withType { - useJUnitPlatform() - jvmArgs( - "--add-opens", "java.base/java.lang=ALL-UNNAMED", - "--add-opens", "java.base/java.util=ALL-UNNAMED" - ) - outputs.upToDateWhen { false } -} - -tasks.register("integrationTest") { - description = "Runs integration tests." - group = "verification" - testClassesDirs = sourceSets["intTest"].output.classesDirs - classpath = sourceSets["intTest"].runtimeClasspath - // Yarn immutable installs prevents failures in integration tests due to missing yarn.lock file. - environment["YARN_ENABLE_IMMUTABLE_INSTALLS"] = "false" - shouldRunAfter("test") - outputs.upToDateWhen { false } -} - -tasks.named("check") { - dependsOn(tasks.named("integrationTest")) -} - -tasks.named("jacocoTestReport") { - dependsOn(tasks.named("test"), tasks.named("integrationTest")) - executionData.setFrom( - file("${project.buildDir}/jacoco/test.exec"), - file("${project.buildDir}/jacoco/integrationTest.exec") - ) - reports { - xml.required.set(true) - xml.outputLocation.set(file("${buildDir}/reports/jacoco/report.xml")) - } + implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1") + implementation("org.apache.commons:commons-compress:1.26.2") + implementation("org.json:json:20240303") + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") + + testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.2") + testImplementation("org.mockito:mockito-core:5.12.0") + testImplementation("org.mockito:mockito-junit-jupiter:5.12.0") + testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") + testImplementation("org.assertj:assertj-core:3.26.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.2") + testCompileOnly("org.projectlombok:lombok:1.18.32") + testAnnotationProcessor("org.projectlombok:lombok:1.18.32") + + integrationTestImplementation("org.wiremock:wiremock:3.6.0") } -gradle.addListener(GradleTestListener(logger)) - idea { module { // Force integration test source set as test folder - testSources.from(project.sourceSets.getByName("intTest").java.srcDirs) - testResources.from(project.sourceSets.getByName("intTest").resources.srcDirs) + testSources.from(project.sourceSets.getByName("integrationTest").java.srcDirs) + testResources.from(project.sourceSets.getByName("integrationTest").resources.srcDirs) + isDownloadJavadoc = true + isDownloadSources = true } } jacoco { - toolVersion = "0.8.10" + toolVersion = "0.8.11" } gradlePlugin { @@ -148,23 +109,63 @@ sonarqube { property("sonar.projectVersion", "${fgpVersion}-jdk11") property("sonar.links.homepage", "https://github.com/siouan/frontend-gradle-plugin") - property("sonar.links.ci", "https://travis-ci.com/siouan/frontend-gradle-plugin") + property("sonar.links.ci", "https://github.com/siouan/frontend-gradle-plugin/actions") property("sonar.links.scm", "https://github.com/siouan/frontend-gradle-plugin") property("sonar.links.issue", "https://github.com/siouan/frontend-gradle-plugin/issues") property("sonar.sources", "src/main") - property("sonar.tests", "src/test,src/intTest") + property("sonar.tests", "src/test,src/integrationTest") property("sonar.java.binaries", "build/classes/java/main") - property("sonar.java.test.binaries", "build/classes/java/test,build/classes/java/intTest") + property("sonar.java.test.binaries", "build/classes/java/test,build/classes/java/integrationTest") property("sonar.junit.reportPaths", "build/test-results/test/,build/test-results/integrationTest/") - property("sonar.jacoco.xmlReportPaths", "${buildDir}/reports/jacoco/report.xml") + property("sonar.jacoco.xmlReportPaths", "build/reports/jacoco/report.xml") property("sonar.verbose", true) // Irrelevant duplications detected on task inputs property( "sonar.cpd.exclusions", - "**/org/siouan/frontendgradleplugin/domain/model/*.java,**/org/siouan/frontendgradleplugin/domain/usecase/Get*ExecutablePath.java" + "**/org/siouan/frontendgradleplugin/domain/Resolve*ExecutablePath.java,**/org/siouan/frontendgradleplugin/infrastructure/gradle/FrontendExtension.java" ) } } + +tasks.named("wrapper") { + distributionType = Wrapper.DistributionType.ALL +} + +tasks.withType { + useJUnitPlatform() +} + +tasks.named("test") { + outputs.upToDateWhen { false } +} + +tasks.register("integrationTest") { + description = "Runs integration tests." + group = "verification" + testClassesDirs = sourceSets["integrationTest"].output.classesDirs + classpath = sourceSets["integrationTest"].runtimeClasspath + // Yarn immutable installs prevents failures in integration tests due to missing yarn.lock file. + environment["YARN_ENABLE_IMMUTABLE_INSTALLS"] = "false" + shouldRunAfter("test") + outputs.upToDateWhen { false } +} + +tasks.named("check") { + dependsOn(tasks.named("integrationTest")) +} + +tasks.named("jacocoTestReport") { + dependsOn(tasks.named("test"), tasks.named("integrationTest")) + executionData.setFrom( + project.layout.buildDirectory.files("jacoco/test.exec", "jacoco/integrationTest.exec"), + ) + reports { + xml.required.set(true) + xml.outputLocation.set(project.layout.buildDirectory.file("reports/jacoco/report.xml")) + } +} + +gradle.addListener(GradleTestListener(logger)) diff --git a/plugin/buildSrc/build.gradle.kts b/plugin/buildSrc/build.gradle.kts index a44afdf1..db0ed947 100644 --- a/plugin/buildSrc/build.gradle.kts +++ b/plugin/buildSrc/build.gradle.kts @@ -7,6 +7,7 @@ dependencies { } java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + toolchain { + languageVersion = JavaLanguageVersion.of(11) + } } diff --git a/plugin/lombok.config b/plugin/lombok.config index df71bb6a..ba6373cb 100644 --- a/plugin/lombok.config +++ b/plugin/lombok.config @@ -1,2 +1,3 @@ config.stopBubbling = true lombok.addLombokGeneratedAnnotation = true +lombok.log.fieldName=LOGGER diff --git a/plugin/settings.gradle.kts b/plugin/settings.gradle.kts index 31c9e626..a286b6cb 100644 --- a/plugin/settings.gradle.kts +++ b/plugin/settings.gradle.kts @@ -2,21 +2,21 @@ val fgpArtifactId: String by extra pluginManagement { plugins { - id("com.gradle.enterprise") version "3.13.1" - id("com.gradle.plugin-publish") version "1.2.0" - id("org.sonarqube") version "4.0.0.2929" + id("com.gradle.develocity") version "3.17.4" + id("com.gradle.plugin-publish") version "1.2.1" + id("org.sonarqube") version "5.0.0.4638" } } plugins { - id("com.gradle.enterprise") + id("com.gradle.develocity") } rootProject.name = fgpArtifactId -gradleEnterprise { +develocity { buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" + termsOfUseUrl.set("https://gradle.com/help/legal-terms-of-use") + termsOfUseAgree.set("yes") } } diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckFrontendTaskFuncTest.java b/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckFrontendTaskFuncTest.java deleted file mode 100644 index 56ada41d..00000000 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckFrontendTaskFuncTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.gradle; - -import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertCheckTaskOutcomes; -import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; -import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; -import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; -import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.gradle.testkit.runner.BuildResult; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; -import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; - -/** - * Functional tests to verify the {@link CheckTask} integration in a Gradle build. Test cases uses fake Node/Yarn - * distributions, to avoid the download overhead. The 'yarn' and 'npm' executables in these distributions simply call - * the 'node' executable with the same arguments. - */ -class CheckFrontendTaskFuncTest { - - @TempDir - Path projectDirectoryPath; - - @Test - void should_skip_task_when_package_json_file_is_not_a_file() throws IOException { - final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) - .checkScript("run check"); - createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, null); - - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, null); - } - - @Test - void should_skip_task_when_script_is_not_defined() throws IOException { - Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); - final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); - createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); - - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); - } - - @Test - void should_skip_task_when_running_gradle_task_and_script_is_not_defined() throws IOException { - Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); - final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); - createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.UP_TO_DATE); - - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.UP_TO_DATE); - } - - @Test - void should_check_frontend() throws IOException { - Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); - final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) - .checkScript("run check"); - createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME); - - assertCheckTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); - } -} diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/MultiProjectsFuncTest.java b/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/MultiProjectsFuncTest.java deleted file mode 100644 index 3e504055..00000000 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/MultiProjectsFuncTest.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.gradle; - -import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; -import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; -import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; -import static org.siouan.frontendgradleplugin.test.GradleSettingsFiles.createSettingsFile; -import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; -import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.gradle.language.base.plugins.LifecycleBasePlugin; -import org.gradle.testkit.runner.BuildResult; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; -import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; - -/** - * This test suite verifies task execution in a multi-projects build, where Node and Yarn distributions are downloaded - * and installed by one sub-project, and used as provided distributions by a second sub-project. The project layout is: - *
- * node/                        Node install directory, shall be created by sub-project-1
- * yarn-project-1/              Yarn sub-project
- *      build.gradle            Installs Node and Yarn distributions
- * npm-project-2/               NPM sub-project
- *      build.gradle            Uses distributions provided by sub-project-1
- * pnpm-project-3/              PNPM sub-project
- *      build.gradle            Uses distributions provided by sub-project-1
- * build.gradle                 Declares plugin, but doesn't apply it
- * settings.gradle
- * 
- */ -class MultiProjectsFuncTest { - - private static final String YARN_SUB_PROJECT_NAME = "yarn-project-1"; - - private static final String NPM_SUB_PROJECT_NAME = "npm-project-2"; - - private static final String PNPM_SUB_PROJECT_NAME = "pnpm-project-3"; - - @TempDir - Path temporaryDirectorypath; - - @Test - void should_run_tasks_in_sub_projects() throws IOException { - // Root project - final Path projectDirectoryPath = temporaryDirectorypath; - createSettingsFile(projectDirectoryPath, "multi-projects-test", YARN_SUB_PROJECT_NAME, NPM_SUB_PROJECT_NAME, - PNPM_SUB_PROJECT_NAME); - createBuildFile(projectDirectoryPath, true, false); - final Path nodeInstallDirectory = Paths.get("${rootProject.projectDir}/node"); - - // Sub-project 1 - final Path yarnSubProjectPath = Files.createDirectory(projectDirectoryPath.resolve(YARN_SUB_PROJECT_NAME)); - Files.copy(getResourcePath("package-yarn.json"), yarnSubProjectPath.resolve("package.json")); - final FrontendMapBuilder yarnSubProjectFrontendProperties = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeInstallDirectory(nodeInstallDirectory) - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) - .installScript("run install") - .cleanScript("run clean") - .assembleScript("run assemble") - .checkScript("run check") - .publishScript("run publish"); - createBuildFile(yarnSubProjectPath, yarnSubProjectFrontendProperties.toMap()); - - // Sub-project 2 - final Path npmSubProjectPath = Files.createDirectory(projectDirectoryPath.resolve(NPM_SUB_PROJECT_NAME)); - Files.copy(getResourcePath("package-npm.json"), npmSubProjectPath.resolve("package.json")); - final FrontendMapBuilder npmSubProjectFrontendProperties = new FrontendMapBuilder() - .nodeDistributionProvided(true) - .nodeInstallDirectory(nodeInstallDirectory) - .installScript("run install") - .cleanScript("run clean") - .assembleScript("run assemble") - .checkScript("run check") - .publishScript("run publish"); - createBuildFile(npmSubProjectPath, npmSubProjectFrontendProperties.toMap(), - "tasks.named('installPackageManager').configure {" + "dependsOn project(':" + YARN_SUB_PROJECT_NAME - + "').installNode\n}"); - - // Sub-project 3 - final Path pnpmSubProjectPath = Files.createDirectory(projectDirectoryPath.resolve(PNPM_SUB_PROJECT_NAME)); - Files.copy(getResourcePath("package-pnpm.json"), pnpmSubProjectPath.resolve("package.json")); - final FrontendMapBuilder pnpmSubProjectFrontendProperties = new FrontendMapBuilder() - .nodeDistributionProvided(true) - .nodeInstallDirectory(nodeInstallDirectory) - .installScript("run install") - .cleanScript("run clean") - .assembleScript("run assemble") - .checkScript("run check") - .publishScript("run publish"); - createBuildFile(pnpmSubProjectPath, pnpmSubProjectFrontendProperties.toMap(), - "tasks.named('installPackageManager').configure {" + "dependsOn project(':" + YARN_SUB_PROJECT_NAME - + "').installNode\n}"); - - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME, - LifecycleBasePlugin.BUILD_TASK_NAME, FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); - - assertTaskOutcomes(result1, YARN_SUB_PROJECT_NAME, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result1, NPM_SUB_PROJECT_NAME, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result1, PNPM_SUB_PROJECT_NAME, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result1, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED); - - final BuildResult result2 = runGradle(projectDirectoryPath, LifecycleBasePlugin.BUILD_TASK_NAME, - FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); - - assertTaskOutcomes(result2, YARN_SUB_PROJECT_NAME, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result2, NPM_SUB_PROJECT_NAME, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result2, PNPM_SUB_PROJECT_NAME, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result2, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED); - - final BuildResult result3 = runGradle(projectDirectoryPath, LifecycleBasePlugin.BUILD_TASK_NAME, - FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); - - assertTaskOutcomes(result3, YARN_SUB_PROJECT_NAME, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result3, NPM_SUB_PROJECT_NAME, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result3, PNPM_SUB_PROJECT_NAME, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - - assertTaskOutcomes(result3, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, PluginTaskOutcome.IGNORED, - PluginTaskOutcome.IGNORED); - } -} diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTaskFuncTest.java b/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTaskFuncTest.java deleted file mode 100644 index 841ffd59..00000000 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTaskFuncTest.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.gradle; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; -import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; -import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; -import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; -import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; -import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.gradle.testkit.runner.BuildResult; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; -import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; - -/** - * Functional tests to verify the {@link ResolvePackageManagerTask} integration in a Gradle build. - * - * @since 7.0.0 - */ -class ResolvePackageManagerTaskFuncTest { - - @TempDir - Path projectDirectoryPath; - - @Test - void should_skip_task_when_package_json_file_is_not_a_file() throws IOException { - Files.createDirectory(projectDirectoryPath.resolve(FrontendGradlePlugin.PACKAGE_JSON_FILE_NAME)); - createBuildFile(projectDirectoryPath, new FrontendMapBuilder().nodeDistributionProvided(true).toMap()); - - final BuildResult result = runGradle(projectDirectoryPath, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME); - - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED); - assertThat(projectDirectoryPath.resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_SPECIFICATION_FILE_NAME))).doesNotExist(); - assertThat(projectDirectoryPath.resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME))).doesNotExist(); - } - - @Test - void should_fail_when_package_manager_property_is_not_set_in_package_json_file() throws IOException { - Files.copy(getResourcePath("package-no-manager.json"), projectDirectoryPath.resolve("package.json")); - createBuildFile(projectDirectoryPath, new FrontendMapBuilder() - .nodeDistributionProvided(true) - .nodeInstallDirectory(getResourcePath("node-dist-provided")) - .toMap()); - - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME); - - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.FAILED); - assertThat(projectDirectoryPath.resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_SPECIFICATION_FILE_NAME))).doesNotExist(); - assertThat(projectDirectoryPath.resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME))).doesNotExist(); - } - - @Test - void should_fail_when_package_manager_property_is_invalid_in_package_json_file() throws IOException { - Files.copy(getResourcePath("package-invalid-manager.json"), projectDirectoryPath.resolve("package.json")); - createBuildFile(projectDirectoryPath, new FrontendMapBuilder() - .nodeDistributionProvided(true) - .nodeInstallDirectory(getResourcePath("node-dist-provided")) - .toMap()); - - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME); - - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.FAILED); - assertThat(projectDirectoryPath.resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_SPECIFICATION_FILE_NAME))).doesNotExist(); - assertThat(projectDirectoryPath.resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME))).doesNotExist(); - } - - @Test - void should_pass_when_package_manager_property_is_valid() throws IOException { - Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); - createBuildFile(projectDirectoryPath, new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) - .toMap()); - - final BuildResult result1 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME); - - assertTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); - final Path packageManagerNameFilePath = projectDirectoryPath.resolve( - Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_SPECIFICATION_FILE_NAME)); - assertThat(packageManagerNameFilePath).content(StandardCharsets.UTF_8).isEqualTo("npm@9.6.7"); - final Path packageManagerExecutablePathFilePath = projectDirectoryPath.resolve( - Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME)); - assertThat(packageManagerExecutablePathFilePath).exists(); - - final BuildResult result2 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME); - - assertTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE); - assertThat(packageManagerNameFilePath).content(StandardCharsets.UTF_8).isEqualTo("npm@9.6.7"); - assertThat(packageManagerExecutablePathFilePath).exists(); - } -} diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithDownloadedDistributionsFuncTest.java b/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithDownloadedDistributionsFuncTest.java deleted file mode 100644 index 46fad3b3..00000000 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithDownloadedDistributionsFuncTest.java +++ /dev/null @@ -1,212 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.gradle; - -import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskFailed; -import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; -import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; -import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; -import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; -import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; -import static org.siouan.frontendgradleplugin.test.TaskTypes.buildCorepackTaskDefinition; -import static org.siouan.frontendgradleplugin.test.TaskTypes.buildNodeTaskDefinition; -import static org.siouan.frontendgradleplugin.test.TaskTypes.buildNpmTaskDefinition; -import static org.siouan.frontendgradleplugin.test.TaskTypes.buildPnpmTaskDefinition; -import static org.siouan.frontendgradleplugin.test.TaskTypes.buildYarnTaskDefinition; -import static org.siouan.frontendgradleplugin.test.TaskTypes.createJavascriptFile; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.Set; - -import org.gradle.testkit.runner.BuildResult; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; -import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; - -/** - * Functional tests to verify task types {@link RunNode}, {@link RunNpm}, {@link RunPnpm}, {@link RunYarn} in a Gradle - * build, with a downloaded Node.js distribution. - */ -class TaskTypesWithDownloadedDistributionsFuncTest { - - private static final String RUN_COREPACK_TASK_NAME = "customCorepackTask"; - - private static final String RUN_NODE_TASK_NAME = "customNodeTask"; - - private static final String RUN_NPM_TASK_NAME = "customNpmTask"; - - private static final String RUN_PNPM_TASK_NAME = "customPnpmTask"; - - private static final String RUN_YARN_TASK_NAME = "customYarnTask"; - - @TempDir - Path temporaryDirectoryPath; - - private Path projectDirectoryPath; - - @BeforeEach - void setUp() { - projectDirectoryPath = temporaryDirectoryPath; - } - - @Test - void should_fail_running_custom_corepack_task_when_script_is_undefined() throws IOException { - final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, null); - createBuildFile(projectDirectoryPath, runCorepackTaskDefinition); - - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_COREPACK_TASK_NAME); - - assertTaskFailed(result, RUN_COREPACK_TASK_NAME); - } - - @Test - void should_fail_running_custom_node_task_when_script_is_undefined() throws IOException { - final String runNodeTaskDefinition = buildNodeTaskDefinition(RUN_NODE_TASK_NAME, null, null); - createBuildFile(projectDirectoryPath, runNodeTaskDefinition); - - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_NODE_TASK_NAME); - - assertTaskFailed(result, RUN_NODE_TASK_NAME); - } - - @Test - void should_fail_running_custom_npm_task_when_script_is_undefined() throws IOException { - final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, null); - createBuildFile(projectDirectoryPath, runNpmTaskDefinition); - - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_NPM_TASK_NAME); - - assertTaskFailed(result, RUN_NPM_TASK_NAME); - } - - @Test - void should_fail_running_custom_pnpm_task_when_script_is_undefined() throws IOException { - final String runPnpmTaskDefinition = buildPnpmTaskDefinition(RUN_PNPM_TASK_NAME, null); - createBuildFile(projectDirectoryPath, runPnpmTaskDefinition); - - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_PNPM_TASK_NAME); - - assertTaskFailed(result, RUN_PNPM_TASK_NAME); - } - - @Test - void should_fail_running_custom_yarn_task_when_script_is_undefined() throws IOException { - final String customTaskDefinition = buildYarnTaskDefinition(RUN_YARN_TASK_NAME, null); - createBuildFile(projectDirectoryPath, customTaskDefinition); - - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_YARN_TASK_NAME); - - assertTaskFailed(result, RUN_YARN_TASK_NAME); - } - - @Test - void should_run_custom_tasks() throws IOException { - final Path packageJsonDirectoryPath = Files.createDirectory(projectDirectoryPath.resolve("frontend")); - Files.copy(getResourcePath("package-npm.json"), packageJsonDirectoryPath.resolve("package.json")); - final Path temporaryScriptPath = createJavascriptFile(temporaryDirectoryPath.resolve("script.js")); - final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeInstallDirectory(projectDirectoryPath.resolve("node-dist")) - .packageJsonDirectory(packageJsonDirectoryPath) - .verboseModeEnabled(false); - final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, "-v"); - final String runNodeTaskDefinition = buildNodeTaskDefinition(RUN_NODE_TASK_NAME, - temporaryScriptPath.toString().replace("\\", "\\\\")); - final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, - FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, "run another-script"); - final String runPnpmTaskDefinition = buildPnpmTaskDefinition(RUN_PNPM_TASK_NAME, - FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, "run another-script"); - final String runYarnTaskDefinition = buildYarnTaskDefinition(RUN_YARN_TASK_NAME, - Set.of(FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME), - "run another-script"); - final String additionalContent = String.join("\n", runCorepackTaskDefinition, runNodeTaskDefinition, - runNpmTaskDefinition, runPnpmTaskDefinition, runYarnTaskDefinition); - createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), additionalContent); - - final BuildResult runNodeTaskResult1 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); - - assertTaskOutcomes(runNodeTaskResult1, PluginTaskOutcome.SUCCESS, RUN_NODE_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runNodeTaskResult2 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); - - assertTaskOutcomes(runNodeTaskResult2, PluginTaskOutcome.UP_TO_DATE, RUN_NODE_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runCorepackTaskResult1 = runGradle(projectDirectoryPath, RUN_COREPACK_TASK_NAME); - - assertTaskOutcomes(runCorepackTaskResult1, PluginTaskOutcome.UP_TO_DATE, RUN_COREPACK_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runNpmTaskResult1 = runGradle(projectDirectoryPath, RUN_NPM_TASK_NAME); - - assertTaskOutcomes(runNpmTaskResult1, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, RUN_NPM_TASK_NAME, PluginTaskOutcome.SUCCESS); - - final BuildResult runNpmTaskResult2 = runGradle(projectDirectoryPath, RUN_NPM_TASK_NAME); - - assertTaskOutcomes(runNpmTaskResult2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, RUN_NPM_TASK_NAME, PluginTaskOutcome.SUCCESS); - - Files.deleteIfExists(projectDirectoryPath.resolve("package-lock.json")); - Files.copy(getResourcePath("package-pnpm.json"), packageJsonDirectoryPath.resolve("package.json"), - StandardCopyOption.REPLACE_EXISTING); - createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), additionalContent); - - final BuildResult runNodeTaskResult3 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); - - assertTaskOutcomes(runNodeTaskResult3, PluginTaskOutcome.UP_TO_DATE, RUN_NODE_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runCorepackTaskResult2 = runGradle(projectDirectoryPath, RUN_COREPACK_TASK_NAME); - - assertTaskOutcomes(runCorepackTaskResult2, PluginTaskOutcome.UP_TO_DATE, RUN_COREPACK_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runPnpmTaskResult3 = runGradle(projectDirectoryPath, RUN_PNPM_TASK_NAME); - - assertTaskOutcomes(runPnpmTaskResult3, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, RUN_PNPM_TASK_NAME, PluginTaskOutcome.SUCCESS); - - final BuildResult runPnpmTaskResult4 = runGradle(projectDirectoryPath, RUN_PNPM_TASK_NAME); - - assertTaskOutcomes(runPnpmTaskResult4, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, RUN_PNPM_TASK_NAME, PluginTaskOutcome.SUCCESS); - - Files.deleteIfExists(packageJsonDirectoryPath.resolve("package-lock.json")); - Files.copy(getResourcePath("package-yarn.json"), packageJsonDirectoryPath.resolve("package.json"), - StandardCopyOption.REPLACE_EXISTING); - frontendMapBuilder.verboseModeEnabled(false); - createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), additionalContent); - - final BuildResult runNodeTaskResult5 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); - - assertTaskOutcomes(runNodeTaskResult5, PluginTaskOutcome.UP_TO_DATE, RUN_NODE_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runNodeTaskResult6 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); - - assertTaskOutcomes(runNodeTaskResult6, PluginTaskOutcome.UP_TO_DATE, RUN_NODE_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runCorepackTaskResult3 = runGradle(projectDirectoryPath, RUN_COREPACK_TASK_NAME); - - assertTaskOutcomes(runCorepackTaskResult3, PluginTaskOutcome.UP_TO_DATE, RUN_COREPACK_TASK_NAME, - PluginTaskOutcome.SUCCESS); - - final BuildResult runYarnTaskResult1 = runGradle(projectDirectoryPath, RUN_YARN_TASK_NAME); - - assertTaskOutcomes(runYarnTaskResult1, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, RUN_YARN_TASK_NAME, PluginTaskOutcome.SUCCESS); - - final BuildResult runYarnTaskResult2 = runGradle(projectDirectoryPath, RUN_YARN_TASK_NAME); - - assertTaskOutcomes(runYarnTaskResult2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, RUN_YARN_TASK_NAME, PluginTaskOutcome.SUCCESS); - } -} diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/bin/node b/plugin/src/intTest/resources/node-dist-without-corepack/bin/node deleted file mode 100644 index b9b6f161..00000000 --- a/plugin/src/intTest/resources/node-dist-without-corepack/bin/node +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "$0 $*" - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/bin/npx b/plugin/src/intTest/resources/node-dist-without-corepack/bin/npx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-corepack/bin/npx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/bin/pnpm b/plugin/src/intTest/resources/node-dist-without-corepack/bin/pnpm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-corepack/bin/pnpm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/bin/pnpx b/plugin/src/intTest/resources/node-dist-without-corepack/bin/pnpx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-corepack/bin/pnpx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/node.exe b/plugin/src/intTest/resources/node-dist-without-corepack/node.exe deleted file mode 100644 index 01ad30e9..00000000 Binary files a/plugin/src/intTest/resources/node-dist-without-corepack/node.exe and /dev/null differ diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/npx.cmd b/plugin/src/intTest/resources/node-dist-without-corepack/npx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-corepack/npx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/pnpm.cmd b/plugin/src/intTest/resources/node-dist-without-corepack/pnpm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-corepack/pnpm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/pnpx.cmd b/plugin/src/intTest/resources/node-dist-without-corepack/pnpx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-corepack/pnpx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-node/bin/npm b/plugin/src/intTest/resources/node-dist-without-node/bin/npm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-node/bin/npm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-node/bin/yarn b/plugin/src/intTest/resources/node-dist-without-node/bin/yarn deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-node/bin/yarn +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-node/npm.cmd b/plugin/src/intTest/resources/node-dist-without-node/npm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-node/npm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-node/yarn.cmd b/plugin/src/intTest/resources/node-dist-without-node/yarn.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-node/yarn.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/bin/corepack b/plugin/src/intTest/resources/node-dist-without-npm/bin/corepack deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/bin/corepack +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/bin/node b/plugin/src/intTest/resources/node-dist-without-npm/bin/node deleted file mode 100644 index b9b6f161..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/bin/node +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "$0 $*" - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/bin/npx b/plugin/src/intTest/resources/node-dist-without-npm/bin/npx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/bin/npx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/bin/pnpm b/plugin/src/intTest/resources/node-dist-without-npm/bin/pnpm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/bin/pnpm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/bin/pnpx b/plugin/src/intTest/resources/node-dist-without-npm/bin/pnpx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/bin/pnpx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/bin/yarn b/plugin/src/intTest/resources/node-dist-without-npm/bin/yarn deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/bin/yarn +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/corepack.cmd b/plugin/src/intTest/resources/node-dist-without-npm/corepack.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/corepack.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/node.exe b/plugin/src/intTest/resources/node-dist-without-npm/node.exe deleted file mode 100644 index 01ad30e9..00000000 Binary files a/plugin/src/intTest/resources/node-dist-without-npm/node.exe and /dev/null differ diff --git a/plugin/src/intTest/resources/node-dist-without-npm/npx.cmd b/plugin/src/intTest/resources/node-dist-without-npm/npx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/npx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/pnpm.cmd b/plugin/src/intTest/resources/node-dist-without-npm/pnpm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/pnpm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/pnpx.cmd b/plugin/src/intTest/resources/node-dist-without-npm/pnpx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/pnpx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npm/yarn.cmd b/plugin/src/intTest/resources/node-dist-without-npm/yarn.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npm/yarn.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/bin/corepack b/plugin/src/intTest/resources/node-dist-without-npx/bin/corepack deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/bin/corepack +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/bin/node b/plugin/src/intTest/resources/node-dist-without-npx/bin/node deleted file mode 100644 index b9b6f161..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/bin/node +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "$0 $*" - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/bin/npm b/plugin/src/intTest/resources/node-dist-without-npx/bin/npm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/bin/npm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/bin/pnpm b/plugin/src/intTest/resources/node-dist-without-npx/bin/pnpm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/bin/pnpm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/bin/pnpx b/plugin/src/intTest/resources/node-dist-without-npx/bin/pnpx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/bin/pnpx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/bin/yarn b/plugin/src/intTest/resources/node-dist-without-npx/bin/yarn deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/bin/yarn +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/corepack.cmd b/plugin/src/intTest/resources/node-dist-without-npx/corepack.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/corepack.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/node.exe b/plugin/src/intTest/resources/node-dist-without-npx/node.exe deleted file mode 100644 index 01ad30e9..00000000 Binary files a/plugin/src/intTest/resources/node-dist-without-npx/node.exe and /dev/null differ diff --git a/plugin/src/intTest/resources/node-dist-without-npx/npm.cmd b/plugin/src/intTest/resources/node-dist-without-npx/npm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/npm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/pnpm.cmd b/plugin/src/intTest/resources/node-dist-without-npx/pnpm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/pnpm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/pnpx.cmd b/plugin/src/intTest/resources/node-dist-without-npx/pnpx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/pnpx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-npx/yarn.cmd b/plugin/src/intTest/resources/node-dist-without-npx/yarn.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-npx/yarn.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/corepack b/plugin/src/intTest/resources/node-dist-without-pnpm/bin/corepack deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/corepack +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/node b/plugin/src/intTest/resources/node-dist-without-pnpm/bin/node deleted file mode 100644 index b9b6f161..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/node +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "$0 $*" - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/npm b/plugin/src/intTest/resources/node-dist-without-pnpm/bin/npm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/npm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/npx b/plugin/src/intTest/resources/node-dist-without-pnpm/bin/npx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/npx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/pnpx b/plugin/src/intTest/resources/node-dist-without-pnpm/bin/pnpx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/pnpx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/yarn b/plugin/src/intTest/resources/node-dist-without-pnpm/bin/yarn deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/bin/yarn +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/corepack.cmd b/plugin/src/intTest/resources/node-dist-without-pnpm/corepack.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/corepack.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/node.exe b/plugin/src/intTest/resources/node-dist-without-pnpm/node.exe deleted file mode 100644 index 01ad30e9..00000000 Binary files a/plugin/src/intTest/resources/node-dist-without-pnpm/node.exe and /dev/null differ diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/npm.cmd b/plugin/src/intTest/resources/node-dist-without-pnpm/npm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/npm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/npx.cmd b/plugin/src/intTest/resources/node-dist-without-pnpm/npx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/npx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/pnpx.cmd b/plugin/src/intTest/resources/node-dist-without-pnpm/pnpx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/pnpx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpm/yarn.cmd b/plugin/src/intTest/resources/node-dist-without-pnpm/yarn.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpm/yarn.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/corepack b/plugin/src/intTest/resources/node-dist-without-pnpx/bin/corepack deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/corepack +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/node b/plugin/src/intTest/resources/node-dist-without-pnpx/bin/node deleted file mode 100644 index b9b6f161..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/node +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "$0 $*" - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/npm b/plugin/src/intTest/resources/node-dist-without-pnpx/bin/npm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/npm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/npx b/plugin/src/intTest/resources/node-dist-without-pnpx/bin/npx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/npx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/pnpm b/plugin/src/intTest/resources/node-dist-without-pnpx/bin/pnpm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/pnpm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/yarn b/plugin/src/intTest/resources/node-dist-without-pnpx/bin/yarn deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/bin/yarn +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/corepack.cmd b/plugin/src/intTest/resources/node-dist-without-pnpx/corepack.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/corepack.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/node.exe b/plugin/src/intTest/resources/node-dist-without-pnpx/node.exe deleted file mode 100644 index 01ad30e9..00000000 Binary files a/plugin/src/intTest/resources/node-dist-without-pnpx/node.exe and /dev/null differ diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/npm.cmd b/plugin/src/intTest/resources/node-dist-without-pnpx/npm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/npm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/npx.cmd b/plugin/src/intTest/resources/node-dist-without-pnpx/npx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/npx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/pnpm.cmd b/plugin/src/intTest/resources/node-dist-without-pnpx/pnpm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/pnpm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-pnpx/yarn.cmd b/plugin/src/intTest/resources/node-dist-without-pnpx/yarn.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-pnpx/yarn.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/bin/corepack b/plugin/src/intTest/resources/node-dist-without-yarn/bin/corepack deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/bin/corepack +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/bin/node b/plugin/src/intTest/resources/node-dist-without-yarn/bin/node deleted file mode 100644 index b9b6f161..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/bin/node +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "$0 $*" - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/bin/npm b/plugin/src/intTest/resources/node-dist-without-yarn/bin/npm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/bin/npm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/bin/npx b/plugin/src/intTest/resources/node-dist-without-yarn/bin/npx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/bin/npx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/bin/pnpm b/plugin/src/intTest/resources/node-dist-without-yarn/bin/pnpm deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/bin/pnpm +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/bin/pnpx b/plugin/src/intTest/resources/node-dist-without-yarn/bin/pnpx deleted file mode 100644 index 41de4b4e..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/bin/pnpx +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/corepack.cmd b/plugin/src/intTest/resources/node-dist-without-yarn/corepack.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/corepack.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/node.exe b/plugin/src/intTest/resources/node-dist-without-yarn/node.exe deleted file mode 100644 index 01ad30e9..00000000 Binary files a/plugin/src/intTest/resources/node-dist-without-yarn/node.exe and /dev/null differ diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/npm.cmd b/plugin/src/intTest/resources/node-dist-without-yarn/npm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/npm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/npx.cmd b/plugin/src/intTest/resources/node-dist-without-yarn/npx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/npx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/pnpm.cmd b/plugin/src/intTest/resources/node-dist-without-yarn/pnpm.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/pnpm.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/resources/node-dist-without-yarn/pnpx.cmd b/plugin/src/intTest/resources/node-dist-without-yarn/pnpx.cmd deleted file mode 100644 index 1c835f1b..00000000 --- a/plugin/src/intTest/resources/node-dist-without-yarn/pnpx.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO off -ECHO %~dp0 %* -@IF EXIST "%~dp0\node.exe" ( - "%~dp0\node.exe" %* -) ELSE ( - node %* -) - diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleFrontedTaskFuncTest.java similarity index 52% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleTaskFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleFrontedTaskFuncTest.java index 7e66db15..bbb732e8 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleTaskFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleFrontedTaskFuncTest.java @@ -1,8 +1,13 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.ASSEMBLE_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertAssembleTaskOutcomes; import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; @@ -14,16 +19,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; /** - * Functional tests to verify the {@link AssembleTask} integration in a Gradle build. Test cases uses fake Node/Yarn - * distributions, to avoid the download overhead. The 'yarn' and 'npm' executables in these distributions simply call - * the 'node' executable with the same arguments. + * Functional tests to verify the {@link AssembleTask} integration in a Gradle build. Test cases uses fake + * Node/NPM/PNPM/Yarn distributions, to avoid the download overhead. The 'npm', 'pnpm', 'yarn' executables in these + * distributions simply call the 'node' executable with the same arguments. */ -class AssembleTaskFuncTest { +class AssembleFrontedTaskFuncTest { @TempDir Path projectDirectoryPath; @@ -36,86 +39,75 @@ void setUp() throws IOException { } @Test - void should_skip_task_when_package_json_file_is_not_a_file() throws IOException { + void should_skip_task_when_package_json_file_does_not_exist() throws IOException { final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .assembleScript("run assemble") .packageJsonDirectory(packageJsonDirectoryPath); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.ASSEMBLE_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, null); + assertAssembleTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SKIPPED, SKIPPED, SKIPPED, null); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.ASSEMBLE_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, null); + assertAssembleTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, SKIPPED, SKIPPED, SKIPPED, null); } @Test void should_skip_task_when_script_is_not_defined() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), packageJsonDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .packageJsonDirectory(packageJsonDirectoryPath); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.ASSEMBLE_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); + assertAssembleTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, null); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.ASSEMBLE_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); + assertAssembleTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, null); } @Test void should_skip_task_when_running_gradle_task_and_script_is_not_defined() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), packageJsonDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .packageJsonDirectory(packageJsonDirectoryPath); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.UP_TO_DATE); + assertAssembleTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, UP_TO_DATE); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.UP_TO_DATE); + assertAssembleTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, UP_TO_DATE); } @Test void should_assemble_frontend() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), packageJsonDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .packageJsonDirectory(packageJsonDirectoryPath) .assembleScript("run assemble"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); + assertAssembleTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_ASSEMBLE_TASK_NAME); - assertAssembleTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); + assertAssembleTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS); } } diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AuthenticationAndProxyFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AuthenticationAndProxyFuncTest.java similarity index 79% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AuthenticationAndProxyFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AuthenticationAndProxyFuncTest.java index 775cf809..61fc7ee8 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AuthenticationAndProxyFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AuthenticationAndProxyFuncTest.java @@ -1,7 +1,13 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_NODE_TASK_NAME; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcome; +import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.FAILED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; import java.io.IOException; import java.net.URL; @@ -14,11 +20,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.GradleBuildFiles; -import org.siouan.frontendgradleplugin.test.GradleHelper; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; import org.siouan.frontendgradleplugin.test.ServerConfigurator; /** @@ -81,12 +83,11 @@ void should_fail_installing_node_when_authentication_fails_on_distribution_serve // We use a HTTP address because proxying through HTTPS is not supported with WireMock. final FrontendMapBuilder frontendMapBuilder = configureNodeServerAndPluginWithDirectConnection("AYr2n{VF"); - GradleBuildFiles.createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result = GradleHelper.runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, FAILED); } // Same test as above, just use the exact password. @@ -97,12 +98,11 @@ void should_install_node_when_authentication_succeeds_on_distribution_server() t // We use a HTTP address because proxying through HTTPS is not supported with WireMock. final FrontendMapBuilder frontendMapBuilder = configureNodeServerAndPluginWithDirectConnection( DISTRIBUTION_SERVER_PASSWORD); - GradleBuildFiles.createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result = GradleHelper.runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradle(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, SUCCESS); } @Test @@ -115,13 +115,12 @@ void should_fail_installing_node_when_proxy_server_is_not_reachable() throws IOE // the proxy server, and the build shall succeed. final FrontendMapBuilder frontendMapBuilder = configureNodeServerAndPluginWithProxyConnection( DISTRIBUTION_SERVER_PORT + 10); - GradleBuildFiles.createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); // The build should fail with a java.net.ConnectException because the proxy server is not reachable. - final BuildResult result = GradleHelper.runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, FAILED); } // Same test as above, just use the exact proxy server port. @@ -131,12 +130,11 @@ void should_install_node_through_proxy_server() throws IOException { // We use a HTTP address because proxying through HTTPS is not supported with WireMock. final FrontendMapBuilder frontendMapBuilder = configureNodeServerAndPluginWithProxyConnection(); - GradleBuildFiles.createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result = GradleHelper.runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradle(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, SUCCESS); } @Test @@ -145,12 +143,11 @@ void should_fail_installing_node_when_authentication_fails_on_proxy_server() thr // We use a HTTP address because proxying through HTTPS is not supported with WireMock. final FrontendMapBuilder frontendMapBuilder = configureNodeServerAndPluginWithProxyConnection("xE!s67O?"); - GradleBuildFiles.createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result = GradleHelper.runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, FAILED); } // Same test as above, just use the exact password. @@ -161,12 +158,11 @@ void should_install_node_when_authentication_succeeds_on_proxy_server() throws I // We use a HTTP address because proxying through HTTPS is not supported with WireMock. final FrontendMapBuilder frontendMapBuilder = configureNodeServerAndPluginWithProxyConnection( PROXY_SERVER_PASSWORD); - GradleBuildFiles.createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result = GradleHelper.runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradle(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, SUCCESS); } private FrontendMapBuilder configureNodeServerAndPluginWithDirectConnection(final String distributionServerPassword) @@ -207,7 +203,7 @@ private FrontendMapBuilder configureServerAndPlugin(final String nodeDistributio final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder().verboseModeEnabled(false); if (nodeDistributionUrlRoot != null) { frontendMapBuilder - .nodeVersion("18.17.1") + .nodeVersion("20.14.0") .nodeDistributionUrlRoot(nodeDistributionUrlRoot) .nodeDistributionUrlPathPattern(nodeDistributionUrlPathPattern); distributionServerConfigurator.withNodeDistribution(); diff --git a/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckFrontendTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckFrontendTaskFuncTest.java new file mode 100644 index 00000000..15f6928e --- /dev/null +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckFrontendTaskFuncTest.java @@ -0,0 +1,101 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.CHECK_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME; +import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertCheckTaskOutcomes; +import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; +import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; +import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.gradle.testkit.runner.BuildResult; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; + +/** + * Functional tests to verify the {@link CheckTask} integration in a Gradle build. Test cases uses fake + * Node/NPM/PNPM/Yarn distributions, to avoid the download overhead. The 'npm', 'pnpm', 'yarn' executables in these + * distributions simply call the 'node' executable with the same arguments. + */ +class CheckFrontendTaskFuncTest { + + @TempDir + Path projectDirectoryPath; + + @Test + void should_skip_task_when_package_json_file_does_not_exist() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) + .checkScript("run check"); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + + final BuildResult result1 = runGradle(projectDirectoryPath, CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SKIPPED, SKIPPED, SKIPPED, null); + + final BuildResult result2 = runGradle(projectDirectoryPath, CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, SKIPPED, SKIPPED, SKIPPED, null); + } + + @Test + void should_skip_task_when_script_is_not_defined() throws IOException { + Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + + final BuildResult result1 = runGradle(projectDirectoryPath, CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, null); + + final BuildResult result2 = runGradle(projectDirectoryPath, CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, null); + } + + @Test + void should_skip_task_when_running_gradle_task_and_script_is_not_defined() throws IOException { + Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, UP_TO_DATE); + + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, UP_TO_DATE); + } + + @Test + void should_check_frontend() throws IOException { + Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) + .checkScript("run check"); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS); + + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_CHECK_TASK_NAME); + + assertCheckTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS); + } +} diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanFrontendTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanFrontendTaskFuncTest.java similarity index 52% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanFrontendTaskFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanFrontendTaskFuncTest.java index 3173bb85..113aa4dd 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanFrontendTaskFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanFrontendTaskFuncTest.java @@ -1,8 +1,13 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.CLEAN_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertCleanTaskOutcomes; import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; @@ -13,9 +18,7 @@ import org.gradle.testkit.runner.BuildResult; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; /** * Functional tests to verify the {@link CleanTask} integration in a Gradle build. Test cases uses fake Node/Yarn @@ -28,81 +31,71 @@ class CleanFrontendTaskFuncTest { Path projectDirectoryPath; @Test - void should_skip_task_when_package_json_file_is_not_a_file() throws IOException { + void should_skip_task_when_package_json_file_does_not_exist() throws IOException { final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .cleanScript("run clean"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CLEAN_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, null); + assertCleanTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SKIPPED, SKIPPED, SKIPPED, null); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CLEAN_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, null); + assertCleanTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, SKIPPED, SKIPPED, SKIPPED, null); } @Test void should_skip_task_when_script_is_not_defined() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CLEAN_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); + assertCleanTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, null); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.CLEAN_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); + assertCleanTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, null); } @Test void should_skip_task_when_running_gradle_task_and_script_is_not_defined() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS); + assertCleanTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, SUCCESS); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.UP_TO_DATE); + assertCleanTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, UP_TO_DATE); } @Test void should_clean_frontend() throws IOException { Files.copy(getResourcePath("package-npm.json"), projectDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .cleanScript("run clean"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); + assertCleanTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_CLEAN_TASK_NAME); - assertCleanTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.UP_TO_DATE); + assertCleanTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SUCCESS, UP_TO_DATE); } } diff --git a/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallCorepackTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallCorepackTaskFuncTest.java new file mode 100644 index 00000000..21c1d8ea --- /dev/null +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallCorepackTaskFuncTest.java @@ -0,0 +1,75 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_COREPACK_TASK_NAME; +import static org.siouan.frontendgradleplugin.infrastructure.gradle.InstallCorepackTask.LATEST_VERSION_ARGUMENT; +import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; +import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.FAILED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; +import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; +import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.gradle.testkit.runner.BuildResult; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; + +/** + * Functional tests to verify the {@link InstallCorepackTask} integration in a Gradle build. Test cases uses a fake Node + * distribution, to avoid the download overhead. All executables in these distributions simply call the 'node' + * executable with the same arguments. + */ +class InstallCorepackTaskFuncTest { + + @TempDir + Path projectDirectoryPath; + + @Test + void should_skip_task_when_corepack_version_property_is_null() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + + final BuildResult result = runGradle(projectDirectoryPath, INSTALL_COREPACK_TASK_NAME); + + assertTaskOutcomes(result, SUCCESS, SKIPPED); + } + + @Test + void should_fail_when_node_install_directory_is_not_a_directory() throws IOException { + Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); + createBuildFile(projectDirectoryPath, + new FrontendMapBuilder().nodeDistributionProvided(true).corepackVersion(LATEST_VERSION_ARGUMENT).toMap()); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_COREPACK_TASK_NAME); + + assertTaskOutcomes(result, SKIPPED, FAILED); + } + + @Test + void should_install_corepack() throws IOException { + Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .corepackVersion(LATEST_VERSION_ARGUMENT) + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + + final BuildResult result1 = runGradle(projectDirectoryPath, INSTALL_COREPACK_TASK_NAME); + + assertTaskOutcomes(result1, SUCCESS, SUCCESS); + + final BuildResult result2 = runGradle(projectDirectoryPath, INSTALL_COREPACK_TASK_NAME); + + assertTaskOutcomes(result2, UP_TO_DATE, UP_TO_DATE); + } +} diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTaskFuncTest.java similarity index 53% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTaskFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTaskFuncTest.java index 68553f11..fde86bda 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTaskFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTaskFuncTest.java @@ -1,8 +1,12 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; @@ -13,14 +17,12 @@ import org.gradle.testkit.runner.BuildResult; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; /** * Functional tests to verify the {@link InstallFrontendTask} integration in a Gradle build. Test cases uses fake - * Node/Yarn distributions, to avoid the download overhead. The 'yarn' and 'npm' executables in these distributions - * simply call the 'node' executable with the same arguments. + * Node/NPM/PNPM/Yarn distributions, to avoid the download overhead. The 'npm', 'pnpm', 'yarn' executables in these + * distributions simply call the 'node' executable with the same arguments. */ class InstallFrontendTaskFuncTest { @@ -28,59 +30,53 @@ class InstallFrontendTaskFuncTest { Path projectDirectoryPath; @Test - void should_skip_task_when_package_json_file_is_not_a_file() throws IOException { + void should_skip_task_when_package_json_file_does_not_exist() throws IOException { final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, INSTALL_FRONTEND_TASK_NAME); - assertTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED); + assertTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SKIPPED, SKIPPED); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, INSTALL_FRONTEND_TASK_NAME); - assertTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.SKIPPED); + assertTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, SKIPPED, SKIPPED); } @Test void should_succeed_with_default_script() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, INSTALL_FRONTEND_TASK_NAME); - assertTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, INSTALL_FRONTEND_TASK_NAME); - assertTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS); } @Test void should_succeed_with_custom_script() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .installScript("ci"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, INSTALL_FRONTEND_TASK_NAME); - assertTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, INSTALL_FRONTEND_TASK_NAME); - assertTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS); } } diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTaskFuncTest.java similarity index 67% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTaskFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTaskFuncTest.java index cc820949..83da0ecb 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTaskFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTaskFuncTest.java @@ -1,9 +1,14 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_NODE_TASK_NAME; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcome; import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.FAILED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; import java.io.IOException; @@ -13,9 +18,7 @@ import org.gradle.testkit.runner.BuildResult; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; /** * Functional tests to verify the {@link InstallNodeTask} integration in a Gradle build. Test cases uses a fake Node @@ -30,57 +33,54 @@ class InstallNodeTaskFuncTest { void should_be_skipped_when_distribution_is_provided() throws IOException { createBuildFile(projectDirectoryPath, new FrontendMapBuilder().nodeDistributionProvided(true).toMap()); - final BuildResult result = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradle(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.SKIPPED); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, SKIPPED); } @Test void should_fail_when_node_version_is_not_set() throws IOException { createBuildFile(projectDirectoryPath, Map.of()); - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, FAILED); } @Test void should_fail_when_distribution_cannot_be_downloaded_due_to_an_unknown_version() throws IOException { createBuildFile(projectDirectoryPath, Map.of("nodeVersion", "0.76.34")); - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, FAILED); } @Test void should_fail_when_distribution_download_url_is_invalid() throws IOException { final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") + .nodeVersion("20.14.0") .nodeDistributionUrlRoot("protocol://domain/unknown"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcome(result, INSTALL_NODE_TASK_NAME, FAILED); } @Test void should_succeed_first_time_and_be_up_to_date_next_time() throws IOException { final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result1, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcome(result1, INSTALL_NODE_TASK_NAME, SUCCESS); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, INSTALL_NODE_TASK_NAME); - assertTaskOutcome(result2, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, PluginTaskOutcome.UP_TO_DATE); + assertTaskOutcome(result2, INSTALL_NODE_TASK_NAME, UP_TO_DATE); } } diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java similarity index 57% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java index 1ea246f0..9787de9b 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTaskFuncTest.java @@ -1,9 +1,14 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.FAILED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; @@ -15,9 +20,7 @@ import org.gradle.testkit.runner.BuildResult; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; /** * Functional tests to verify the {@link InstallPackageManagerTask} integration in a Gradle build. Test cases uses a @@ -30,21 +33,19 @@ class InstallPackageManagerTaskFuncTest { Path projectDirectoryPath; @Test - void should_skip_task_when_package_json_file_is_not_a_file() throws IOException { + void should_skip_task_when_package_json_file_does_not_exist() throws IOException { final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED); + assertTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SKIPPED); - final BuildResult result2 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SKIPPED); + assertTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, SKIPPED); } @Test @@ -52,62 +53,49 @@ void should_fail_when_node_install_directory_is_not_a_directory() throws IOExcep Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); createBuildFile(projectDirectoryPath, new FrontendMapBuilder().nodeDistributionProvided(true).toMap()); - final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.FAILED); + assertTaskOutcomes(result, SKIPPED, SKIPPED, SUCCESS, FAILED); } @Test void should_install_package_managers() throws IOException { Files.copy(getResourcePath("package-npm.json"), projectDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")); + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult installNpmResult1 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult installNpmResult1 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(installNpmResult1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(installNpmResult1, SUCCESS, SKIPPED, SUCCESS, SUCCESS); - final BuildResult installNpmResult2 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult installNpmResult2 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(installNpmResult2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE); + assertTaskOutcomes(installNpmResult2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE); Files.copy(getResourcePath("package-pnpm.json"), projectDirectoryPath.resolve("package.json"), StandardCopyOption.REPLACE_EXISTING); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult installPnpmResult1 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult installPnpmResult1 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(installPnpmResult1, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(installPnpmResult1, UP_TO_DATE, SKIPPED, SUCCESS, SUCCESS); - final BuildResult installPnpmResult2 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult installPnpmResult2 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(installPnpmResult2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE); + assertTaskOutcomes(installPnpmResult2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE); Files.copy(getResourcePath("package-yarn.json"), projectDirectoryPath.resolve("package.json"), StandardCopyOption.REPLACE_EXISTING); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult installYarnResult1 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult installYarnResult1 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(installYarnResult1, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(installYarnResult1, UP_TO_DATE, SKIPPED, SUCCESS, SUCCESS); - final BuildResult installYarnResult2 = runGradle(projectDirectoryPath, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME); + final BuildResult installYarnResult2 = runGradle(projectDirectoryPath, INSTALL_PACKAGE_MANAGER_TASK_NAME); - assertTaskOutcomes(installYarnResult2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE); + assertTaskOutcomes(installYarnResult2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE); } } diff --git a/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/MultiProjectsFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/MultiProjectsFuncTest.java new file mode 100644 index 00000000..b4dc778c --- /dev/null +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/MultiProjectsFuncTest.java @@ -0,0 +1,151 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME; +import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; +import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.GradleSettingsFiles.createSettingsFile; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.IGNORED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; +import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; +import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.gradle.language.base.plugins.LifecycleBasePlugin; +import org.gradle.testkit.runner.BuildResult; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; + +/** + * This test suite verifies task execution in a multi-projects build, where Node is downloaded and installed by one + * sub-project, and used as a provided distribution by a other sub-projects. The project layout is: + *
+ * node/                        Node install directory, shall be created by sub-project-1
+ * yarn-project-1/              Yarn sub-project
+ *      build.gradle            Installs Node and Yarn distributions
+ * npm-project-2/               NPM sub-project
+ *      build.gradle            Uses distributions provided by sub-project-1
+ * pnpm-project-3/              PNPM sub-project
+ *      build.gradle            Uses distributions provided by sub-project-1
+ * build.gradle                 Declares plugin, but doesn't apply it
+ * settings.gradle
+ * 
+ */ +class MultiProjectsFuncTest { + + private static final String YARN_SUB_PROJECT_NAME = "yarn-project-1"; + + private static final String NPM_SUB_PROJECT_NAME = "npm-project-2"; + + private static final String PNPM_SUB_PROJECT_NAME = "pnpm-project-3"; + + @TempDir + Path temporaryDirectorypath; + + @Test + void should_run_tasks_in_sub_projects() throws IOException { + // Root project + final Path projectDirectoryPath = temporaryDirectorypath; + createSettingsFile(projectDirectoryPath, "multi-projects-test", YARN_SUB_PROJECT_NAME, NPM_SUB_PROJECT_NAME, + PNPM_SUB_PROJECT_NAME); + createBuildFile(projectDirectoryPath, true, false); + final Path nodeInstallDirectory = Paths.get("${rootProject.projectDir}/node"); + + // Sub-project 1 + final Path yarnSubProjectPath = Files.createDirectory(projectDirectoryPath.resolve(YARN_SUB_PROJECT_NAME)); + Files.copy(getResourcePath("package-yarn.json"), yarnSubProjectPath.resolve("package.json")); + final FrontendMapBuilder yarnSubProjectFrontendProperties = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeInstallDirectory(nodeInstallDirectory) + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) + .installScript("run install") + .cleanScript("run clean") + .assembleScript("run assemble") + .checkScript("run check") + .publishScript("run publish"); + createBuildFile(yarnSubProjectPath, yarnSubProjectFrontendProperties.toMap()); + + // Sub-project 2 + final Path npmSubProjectPath = Files.createDirectory(projectDirectoryPath.resolve(NPM_SUB_PROJECT_NAME)); + Files.copy(getResourcePath("package-npm.json"), npmSubProjectPath.resolve("package.json")); + final FrontendMapBuilder npmSubProjectFrontendProperties = new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(nodeInstallDirectory) + .installScript("run install") + .cleanScript("run clean") + .assembleScript("run assemble") + .checkScript("run check") + .publishScript("run publish"); + createBuildFile(npmSubProjectPath, npmSubProjectFrontendProperties.toMap(), + "tasks.named('installPackageManager').configure {" + "dependsOn project(':" + YARN_SUB_PROJECT_NAME + + "').installNode\n}"); + + // Sub-project 3 + final Path pnpmSubProjectPath = Files.createDirectory(projectDirectoryPath.resolve(PNPM_SUB_PROJECT_NAME)); + Files.copy(getResourcePath("package-pnpm.json"), pnpmSubProjectPath.resolve("package.json")); + final FrontendMapBuilder pnpmSubProjectFrontendProperties = new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(nodeInstallDirectory) + .installScript("run install") + .cleanScript("run clean") + .assembleScript("run assemble") + .checkScript("run check") + .publishScript("run publish"); + createBuildFile(pnpmSubProjectPath, pnpmSubProjectFrontendProperties.toMap(), + "tasks.named('installPackageManager').configure {" + "dependsOn project(':" + YARN_SUB_PROJECT_NAME + + "').installNode\n}"); + + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_CLEAN_TASK_NAME, + LifecycleBasePlugin.BUILD_TASK_NAME, GRADLE_PUBLISH_TASK_NAME); + + assertTaskOutcomes(result1, YARN_SUB_PROJECT_NAME, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SUCCESS, + SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result1, NPM_SUB_PROJECT_NAME, SKIPPED, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS, + SUCCESS, SUCCESS, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result1, PNPM_SUB_PROJECT_NAME, SKIPPED, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SUCCESS, + SUCCESS, SUCCESS, SUCCESS, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result1, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, + IGNORED, IGNORED, IGNORED, IGNORED); + + final BuildResult result2 = runGradle(projectDirectoryPath, LifecycleBasePlugin.BUILD_TASK_NAME, + GRADLE_PUBLISH_TASK_NAME); + + assertTaskOutcomes(result2, YARN_SUB_PROJECT_NAME, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, + IGNORED, SUCCESS, SUCCESS, SUCCESS, IGNORED, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result2, NPM_SUB_PROJECT_NAME, SKIPPED, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, IGNORED, + SUCCESS, SUCCESS, SUCCESS, IGNORED, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result2, PNPM_SUB_PROJECT_NAME, SKIPPED, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, IGNORED, + SUCCESS, SUCCESS, SUCCESS, IGNORED, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result2, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, + IGNORED, IGNORED, IGNORED, IGNORED); + + final BuildResult result3 = runGradle(projectDirectoryPath, LifecycleBasePlugin.BUILD_TASK_NAME, + GRADLE_PUBLISH_TASK_NAME); + + assertTaskOutcomes(result3, YARN_SUB_PROJECT_NAME, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, + IGNORED, SUCCESS, SUCCESS, SUCCESS, IGNORED, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result3, NPM_SUB_PROJECT_NAME, SKIPPED, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, IGNORED, + SUCCESS, SUCCESS, SUCCESS, IGNORED, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result3, PNPM_SUB_PROJECT_NAME, SKIPPED, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, IGNORED, + SUCCESS, SUCCESS, SUCCESS, IGNORED, SUCCESS, SUCCESS, SUCCESS); + + assertTaskOutcomes(result3, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, + IGNORED, IGNORED, IGNORED, IGNORED); + } +} diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishFrontendTaskFuncTest.java similarity index 51% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishTaskFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishFrontendTaskFuncTest.java index 29c886e1..9316a3e2 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishTaskFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishFrontendTaskFuncTest.java @@ -1,8 +1,13 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.PUBLISH_TASK_NAME; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertPublishTaskOutcomes; import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; @@ -14,18 +19,16 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; /** - * Functional tests to verify the {@link PublishTask} integration in a Gradle build. Test cases uses fake Node/Yarn - * distributions, to avoid the download overhead. The 'yarn' and 'npm' executables in these distributions simply call - * the 'node' executable with the same arguments. + * Functional tests to verify the {@link PublishTask} integration in a Gradle build. Test cases uses fake + * Node/NPM/PNPM/Yarn distributions, to avoid the download overhead. The 'npm', 'pnpm', 'yarn' executables in these + * distributions simply call the 'node' executable with the same arguments. * * @since 1.4.0 */ -class PublishTaskFuncTest { +class PublishFrontendTaskFuncTest { @TempDir Path projectDirectoryPath; @@ -37,68 +40,78 @@ void setUp() throws IOException { packageJsonDirectoryPath = Files.createDirectory(projectDirectoryPath.resolve("frontend")); } + @Test + void should_skip_plugin_task_when_package_json_file_does_not_exist() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) + .assembleScript("run assemble") + .publishScript("run publish") + .packageJsonDirectory(packageJsonDirectoryPath); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); + + final BuildResult result1 = runGradle(projectDirectoryPath, PUBLISH_TASK_NAME); + + assertPublishTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SKIPPED, SKIPPED, SKIPPED, null); + + final BuildResult result2 = runGradle(projectDirectoryPath, PUBLISH_TASK_NAME); + + assertPublishTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, SKIPPED, SKIPPED, SKIPPED, null); + } + @Test void should_skip_plugin_task_when_script_is_not_defined() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), packageJsonDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .packageJsonDirectory(packageJsonDirectoryPath); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.PUBLISH_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, PUBLISH_TASK_NAME); - assertPublishTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); + assertPublishTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, null); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.PUBLISH_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, PUBLISH_TASK_NAME); - assertPublishTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, null); + assertPublishTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, null); } @Test void should_skip_plugin_task_when_running_gradle_task_and_script_is_not_defined() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), packageJsonDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .packageJsonDirectory(packageJsonDirectoryPath); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_PUBLISH_TASK_NAME); - assertPublishTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.UP_TO_DATE); + assertPublishTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SKIPPED, UP_TO_DATE); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_PUBLISH_TASK_NAME); - assertPublishTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SKIPPED, - PluginTaskOutcome.UP_TO_DATE); + assertPublishTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SKIPPED, UP_TO_DATE); } @Test void should_publish_frontend() throws IOException { Files.copy(getResourcePath("package-any-manager.json"), packageJsonDirectoryPath.resolve("package.json")); final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() - .nodeVersion("18.17.1") - .nodeDistributionUrl(getResourceUrl("node-v18.17.1.zip")) + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) .packageJsonDirectory(packageJsonDirectoryPath) .assembleScript("run assemble") .publishScript("run publish"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap()); - final BuildResult result1 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); + final BuildResult result1 = runGradle(projectDirectoryPath, GRADLE_PUBLISH_TASK_NAME); - assertPublishTaskOutcomes(result1, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS); + assertPublishTaskOutcomes(result1, SUCCESS, SKIPPED, SUCCESS, SUCCESS, SUCCESS, SUCCESS, SUCCESS); - final BuildResult result2 = runGradle(projectDirectoryPath, FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); + final BuildResult result2 = runGradle(projectDirectoryPath, GRADLE_PUBLISH_TASK_NAME); - assertPublishTaskOutcomes(result2, PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS); + assertPublishTaskOutcomes(result2, UP_TO_DATE, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS); } } diff --git a/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTaskFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTaskFuncTest.java new file mode 100644 index 00000000..ada47290 --- /dev/null +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ResolvePackageManagerTaskFuncTest.java @@ -0,0 +1,133 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.PACKAGE_JSON_FILE_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.PACKAGE_MANAGER_SPECIFICATION_FILE_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME; +import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; +import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.FAILED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.IGNORED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; +import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; +import static org.siouan.frontendgradleplugin.test.Resources.getResourceUrl; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.gradle.testkit.runner.BuildResult; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; + +/** + * Functional tests to verify the {@link ResolvePackageManagerTask} integration in a Gradle build. + * + * @since 7.0.0 + */ +class ResolvePackageManagerTaskFuncTest { + + @TempDir + Path projectDirectoryPath; + + @Test + void should_delete_output_files_when_package_json_file_does_not_exist() throws IOException { + Files.createDirectory(projectDirectoryPath.resolve(PACKAGE_JSON_FILE_NAME)); + createBuildFile(projectDirectoryPath, new FrontendMapBuilder().nodeDistributionProvided(true).toMap()); + final Path packageManagerSpecificationFilePath = projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_SPECIFICATION_FILE_NAME)); + Files.createDirectories(packageManagerSpecificationFilePath.getParent()); + Files.createFile(packageManagerSpecificationFilePath); + final Path packageManagerExecutablePathFilePath = projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME)); + Files.createFile(packageManagerExecutablePathFilePath); + + final BuildResult result1 = runGradle(projectDirectoryPath, RESOLVE_PACKAGE_MANAGER_TASK_NAME); + + assertTaskOutcomes(result1, SKIPPED, IGNORED, SUCCESS); + assertThat(packageManagerSpecificationFilePath).doesNotExist(); + assertThat(packageManagerExecutablePathFilePath).doesNotExist(); + + final BuildResult result2 = runGradle(projectDirectoryPath, RESOLVE_PACKAGE_MANAGER_TASK_NAME); + + assertTaskOutcomes(result2, SKIPPED, IGNORED, UP_TO_DATE); + assertThat(packageManagerSpecificationFilePath).doesNotExist(); + assertThat(packageManagerExecutablePathFilePath).doesNotExist(); + } + + @Test + void should_fail_when_package_manager_property_is_not_set_in_package_json_file() throws IOException { + Files.copy(getResourcePath("package-no-manager.json"), projectDirectoryPath.resolve("package.json")); + createBuildFile(projectDirectoryPath, new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(getResourcePath("node-dist-provided")) + .toMap()); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RESOLVE_PACKAGE_MANAGER_TASK_NAME); + + assertTaskOutcomes(result, SKIPPED, IGNORED, FAILED); + assertThat(projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_SPECIFICATION_FILE_NAME))).doesNotExist(); + assertThat(projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME))).doesNotExist(); + } + + @Test + void should_fail_when_package_manager_property_is_invalid_in_package_json_file() throws IOException { + Files.copy(getResourcePath("package-invalid-manager.json"), projectDirectoryPath.resolve("package.json")); + createBuildFile(projectDirectoryPath, new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(getResourcePath("node-dist-provided")) + .toMap()); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RESOLVE_PACKAGE_MANAGER_TASK_NAME); + + assertTaskOutcomes(result, SKIPPED, IGNORED, FAILED); + assertThat(projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_SPECIFICATION_FILE_NAME))).doesNotExist(); + assertThat(projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME))).doesNotExist(); + } + + @Test + void should_pass_when_package_manager_property_is_valid() throws IOException { + Files.copy(getResourcePath("package-any-manager.json"), projectDirectoryPath.resolve("package.json")); + createBuildFile(projectDirectoryPath, new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeDistributionUrl(getResourceUrl("node-v20.14.0.zip")) + .toMap()); + + final BuildResult result1 = runGradle(projectDirectoryPath, RESOLVE_PACKAGE_MANAGER_TASK_NAME); + + assertTaskOutcomes(result1, SUCCESS, IGNORED, SUCCESS); + final Path packageManagerNameFilePath = projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_SPECIFICATION_FILE_NAME)); + assertThat(packageManagerNameFilePath).content(StandardCharsets.UTF_8).isEqualTo("npm@9.6.7"); + final Path packageManagerExecutablePathFilePath = projectDirectoryPath.resolve( + Paths.get(DEFAULT_CACHE_DIRECTORY_NAME, RESOLVE_PACKAGE_MANAGER_TASK_NAME, + PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME)); + assertThat(packageManagerExecutablePathFilePath).exists(); + + final BuildResult result2 = runGradle(projectDirectoryPath, RESOLVE_PACKAGE_MANAGER_TASK_NAME); + + assertTaskOutcomes(result2, UP_TO_DATE, IGNORED, UP_TO_DATE); + assertThat(packageManagerNameFilePath).content(StandardCharsets.UTF_8).isEqualTo("npm@9.6.7"); + assertThat(packageManagerExecutablePathFilePath).exists(); + } +} diff --git a/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithDownloadedDistributionsFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithDownloadedDistributionsFuncTest.java new file mode 100644 index 00000000..436480a3 --- /dev/null +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithDownloadedDistributionsFuncTest.java @@ -0,0 +1,155 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_NODE_TASK_NAME; +import static org.siouan.frontendgradleplugin.infrastructure.gradle.InstallCorepackTask.LATEST_VERSION_ARGUMENT; +import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; +import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; +import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; +import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; +import static org.siouan.frontendgradleplugin.test.TaskTypes.buildCorepackTaskDefinition; +import static org.siouan.frontendgradleplugin.test.TaskTypes.buildNodeTaskDefinition; +import static org.siouan.frontendgradleplugin.test.TaskTypes.buildNpmTaskDefinition; +import static org.siouan.frontendgradleplugin.test.TaskTypes.buildPnpmTaskDefinition; +import static org.siouan.frontendgradleplugin.test.TaskTypes.buildYarnTaskDefinition; +import static org.siouan.frontendgradleplugin.test.TaskTypes.createJavascriptFileLoggingProcessTitle; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Map; +import java.util.Set; + +import org.gradle.testkit.runner.BuildResult; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; + +/** + * Functional tests to verify task types {@link RunNode}, {@link RunNpm}, {@link RunPnpm}, {@link RunYarn} in a Gradle + * build, with a downloaded Node.js distribution. + */ +class TaskTypesWithDownloadedDistributionsFuncTest { + + private static final String RUN_COREPACK_TASK_NAME = "customCorepackTask"; + + private static final String RUN_NODE_TASK_NAME = "customNodeTask"; + + private static final String RUN_NPM_TASK_NAME = "customNpmTask"; + + private static final String RUN_PNPM_TASK_NAME = "customPnpmTask"; + + private static final String RUN_YARN_TASK_NAME = "customYarnTask"; + + @TempDir + Path temporaryDirectoryPath; + + private Path projectDirectoryPath; + + @BeforeEach + void setUp() { + projectDirectoryPath = temporaryDirectoryPath; + } + + @Test + void should_run_custom_tasks_and_forward_environment_variables() throws IOException { + final Path packageJsonDirectoryPath = Files.createDirectory(projectDirectoryPath.resolve("frontend")); + Files.copy(getResourcePath("package-npm.json"), packageJsonDirectoryPath.resolve("package.json")); + final Path temporaryScriptPath = createJavascriptFileLoggingProcessTitle( + temporaryDirectoryPath.resolve("script.js")); + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeVersion("20.14.0") + .nodeInstallDirectory(projectDirectoryPath.resolve("node-dist")) + .corepackVersion(LATEST_VERSION_ARGUMENT) + .packageJsonDirectory(packageJsonDirectoryPath); + final String runNodeTaskDefinition = buildNodeTaskDefinition(RUN_NODE_TASK_NAME, + temporaryScriptPath.toString().replace("\\", "\\\\"), + Map.of("NODE_OPTIONS", "--title=\\\"Run custom node task\\\"")); + final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, "-v"); + final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, INSTALL_FRONTEND_TASK_NAME, + "run another-script"); + final String runPnpmTaskDefinition = buildPnpmTaskDefinition(RUN_PNPM_TASK_NAME, INSTALL_FRONTEND_TASK_NAME, + "run another-script"); + final String runYarnTaskDefinition = buildYarnTaskDefinition(RUN_YARN_TASK_NAME, + Set.of(INSTALL_NODE_TASK_NAME, INSTALL_FRONTEND_TASK_NAME), "run another-script"); + final String additionalContent = String.join("\n", runCorepackTaskDefinition, runNodeTaskDefinition, + runNpmTaskDefinition, runPnpmTaskDefinition, runYarnTaskDefinition); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), additionalContent); + + final BuildResult runNodeTaskResult1 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); + + assertTaskOutcomes(runNodeTaskResult1, SUCCESS, RUN_NODE_TASK_NAME, SUCCESS); + assertThat(runNodeTaskResult1.getOutput()).containsIgnoringNewLines( + "> Task :customNodeTask\nRun custom node task\n"); + + final BuildResult runNodeTaskResult2 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); + + assertTaskOutcomes(runNodeTaskResult2, UP_TO_DATE, RUN_NODE_TASK_NAME, SUCCESS); + + final BuildResult runCorepackTaskResult1 = runGradle(projectDirectoryPath, RUN_COREPACK_TASK_NAME); + + assertTaskOutcomes(runCorepackTaskResult1, UP_TO_DATE, SUCCESS, RUN_COREPACK_TASK_NAME, SUCCESS); + + final BuildResult runNpmTaskResult1 = runGradle(projectDirectoryPath, RUN_NPM_TASK_NAME); + + assertTaskOutcomes(runNpmTaskResult1, UP_TO_DATE, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS, RUN_NPM_TASK_NAME, + SUCCESS); + + final BuildResult runNpmTaskResult2 = runGradle(projectDirectoryPath, RUN_NPM_TASK_NAME); + + assertTaskOutcomes(runNpmTaskResult2, UP_TO_DATE, UP_TO_DATE, UP_TO_DATE, UP_TO_DATE, SUCCESS, + RUN_NPM_TASK_NAME, SUCCESS); + + Files.deleteIfExists(projectDirectoryPath.resolve("package-lock.json")); + Files.copy(getResourcePath("package-pnpm.json"), packageJsonDirectoryPath.resolve("package.json"), + StandardCopyOption.REPLACE_EXISTING); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), additionalContent); + + final BuildResult runNodeTaskResult3 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); + + assertTaskOutcomes(runNodeTaskResult3, UP_TO_DATE, RUN_NODE_TASK_NAME, SUCCESS); + + final BuildResult runCorepackTaskResult2 = runGradle(projectDirectoryPath, RUN_COREPACK_TASK_NAME); + + assertTaskOutcomes(runCorepackTaskResult2, UP_TO_DATE, UP_TO_DATE, RUN_COREPACK_TASK_NAME, SUCCESS); + + final BuildResult runPnpmTaskResult3 = runGradle(projectDirectoryPath, RUN_PNPM_TASK_NAME); + + assertTaskOutcomes(runPnpmTaskResult3, UP_TO_DATE, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS, RUN_PNPM_TASK_NAME, + SUCCESS); + + final BuildResult runPnpmTaskResult4 = runGradle(projectDirectoryPath, RUN_PNPM_TASK_NAME); + + assertTaskOutcomes(runPnpmTaskResult4, UP_TO_DATE, UP_TO_DATE, UP_TO_DATE, UP_TO_DATE, SUCCESS, + RUN_PNPM_TASK_NAME, SUCCESS); + + Files.deleteIfExists(packageJsonDirectoryPath.resolve("package-lock.json")); + Files.copy(getResourcePath("package-yarn.json"), packageJsonDirectoryPath.resolve("package.json"), + StandardCopyOption.REPLACE_EXISTING); + frontendMapBuilder.verboseModeEnabled(false); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), additionalContent); + + final BuildResult runNodeTaskResult4 = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); + + assertTaskOutcomes(runNodeTaskResult4, UP_TO_DATE, RUN_NODE_TASK_NAME, SUCCESS); + + final BuildResult runCorepackTaskResult3 = runGradle(projectDirectoryPath, RUN_COREPACK_TASK_NAME); + + assertTaskOutcomes(runCorepackTaskResult3, UP_TO_DATE, UP_TO_DATE, RUN_COREPACK_TASK_NAME, SUCCESS); + + final BuildResult runYarnTaskResult1 = runGradle(projectDirectoryPath, RUN_YARN_TASK_NAME); + + assertTaskOutcomes(runYarnTaskResult1, UP_TO_DATE, UP_TO_DATE, SUCCESS, SUCCESS, SUCCESS, RUN_YARN_TASK_NAME, + SUCCESS); + + final BuildResult runYarnTaskResult2 = runGradle(projectDirectoryPath, RUN_YARN_TASK_NAME); + + assertTaskOutcomes(runYarnTaskResult2, UP_TO_DATE, UP_TO_DATE, UP_TO_DATE, UP_TO_DATE, SUCCESS, + RUN_YARN_TASK_NAME, SUCCESS); + } +} diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithProvidedDistributionsFuncTest.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithProvidedDistributionsFuncTest.java similarity index 56% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithProvidedDistributionsFuncTest.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithProvidedDistributionsFuncTest.java index 0279c4c6..416e720f 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithProvidedDistributionsFuncTest.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskTypesWithProvidedDistributionsFuncTest.java @@ -1,9 +1,17 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME; +import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskFailed; import static org.siouan.frontendgradleplugin.test.GradleBuildAssertions.assertTaskOutcomes; import static org.siouan.frontendgradleplugin.test.GradleBuildFiles.createBuildFile; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradle; import static org.siouan.frontendgradleplugin.test.GradleHelper.runGradleAndExpectFailure; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.FAILED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.IGNORED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SKIPPED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.SUCCESS; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.UP_TO_DATE; import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import static org.siouan.frontendgradleplugin.test.TaskTypes.buildCorepackTaskDefinition; import static org.siouan.frontendgradleplugin.test.TaskTypes.buildNodeTaskDefinition; @@ -19,9 +27,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.test.FrontendMapBuilder; -import org.siouan.frontendgradleplugin.test.PluginTaskOutcome; /** * Functional tests to verify task types {@link RunNode}, {@link RunNpm}, {@link RunYarn} in a Gradle build, with a @@ -59,13 +65,25 @@ void should_fail_running_custom_corepack_task_when_node_executable_does_not_exis final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() .nodeDistributionProvided(true) .nodeInstallDirectory(getResourcePath("node-dist-without-node")); - final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, "disable"); + final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, "disable"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runCorepackTaskDefinition); final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_COREPACK_TASK_NAME); - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, RUN_COREPACK_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcomes(result, SKIPPED, RUN_COREPACK_TASK_NAME, FAILED); + } + + @Test + void should_fail_running_custom_corepack_task_when_script_is_undefined() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(getResourcePath("node-dist-provided")); + final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, null); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runCorepackTaskDefinition); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_COREPACK_TASK_NAME); + + assertTaskOutcomes(result, SKIPPED, RUN_COREPACK_TASK_NAME, FAILED); } @Test @@ -79,7 +97,20 @@ void should_fail_running_custom_node_task_when_node_executable_does_not_exist() final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_NODE_TASK_NAME); - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, RUN_NODE_TASK_NAME, PluginTaskOutcome.FAILED); + assertTaskOutcomes(result, SKIPPED, RUN_NODE_TASK_NAME, FAILED); + } + + @Test + void should_fail_running_custom_node_task_when_script_is_undefined() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(getResourcePath("node-dist-provided")); + final String runNodeTaskDefinition = buildNodeTaskDefinition(RUN_NODE_TASK_NAME, null); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runNodeTaskDefinition); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_NODE_TASK_NAME); + + assertTaskFailed(result, RUN_NODE_TASK_NAME); } @Test @@ -88,14 +119,26 @@ void should_fail_running_custom_npm_task_when_node_executable_does_not_exist() t final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() .nodeDistributionProvided(true) .nodeInstallDirectory(getResourcePath("node-dist-without-node")); - final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME, "run npm-script"); + final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, INSTALL_PACKAGE_MANAGER_TASK_NAME, + "run npm-script"); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runNpmTaskDefinition); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_NPM_TASK_NAME); + + assertTaskOutcomes(result, SKIPPED, SKIPPED, SUCCESS, FAILED, RUN_NPM_TASK_NAME, IGNORED); + } + + @Test + void should_fail_running_custom_npm_task_when_script_is_undefined() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(getResourcePath("node-dist-provided")); + final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, null); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runNpmTaskDefinition); final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_NPM_TASK_NAME); - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.FAILED, - RUN_NPM_TASK_NAME, PluginTaskOutcome.IGNORED); + assertTaskFailed(result, RUN_NPM_TASK_NAME); } @Test @@ -105,13 +148,25 @@ void should_fail_running_custom_pnpm_task_when_node_executable_does_not_exist() .nodeDistributionProvided(true) .nodeInstallDirectory(getResourcePath("node-dist-without-node")); final String runNpmTaskDefinition = buildPnpmTaskDefinition(RUN_PNPM_TASK_NAME, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME, "run pnpm-script"); + INSTALL_PACKAGE_MANAGER_TASK_NAME, "run pnpm-script"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runNpmTaskDefinition); final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_PNPM_TASK_NAME); - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.FAILED, - RUN_PNPM_TASK_NAME, PluginTaskOutcome.IGNORED); + assertTaskOutcomes(result, SKIPPED, SKIPPED, SUCCESS, FAILED, RUN_PNPM_TASK_NAME, IGNORED); + } + + @Test + void should_fail_running_custom_pnpm_task_when_script_is_undefined() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(getResourcePath("node-dist-provided")); + final String runPnpmTaskDefinition = buildPnpmTaskDefinition(RUN_PNPM_TASK_NAME, null); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runPnpmTaskDefinition); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_PNPM_TASK_NAME); + + assertTaskFailed(result, RUN_PNPM_TASK_NAME); } @Test @@ -121,13 +176,25 @@ void should_fail_running_custom_yarn_task_when_node_executable_does_not_exist() .nodeDistributionProvided(true) .nodeInstallDirectory(getResourcePath("node-dist-without-node")); final String runNpmTaskDefinition = buildYarnTaskDefinition(RUN_YARN_TASK_NAME, - FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME, "run yarn-script"); + INSTALL_PACKAGE_MANAGER_TASK_NAME, "run yarn-script"); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), runNpmTaskDefinition); final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_YARN_TASK_NAME); - assertTaskOutcomes(result, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS, PluginTaskOutcome.FAILED, - RUN_YARN_TASK_NAME, PluginTaskOutcome.IGNORED); + assertTaskOutcomes(result, SKIPPED, SKIPPED, SUCCESS, FAILED, RUN_YARN_TASK_NAME, IGNORED); + } + + @Test + void should_fail_running_custom_yarn_task_when_script_is_undefined() throws IOException { + final FrontendMapBuilder frontendMapBuilder = new FrontendMapBuilder() + .nodeDistributionProvided(true) + .nodeInstallDirectory(getResourcePath("node-dist-provided")); + final String customTaskDefinition = buildYarnTaskDefinition(RUN_YARN_TASK_NAME, null); + createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), customTaskDefinition); + + final BuildResult result = runGradleAndExpectFailure(projectDirectoryPath, RUN_YARN_TASK_NAME); + + assertTaskFailed(result, RUN_YARN_TASK_NAME); } @Test @@ -138,40 +205,37 @@ void should_run_custom_tasks() throws IOException { .nodeInstallDirectory(getResourcePath("node-dist-provided")); final String runNodeTaskDefinition = buildNodeTaskDefinition(RUN_NODE_TASK_NAME, temporaryScriptPath.toString().replace("\\", "\\\\")); - final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, "disable"); - final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, - FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, "run npm-script"); - final String runPnpmTaskDefinition = buildPnpmTaskDefinition(RUN_PNPM_TASK_NAME, - FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, "run pnpm-script"); - final String runYarnTaskDefinition = buildYarnTaskDefinition(RUN_YARN_TASK_NAME, - FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, "run yarn-script"); + final String runCorepackTaskDefinition = buildCorepackTaskDefinition(RUN_COREPACK_TASK_NAME, "disable"); + final String runNpmTaskDefinition = buildNpmTaskDefinition(RUN_NPM_TASK_NAME, INSTALL_FRONTEND_TASK_NAME, + "run npm-script"); + final String runPnpmTaskDefinition = buildPnpmTaskDefinition(RUN_PNPM_TASK_NAME, INSTALL_FRONTEND_TASK_NAME, + "run pnpm-script"); + final String runYarnTaskDefinition = buildYarnTaskDefinition(RUN_YARN_TASK_NAME, INSTALL_FRONTEND_TASK_NAME, + "run yarn-script"); final String additionalContent = String.join("\n", runNodeTaskDefinition, runCorepackTaskDefinition, runNpmTaskDefinition, runPnpmTaskDefinition, runYarnTaskDefinition); createBuildFile(projectDirectoryPath, frontendMapBuilder.toMap(), additionalContent); final BuildResult nodeTaskResult = runGradle(projectDirectoryPath, RUN_NODE_TASK_NAME); - assertTaskOutcomes(nodeTaskResult, PluginTaskOutcome.SKIPPED, RUN_NODE_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(nodeTaskResult, SKIPPED, RUN_NODE_TASK_NAME, SUCCESS); final BuildResult corepackTaskResult = runGradle(projectDirectoryPath, RUN_COREPACK_TASK_NAME); - assertTaskOutcomes(corepackTaskResult, PluginTaskOutcome.SKIPPED, RUN_COREPACK_TASK_NAME, - PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(corepackTaskResult, SKIPPED, SKIPPED, RUN_COREPACK_TASK_NAME, SUCCESS); final BuildResult npmTaskResult = runGradle(projectDirectoryPath, RUN_NPM_TASK_NAME); - assertTaskOutcomes(npmTaskResult, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.SUCCESS, - PluginTaskOutcome.SUCCESS, PluginTaskOutcome.SUCCESS, RUN_NPM_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(npmTaskResult, SKIPPED, SKIPPED, SUCCESS, SUCCESS, SUCCESS, RUN_NPM_TASK_NAME, SUCCESS); final BuildResult pnpmTaskResult = runGradle(projectDirectoryPath, RUN_PNPM_TASK_NAME); - assertTaskOutcomes(pnpmTaskResult, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, RUN_PNPM_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(pnpmTaskResult, SKIPPED, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, RUN_PNPM_TASK_NAME, + SUCCESS); final BuildResult yarnTaskResult = runGradle(projectDirectoryPath, RUN_YARN_TASK_NAME); - assertTaskOutcomes(yarnTaskResult, PluginTaskOutcome.SKIPPED, PluginTaskOutcome.UP_TO_DATE, - PluginTaskOutcome.UP_TO_DATE, PluginTaskOutcome.SUCCESS, RUN_YARN_TASK_NAME, PluginTaskOutcome.SUCCESS); + assertTaskOutcomes(yarnTaskResult, SKIPPED, SKIPPED, UP_TO_DATE, UP_TO_DATE, SUCCESS, RUN_YARN_TASK_NAME, + SUCCESS); } } diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/FrontendMapBuilder.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/FrontendMapBuilder.java similarity index 95% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/FrontendMapBuilder.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/FrontendMapBuilder.java index 76ba60ed..92d00f9c 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/FrontendMapBuilder.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/FrontendMapBuilder.java @@ -24,6 +24,8 @@ public final class FrontendMapBuilder { private Path nodeInstallDirectory; + private String corepackVersion; + private String installScript; private String cleanScript; @@ -88,6 +90,11 @@ public FrontendMapBuilder nodeInstallDirectory(final Path nodeInstallDirectory) return this; } + public FrontendMapBuilder corepackVersion(final String corepackVersion) { + this.corepackVersion = corepackVersion; + return this; + } + public FrontendMapBuilder installScript(final String installScript) { this.installScript = installScript; return this; @@ -166,6 +173,9 @@ public Map toMap() { if (nodeInstallDirectory != null) { properties.put("nodeInstallDirectory", nodeInstallDirectory); } + if (corepackVersion != null) { + properties.put("corepackVersion", corepackVersion); + } if (installScript != null) { properties.put("installScript", installScript); } diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleBuildAssertions.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleBuildAssertions.java similarity index 55% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleBuildAssertions.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleBuildAssertions.java index c8cf749e..bcc8e03f 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleBuildAssertions.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleBuildAssertions.java @@ -1,6 +1,21 @@ package org.siouan.frontendgradleplugin.test; import static org.assertj.core.api.Assertions.assertThat; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.ASSEMBLE_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.CHECK_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.CLEAN_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_COREPACK_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_NODE_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.PUBLISH_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.FAILED; +import static org.siouan.frontendgradleplugin.test.PluginTaskOutcome.IGNORED; import java.util.HashMap; import java.util.List; @@ -11,144 +26,158 @@ import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.BuildTask; import org.gradle.testkit.runner.TaskOutcome; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; /** * Class providing assertions for Gradle builds. */ public final class GradleBuildAssertions { - private static final List TASK_NAMES = List.of(FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, FrontendGradlePlugin.CLEAN_TASK_NAME, - FrontendGradlePlugin.ASSEMBLE_TASK_NAME, FrontendGradlePlugin.CHECK_TASK_NAME, - FrontendGradlePlugin.PUBLISH_TASK_NAME, FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME, - FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME, FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME, - FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME); + private static final List TASK_NAMES = List.of(INSTALL_NODE_TASK_NAME, INSTALL_COREPACK_TASK_NAME, + RESOLVE_PACKAGE_MANAGER_TASK_NAME, INSTALL_PACKAGE_MANAGER_TASK_NAME, INSTALL_FRONTEND_TASK_NAME, + CLEAN_TASK_NAME, ASSEMBLE_TASK_NAME, CHECK_TASK_NAME, PUBLISH_TASK_NAME, GRADLE_CLEAN_TASK_NAME, + GRADLE_ASSEMBLE_TASK_NAME, GRADLE_CHECK_TASK_NAME, GRADLE_PUBLISH_TASK_NAME); private GradleBuildAssertions() { } public static void assertAssembleTaskOutcomes(final BuildResult result, - final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome installCorepackTaskOutcome, + final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final PluginTaskOutcome assembleTaskOutcome, final PluginTaskOutcome gradleAssembleTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, assembleTaskOutcome, null, null, null, - gradleAssembleTaskOutcome, null, null, null, null); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, + assembleTaskOutcome, null, null, null, gradleAssembleTaskOutcome, null, null, null, null); } public static void assertCheckTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final PluginTaskOutcome checkTaskOutcome, final PluginTaskOutcome gradleCheckTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, checkTaskOutcome, null, null, - null, gradleCheckTaskOutcome, null, null, null); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, + checkTaskOutcome, null, null, null, gradleCheckTaskOutcome, null, null, null); } public static void assertCleanTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final PluginTaskOutcome cleanTaskOutcome, final PluginTaskOutcome gradleCleanTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, cleanTaskOutcome, null, null, null, - gradleCleanTaskOutcome, null, null, null, null, null); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, + cleanTaskOutcome, null, null, null, gradleCleanTaskOutcome, null, null, null, null, null); } public static void assertPublishTaskOutcomes(final BuildResult result, - final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome installCorepackTaskOutcome, + final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final PluginTaskOutcome publishTaskOutcome, final PluginTaskOutcome gradlePublishTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, null, publishTaskOutcome, null, - null, null, gradlePublishTaskOutcome, null, null); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, + null, publishTaskOutcome, null, null, null, gradlePublishTaskOutcome, null, null); } public static void assertTaskFailed(final BuildResult result, final String taskName) { - assertTaskOutcomes(result, null, null, null, null, null, null, null, null, null, null, null, null, null, - taskName, PluginTaskOutcome.FAILED); + assertTaskOutcomes(result, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + taskName, FAILED); } public static void assertTaskOutcome(final BuildResult result, final String taskName, final PluginTaskOutcome taskOutcome) { - assertTaskOutcomes(result, null, null, null, null, null, null, null, null, null, null, null, null, null, + assertTaskOutcomes(result, null, null, null, null, null, null, null, null, null, null, null, null, null, null, taskName, taskOutcome); } public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, final String taskName, final PluginTaskOutcome taskOutcome) { assertTaskOutcomes(result, null, installNodeTaskOutcome, null, null, null, null, null, null, null, null, null, - null, null, taskName, taskOutcome); + null, null, null, taskName, taskOutcome); } public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, null, null, null, + final PluginTaskOutcome installCorepackTaskOutcome, final String taskName, + final PluginTaskOutcome taskOutcome) { + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, null, null, null, null, + null, null, null, null, null, null, null, taskName, taskOutcome); + } + + public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome) { + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, null, null, null, null, null, null, null, null, null, null, null, null, null); } public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome) { + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, null, null, null, null, null, null, null, null, null, null, null, null); + } + + public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, null, null, null, null, null, null, null, null, null, null, null); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, null, null, null, null, null, null, + null, null, null, null, null); } public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final String taskName, final PluginTaskOutcome taskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, null, null, null, null, null, null, null, null, null, taskName, - taskOutcome); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, null, null, null, null, null, null, + null, null, null, taskName, taskOutcome); } public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, null, null, null, null, null, - null, null, null); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, + null, null, null, null, null, null, null, null); } public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final String taskName, final PluginTaskOutcome taskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, null, null, null, null, null, - null, taskName, taskOutcome); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, null, null, + null, null, null, null, null, null, taskName, taskOutcome); } public static void assertTaskOutcomes(final BuildResult result, final PluginTaskOutcome installNodeTaskOutcome, - final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installCorepackTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final PluginTaskOutcome cleanTaskOutcome, final PluginTaskOutcome assembleTaskOutcome, final PluginTaskOutcome checkTaskOutcome, final PluginTaskOutcome publishTaskOutcome, final PluginTaskOutcome gradleCleanTaskOutcome, final PluginTaskOutcome gradleAssembleTaskOutcome, final PluginTaskOutcome gradleCheckTaskOutcome, final PluginTaskOutcome gradlePublishTaskOutcome) { - assertTaskOutcomes(result, null, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, cleanTaskOutcome, assembleTaskOutcome, - checkTaskOutcome, publishTaskOutcome, gradleCleanTaskOutcome, gradleAssembleTaskOutcome, - gradleCheckTaskOutcome, gradlePublishTaskOutcome, null, null); + assertTaskOutcomes(result, null, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, + cleanTaskOutcome, assembleTaskOutcome, checkTaskOutcome, publishTaskOutcome, gradleCleanTaskOutcome, + gradleAssembleTaskOutcome, gradleCheckTaskOutcome, gradlePublishTaskOutcome, null, null); } public static void assertTaskOutcomes(final BuildResult result, final String projectName, - final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome installCorepackTaskOutcome, + final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final PluginTaskOutcome cleanTaskOutcome, final PluginTaskOutcome assembleTaskOutcome, final PluginTaskOutcome checkTaskOutcome, final PluginTaskOutcome publishTaskOutcome, final PluginTaskOutcome gradleCleanTaskOutcome, final PluginTaskOutcome gradleAssembleTaskOutcome, final PluginTaskOutcome gradleCheckTaskOutcome, final PluginTaskOutcome gradlePublishTaskOutcome) { - assertTaskOutcomes(result, projectName, installNodeTaskOutcome, resolvePackageManagerTaskOutcome, - installPackageManagerTaskOutcome, installFrontendTaskOutcome, cleanTaskOutcome, assembleTaskOutcome, - checkTaskOutcome, publishTaskOutcome, gradleCleanTaskOutcome, gradleAssembleTaskOutcome, - gradleCheckTaskOutcome, gradlePublishTaskOutcome, null, null); + assertTaskOutcomes(result, projectName, installNodeTaskOutcome, installCorepackTaskOutcome, + resolvePackageManagerTaskOutcome, installPackageManagerTaskOutcome, installFrontendTaskOutcome, + cleanTaskOutcome, assembleTaskOutcome, checkTaskOutcome, publishTaskOutcome, gradleCleanTaskOutcome, + gradleAssembleTaskOutcome, gradleCheckTaskOutcome, gradlePublishTaskOutcome, null, null); } public static void assertTaskOutcomes(final BuildResult result, final String projectName, - final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome resolvePackageManagerTaskOutcome, + final PluginTaskOutcome installNodeTaskOutcome, final PluginTaskOutcome installCorepackTaskOutcome, + final PluginTaskOutcome resolvePackageManagerTaskOutcome, final PluginTaskOutcome installPackageManagerTaskOutcome, final PluginTaskOutcome installFrontendTaskOutcome, final PluginTaskOutcome cleanTaskOutcome, final PluginTaskOutcome assembleTaskOutcome, final PluginTaskOutcome checkTaskOutcome, final PluginTaskOutcome publishTaskOutcome, @@ -156,27 +185,26 @@ public static void assertTaskOutcomes(final BuildResult result, final String pro final PluginTaskOutcome gradleCheckTaskOutcome, final PluginTaskOutcome gradlePublishTaskOutcome, final String taskName, final PluginTaskOutcome taskOutcome) { final Map outcomeByTaskNames = new HashMap<>(); - outcomeByTaskNames.put(FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, installNodeTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - resolvePackageManagerTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME, - installPackageManagerTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, installFrontendTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.CLEAN_TASK_NAME, cleanTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.ASSEMBLE_TASK_NAME, assembleTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.CHECK_TASK_NAME, checkTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.PUBLISH_TASK_NAME, publishTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.GRADLE_CLEAN_TASK_NAME, gradleCleanTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.GRADLE_ASSEMBLE_TASK_NAME, gradleAssembleTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.GRADLE_CHECK_TASK_NAME, gradleCheckTaskOutcome); - outcomeByTaskNames.put(FrontendGradlePlugin.GRADLE_PUBLISH_TASK_NAME, gradlePublishTaskOutcome); + outcomeByTaskNames.put(INSTALL_NODE_TASK_NAME, installNodeTaskOutcome); + outcomeByTaskNames.put(INSTALL_COREPACK_TASK_NAME, installCorepackTaskOutcome); + outcomeByTaskNames.put(RESOLVE_PACKAGE_MANAGER_TASK_NAME, resolvePackageManagerTaskOutcome); + outcomeByTaskNames.put(INSTALL_PACKAGE_MANAGER_TASK_NAME, installPackageManagerTaskOutcome); + outcomeByTaskNames.put(INSTALL_FRONTEND_TASK_NAME, installFrontendTaskOutcome); + outcomeByTaskNames.put(CLEAN_TASK_NAME, cleanTaskOutcome); + outcomeByTaskNames.put(ASSEMBLE_TASK_NAME, assembleTaskOutcome); + outcomeByTaskNames.put(CHECK_TASK_NAME, checkTaskOutcome); + outcomeByTaskNames.put(PUBLISH_TASK_NAME, publishTaskOutcome); + outcomeByTaskNames.put(GRADLE_CLEAN_TASK_NAME, gradleCleanTaskOutcome); + outcomeByTaskNames.put(GRADLE_ASSEMBLE_TASK_NAME, gradleAssembleTaskOutcome); + outcomeByTaskNames.put(GRADLE_CHECK_TASK_NAME, gradleCheckTaskOutcome); + outcomeByTaskNames.put(GRADLE_PUBLISH_TASK_NAME, gradlePublishTaskOutcome); if (taskName != null) { outcomeByTaskNames.put(taskName, taskOutcome); } Stream.concat(TASK_NAMES.stream(), Stream.ofNullable(taskName)).forEach(aTaskName -> { final PluginTaskOutcome anOutcome = outcomeByTaskNames.get(aTaskName); if (anOutcome != null) { - if (anOutcome == PluginTaskOutcome.IGNORED) { + if (anOutcome == IGNORED) { assertTaskIgnored(result, aTaskName); } else { assertTaskOutcome(result, projectName, aTaskName, anOutcome.getNativeOutcome()); diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleBuildFiles.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleBuildFiles.java similarity index 100% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleBuildFiles.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleBuildFiles.java diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleHelper.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleHelper.java similarity index 98% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleHelper.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleHelper.java index fa26f9fb..6599d781 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleHelper.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleHelper.java @@ -16,7 +16,7 @@ */ public final class GradleHelper { - private static final String MINIMAL_GRADLE_VERSION = "6.2"; + private static final String MINIMAL_GRADLE_VERSION = "8.5"; private GradleHelper() { } diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleSettingsFiles.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleSettingsFiles.java similarity index 100% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/GradleSettingsFiles.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/GradleSettingsFiles.java diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/PluginTaskOutcome.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/PluginTaskOutcome.java similarity index 100% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/PluginTaskOutcome.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/PluginTaskOutcome.java diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/ServerConfigurator.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/ServerConfigurator.java similarity index 98% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/ServerConfigurator.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/ServerConfigurator.java index 72fe4fef..4b18084a 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/ServerConfigurator.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/ServerConfigurator.java @@ -52,7 +52,7 @@ public void configure() throws IOException { mappingBuilder = get(urlPathMatching("^.*/node-v[^/]+$")); withAuth(mappingBuilder); server.stubFor(mappingBuilder.willReturn( - aResponse().withBody(Files.readAllBytes(getResourcePath("node-v18.17.1.zip"))))); + aResponse().withBody(Files.readAllBytes(getResourcePath("node-v20.14.0.zip"))))); mappingBuilder = get(urlPathMatching("^.*/SHASUMS256.txt$")); withAuth(mappingBuilder); diff --git a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/TaskTypes.java b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/TaskTypes.java similarity index 73% rename from plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/TaskTypes.java rename to plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/TaskTypes.java index fbc386e4..913d5344 100644 --- a/plugin/src/intTest/java/org/siouan/frontendgradleplugin/test/TaskTypes.java +++ b/plugin/src/integrationTest/java/org/siouan/frontendgradleplugin/test/TaskTypes.java @@ -1,12 +1,15 @@ package org.siouan.frontendgradleplugin.test; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_COREPACK_TASK_NAME; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.INSTALL_NODE_TASK_NAME; + import java.io.IOException; import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Map; import java.util.Set; -import org.siouan.frontendgradleplugin.FrontendGradlePlugin; import org.siouan.frontendgradleplugin.infrastructure.gradle.RunCorepack; import org.siouan.frontendgradleplugin.infrastructure.gradle.RunNode; import org.siouan.frontendgradleplugin.infrastructure.gradle.RunNpm; @@ -22,22 +25,17 @@ private TaskTypes() { } public static String buildCorepackTaskDefinition(final String taskName, final String script) { - return buildTaskDefinition(taskName, RunCorepack.class, Set.of(), script); - } - - public static String buildCorepackTaskDefinition(final String taskName, final String dependsOnTaskName, - final String script) { - return buildTaskDefinition(taskName, RunCorepack.class, Set.of(dependsOnTaskName), script); + return buildTaskDefinition(taskName, RunCorepack.class, Set.of(INSTALL_COREPACK_TASK_NAME), script); } public static String buildNodeTaskDefinition(final String taskName, final String script) { - return buildNodeTaskDefinition(taskName, FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, script); + return buildTaskDefinition(taskName, RunNode.class, Set.of(INSTALL_NODE_TASK_NAME), script); } - public static String buildNodeTaskDefinition(final String taskName, final String dependsOnTaskName, - final String script) { - return buildTaskDefinition(taskName, RunNode.class, - (dependsOnTaskName == null) ? Set.of() : Set.of(dependsOnTaskName), script); + public static String buildNodeTaskDefinition(final String taskName, final String script, + final Map environmentVariables) { + return buildTaskDefinition(taskName, RunNode.class, Set.of(INSTALL_NODE_TASK_NAME), script, + environmentVariables); } public static String buildNpmTaskDefinition(final String taskName, final String script) { @@ -82,15 +80,20 @@ public static String buildYarnTaskDefinition(final String taskName, final Set taskTypeClass, final Set dependsOnTaskNames, final String script) { + return buildTaskDefinition(taskName, taskTypeClass, dependsOnTaskNames, script, Map.of()); + } + + private static String buildTaskDefinition(final String taskName, final Class taskTypeClass, + final Set dependsOnTaskNames, final String script, final Map environmentVariables) { final StringBuilder definition = new StringBuilder(); definition.append("tasks.register('"); definition.append(taskName); @@ -107,6 +110,14 @@ private static String buildTaskDefinition(final String taskName, final Class definition.append(script); definition.append("'\n"); } + if (!environmentVariables.isEmpty()) { + environmentVariables.forEach((variableName, variableValue) -> definition + .append("environmentVariables.put(\"") + .append(variableName) + .append("\", \"") + .append(variableValue) + .append("\")\n")); + } definition.append("}\n"); return definition.toString(); } diff --git a/plugin/src/intTest/resources/SHASUMS256.txt b/plugin/src/integrationTest/resources/SHASUMS256.txt similarity index 88% rename from plugin/src/intTest/resources/SHASUMS256.txt rename to plugin/src/integrationTest/resources/SHASUMS256.txt index 36c74754..7de72267 100644 --- a/plugin/src/intTest/resources/SHASUMS256.txt +++ b/plugin/src/integrationTest/resources/SHASUMS256.txt @@ -1,2 +1,2 @@ 8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85 node-v10.15.1.txt -c5b1eab3577b2b060caeedfb041098c9febddd6168164ace02845e6151710f30 node-v18.17.1.zip +c5b1eab3577b2b060caeedfb041098c9febddd6168164ace02845e6151710f30 node-v20.14.0.zip diff --git a/plugin/src/intTest/resources/node-dist-provided/bin/corepack b/plugin/src/integrationTest/resources/node-dist-provided/bin/corepack similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/bin/corepack rename to plugin/src/integrationTest/resources/node-dist-provided/bin/corepack diff --git a/plugin/src/intTest/resources/node-dist-provided/bin/node b/plugin/src/integrationTest/resources/node-dist-provided/bin/node similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/bin/node rename to plugin/src/integrationTest/resources/node-dist-provided/bin/node diff --git a/plugin/src/intTest/resources/node-dist-provided/bin/npm b/plugin/src/integrationTest/resources/node-dist-provided/bin/npm similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/bin/npm rename to plugin/src/integrationTest/resources/node-dist-provided/bin/npm diff --git a/plugin/src/intTest/resources/node-dist-provided/bin/npx b/plugin/src/integrationTest/resources/node-dist-provided/bin/npx similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/bin/npx rename to plugin/src/integrationTest/resources/node-dist-provided/bin/npx diff --git a/plugin/src/intTest/resources/node-dist-provided/bin/pnpm b/plugin/src/integrationTest/resources/node-dist-provided/bin/pnpm similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/bin/pnpm rename to plugin/src/integrationTest/resources/node-dist-provided/bin/pnpm diff --git a/plugin/src/intTest/resources/node-dist-provided/bin/pnpx b/plugin/src/integrationTest/resources/node-dist-provided/bin/pnpx similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/bin/pnpx rename to plugin/src/integrationTest/resources/node-dist-provided/bin/pnpx diff --git a/plugin/src/intTest/resources/node-dist-provided/bin/yarn b/plugin/src/integrationTest/resources/node-dist-provided/bin/yarn similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/bin/yarn rename to plugin/src/integrationTest/resources/node-dist-provided/bin/yarn diff --git a/plugin/src/intTest/resources/node-dist-provided/corepack.cmd b/plugin/src/integrationTest/resources/node-dist-provided/corepack.cmd similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/corepack.cmd rename to plugin/src/integrationTest/resources/node-dist-provided/corepack.cmd diff --git a/plugin/src/intTest/resources/node-dist-provided/node.exe b/plugin/src/integrationTest/resources/node-dist-provided/node.exe similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/node.exe rename to plugin/src/integrationTest/resources/node-dist-provided/node.exe diff --git a/plugin/src/intTest/resources/node-dist-provided/npm.cmd b/plugin/src/integrationTest/resources/node-dist-provided/npm.cmd similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/npm.cmd rename to plugin/src/integrationTest/resources/node-dist-provided/npm.cmd diff --git a/plugin/src/intTest/resources/node-dist-provided/npx.cmd b/plugin/src/integrationTest/resources/node-dist-provided/npx.cmd similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/npx.cmd rename to plugin/src/integrationTest/resources/node-dist-provided/npx.cmd diff --git a/plugin/src/intTest/resources/node-dist-provided/pnpm.cmd b/plugin/src/integrationTest/resources/node-dist-provided/pnpm.cmd similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/pnpm.cmd rename to plugin/src/integrationTest/resources/node-dist-provided/pnpm.cmd diff --git a/plugin/src/intTest/resources/node-dist-provided/pnpx.cmd b/plugin/src/integrationTest/resources/node-dist-provided/pnpx.cmd similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/pnpx.cmd rename to plugin/src/integrationTest/resources/node-dist-provided/pnpx.cmd diff --git a/plugin/src/intTest/resources/node-dist-provided/yarn.cmd b/plugin/src/integrationTest/resources/node-dist-provided/yarn.cmd similarity index 100% rename from plugin/src/intTest/resources/node-dist-provided/yarn.cmd rename to plugin/src/integrationTest/resources/node-dist-provided/yarn.cmd diff --git a/plugin/src/intTest/resources/node-dist-without-node/bin/corepack b/plugin/src/integrationTest/resources/node-dist-without-node/bin/corepack similarity index 95% rename from plugin/src/intTest/resources/node-dist-without-node/bin/corepack rename to plugin/src/integrationTest/resources/node-dist-without-node/bin/corepack index 41de4b4e..908ba841 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/bin/corepack +++ b/plugin/src/integrationTest/resources/node-dist-without-node/bin/corepack @@ -1,2 +1 @@ #!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/bin/npm b/plugin/src/integrationTest/resources/node-dist-without-node/bin/npm similarity index 95% rename from plugin/src/intTest/resources/node-dist-without-corepack/bin/npm rename to plugin/src/integrationTest/resources/node-dist-without-node/bin/npm index 41de4b4e..908ba841 100644 --- a/plugin/src/intTest/resources/node-dist-without-corepack/bin/npm +++ b/plugin/src/integrationTest/resources/node-dist-without-node/bin/npm @@ -1,2 +1 @@ #!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-node/bin/npx b/plugin/src/integrationTest/resources/node-dist-without-node/bin/npx similarity index 95% rename from plugin/src/intTest/resources/node-dist-without-node/bin/npx rename to plugin/src/integrationTest/resources/node-dist-without-node/bin/npx index 41de4b4e..908ba841 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/bin/npx +++ b/plugin/src/integrationTest/resources/node-dist-without-node/bin/npx @@ -1,2 +1 @@ #!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-node/bin/pnpm b/plugin/src/integrationTest/resources/node-dist-without-node/bin/pnpm similarity index 95% rename from plugin/src/intTest/resources/node-dist-without-node/bin/pnpm rename to plugin/src/integrationTest/resources/node-dist-without-node/bin/pnpm index 41de4b4e..908ba841 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/bin/pnpm +++ b/plugin/src/integrationTest/resources/node-dist-without-node/bin/pnpm @@ -1,2 +1 @@ #!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-node/bin/pnpx b/plugin/src/integrationTest/resources/node-dist-without-node/bin/pnpx similarity index 95% rename from plugin/src/intTest/resources/node-dist-without-node/bin/pnpx rename to plugin/src/integrationTest/resources/node-dist-without-node/bin/pnpx index 41de4b4e..908ba841 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/bin/pnpx +++ b/plugin/src/integrationTest/resources/node-dist-without-node/bin/pnpx @@ -1,2 +1 @@ #!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/bin/yarn b/plugin/src/integrationTest/resources/node-dist-without-node/bin/yarn similarity index 95% rename from plugin/src/intTest/resources/node-dist-without-corepack/bin/yarn rename to plugin/src/integrationTest/resources/node-dist-without-node/bin/yarn index 41de4b4e..908ba841 100644 --- a/plugin/src/intTest/resources/node-dist-without-corepack/bin/yarn +++ b/plugin/src/integrationTest/resources/node-dist-without-node/bin/yarn @@ -1,2 +1 @@ #!/usr/bin/env node - diff --git a/plugin/src/intTest/resources/node-dist-without-node/corepack.cmd b/plugin/src/integrationTest/resources/node-dist-without-node/corepack.cmd similarity index 99% rename from plugin/src/intTest/resources/node-dist-without-node/corepack.cmd rename to plugin/src/integrationTest/resources/node-dist-without-node/corepack.cmd index 1c835f1b..2c540e6c 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/corepack.cmd +++ b/plugin/src/integrationTest/resources/node-dist-without-node/corepack.cmd @@ -5,4 +5,3 @@ ECHO %~dp0 %* ) ELSE ( node %* ) - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/npm.cmd b/plugin/src/integrationTest/resources/node-dist-without-node/npm.cmd similarity index 99% rename from plugin/src/intTest/resources/node-dist-without-corepack/npm.cmd rename to plugin/src/integrationTest/resources/node-dist-without-node/npm.cmd index 1c835f1b..2c540e6c 100644 --- a/plugin/src/intTest/resources/node-dist-without-corepack/npm.cmd +++ b/plugin/src/integrationTest/resources/node-dist-without-node/npm.cmd @@ -5,4 +5,3 @@ ECHO %~dp0 %* ) ELSE ( node %* ) - diff --git a/plugin/src/intTest/resources/node-dist-without-node/npx.cmd b/plugin/src/integrationTest/resources/node-dist-without-node/npx.cmd similarity index 99% rename from plugin/src/intTest/resources/node-dist-without-node/npx.cmd rename to plugin/src/integrationTest/resources/node-dist-without-node/npx.cmd index 1c835f1b..2c540e6c 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/npx.cmd +++ b/plugin/src/integrationTest/resources/node-dist-without-node/npx.cmd @@ -5,4 +5,3 @@ ECHO %~dp0 %* ) ELSE ( node %* ) - diff --git a/plugin/src/intTest/resources/node-dist-without-node/pnpm.cmd b/plugin/src/integrationTest/resources/node-dist-without-node/pnpm.cmd similarity index 99% rename from plugin/src/intTest/resources/node-dist-without-node/pnpm.cmd rename to plugin/src/integrationTest/resources/node-dist-without-node/pnpm.cmd index 1c835f1b..2c540e6c 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/pnpm.cmd +++ b/plugin/src/integrationTest/resources/node-dist-without-node/pnpm.cmd @@ -5,4 +5,3 @@ ECHO %~dp0 %* ) ELSE ( node %* ) - diff --git a/plugin/src/intTest/resources/node-dist-without-node/pnpx.cmd b/plugin/src/integrationTest/resources/node-dist-without-node/pnpx.cmd similarity index 99% rename from plugin/src/intTest/resources/node-dist-without-node/pnpx.cmd rename to plugin/src/integrationTest/resources/node-dist-without-node/pnpx.cmd index 1c835f1b..2c540e6c 100644 --- a/plugin/src/intTest/resources/node-dist-without-node/pnpx.cmd +++ b/plugin/src/integrationTest/resources/node-dist-without-node/pnpx.cmd @@ -5,4 +5,3 @@ ECHO %~dp0 %* ) ELSE ( node %* ) - diff --git a/plugin/src/intTest/resources/node-dist-without-corepack/yarn.cmd b/plugin/src/integrationTest/resources/node-dist-without-node/yarn.cmd similarity index 99% rename from plugin/src/intTest/resources/node-dist-without-corepack/yarn.cmd rename to plugin/src/integrationTest/resources/node-dist-without-node/yarn.cmd index 1c835f1b..2c540e6c 100644 --- a/plugin/src/intTest/resources/node-dist-without-corepack/yarn.cmd +++ b/plugin/src/integrationTest/resources/node-dist-without-node/yarn.cmd @@ -5,4 +5,3 @@ ECHO %~dp0 %* ) ELSE ( node %* ) - diff --git a/plugin/src/intTest/resources/node-v18.17.1.zip b/plugin/src/integrationTest/resources/node-v20.14.0.zip similarity index 100% rename from plugin/src/intTest/resources/node-v18.17.1.zip rename to plugin/src/integrationTest/resources/node-v20.14.0.zip diff --git a/plugin/src/intTest/resources/package-any-manager.json b/plugin/src/integrationTest/resources/package-any-manager.json similarity index 100% rename from plugin/src/intTest/resources/package-any-manager.json rename to plugin/src/integrationTest/resources/package-any-manager.json diff --git a/plugin/src/intTest/resources/package-invalid-manager.json b/plugin/src/integrationTest/resources/package-invalid-manager.json similarity index 100% rename from plugin/src/intTest/resources/package-invalid-manager.json rename to plugin/src/integrationTest/resources/package-invalid-manager.json diff --git a/plugin/src/intTest/resources/package-no-manager.json b/plugin/src/integrationTest/resources/package-no-manager.json similarity index 100% rename from plugin/src/intTest/resources/package-no-manager.json rename to plugin/src/integrationTest/resources/package-no-manager.json diff --git a/plugin/src/intTest/resources/package-npm.json b/plugin/src/integrationTest/resources/package-npm.json similarity index 100% rename from plugin/src/intTest/resources/package-npm.json rename to plugin/src/integrationTest/resources/package-npm.json diff --git a/plugin/src/intTest/resources/package-pnpm.json b/plugin/src/integrationTest/resources/package-pnpm.json similarity index 100% rename from plugin/src/intTest/resources/package-pnpm.json rename to plugin/src/integrationTest/resources/package-pnpm.json diff --git a/plugin/src/intTest/resources/package-yarn.json b/plugin/src/integrationTest/resources/package-yarn.json similarity index 100% rename from plugin/src/intTest/resources/package-yarn.json rename to plugin/src/integrationTest/resources/package-yarn.json diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java index 154c55d3..63990a0e 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/FrontendGradlePlugin.java @@ -6,6 +6,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; import java.util.Set; import org.gradle.api.GradleException; @@ -14,43 +15,42 @@ import org.gradle.api.Task; import org.gradle.api.file.RegularFile; import org.gradle.api.plugins.BasePlugin; +import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.publish.plugins.PublishingPlugin; import org.gradle.api.tasks.TaskContainer; -import org.gradle.api.tasks.TaskState; import org.gradle.language.base.plugins.LifecycleBasePlugin; import org.siouan.frontendgradleplugin.domain.ExecutableType; import org.siouan.frontendgradleplugin.domain.FileManager; import org.siouan.frontendgradleplugin.domain.MalformedPackageManagerSpecification; import org.siouan.frontendgradleplugin.domain.ParsePackageManagerSpecification; -import org.siouan.frontendgradleplugin.domain.PlatformProvider; +import org.siouan.frontendgradleplugin.domain.Platform; import org.siouan.frontendgradleplugin.domain.ResolveExecutablePathCommand; import org.siouan.frontendgradleplugin.domain.ResolveNodeExecutablePath; -import org.siouan.frontendgradleplugin.domain.SystemSettingsProvider; +import org.siouan.frontendgradleplugin.domain.SystemProperties; import org.siouan.frontendgradleplugin.domain.UnsupportedPackageManagerException; import org.siouan.frontendgradleplugin.infrastructure.archiver.ArchiverProviderImpl; import org.siouan.frontendgradleplugin.infrastructure.bean.BeanInstanciationException; -import org.siouan.frontendgradleplugin.infrastructure.bean.Beans; +import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistry; import org.siouan.frontendgradleplugin.infrastructure.bean.TooManyCandidateBeansException; import org.siouan.frontendgradleplugin.infrastructure.bean.ZeroOrMultiplePublicConstructorsException; import org.siouan.frontendgradleplugin.infrastructure.gradle.AssembleTask; +import org.siouan.frontendgradleplugin.infrastructure.gradle.BeanRegistryBuildService; import org.siouan.frontendgradleplugin.infrastructure.gradle.CheckTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.CleanTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.FrontendExtension; import org.siouan.frontendgradleplugin.infrastructure.gradle.GradleLoggerAdapter; import org.siouan.frontendgradleplugin.infrastructure.gradle.GradleSettings; +import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallCorepackTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallFrontendTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallNodeTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallPackageManagerTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.PublishTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.ResolvePackageManagerTask; -import org.siouan.frontendgradleplugin.infrastructure.gradle.SystemExtension; -import org.siouan.frontendgradleplugin.infrastructure.gradle.SystemSettingsProviderImpl; -import org.siouan.frontendgradleplugin.infrastructure.gradle.TaskLoggerConfigurer; +import org.siouan.frontendgradleplugin.infrastructure.gradle.SystemProviders; import org.siouan.frontendgradleplugin.infrastructure.httpclient.HttpClientProviderImpl; import org.siouan.frontendgradleplugin.infrastructure.system.ChannelProviderImpl; import org.siouan.frontendgradleplugin.infrastructure.system.FileManagerImpl; -import org.siouan.frontendgradleplugin.infrastructure.system.PlatformProviderImpl; /** * Main plugin class that bootstraps the plugin by declaring its DSL and its tasks. @@ -164,6 +164,13 @@ public class FrontendGradlePlugin implements Plugin { */ public static final String PACKAGE_JSON_FILE_NAME = "package.json"; + /** + * Name of the task that installs a specific version of Corepack. + * + * @since 8.1.0 + */ + public static final String INSTALL_COREPACK_TASK_NAME = "installCorepack"; + /** * Name of the task that installs a Node distribution. */ @@ -199,7 +206,6 @@ public void apply(final Project project) { project.getPluginManager().apply(BasePlugin.class); project.getPluginManager().apply(PublishingPlugin.class); - final SystemExtension systemExtension = new SystemExtension(project.getProviders()); final FrontendExtension frontendExtension = project .getExtensions() .create(EXTENSION_NAME, FrontendExtension.class, project.getObjects()); @@ -223,82 +229,81 @@ public void apply(final Project project) { frontendExtension .getCacheDirectory() .convention(project.getLayout().getProjectDirectory().dir(DEFAULT_CACHE_DIRECTORY_NAME)); - frontendExtension - .getInternalPackageManagerSpecificationFile() - .convention(frontendExtension - .getCacheDirectory() - .dir(RESOLVE_PACKAGE_MANAGER_TASK_NAME) - .map(directory -> directory.file(PACKAGE_MANAGER_SPECIFICATION_FILE_NAME))); - frontendExtension - .getInternalPackageManagerExecutablePathFile() - .convention(frontendExtension - .getCacheDirectory() - .dir(RESOLVE_PACKAGE_MANAGER_TASK_NAME) - .map(directory -> directory.file(PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME))); frontendExtension.getVerboseModeEnabled().convention(false); // Create bean registry and register concrete base implementations. - final String beanRegistryId = configureBeanRegistry(project, systemExtension, frontendExtension); + final Provider beanRegistryBuildServiceProvider = configureBeanRegistry(project, + Set.of(GradleSettings.ofProject(project), GradleLoggerAdapter.class, FileManagerImpl.class, + ChannelProviderImpl.class, ArchiverProviderImpl.class, HttpClientProviderImpl.class)); // Create and configure all tasks. - configureTasks(project, beanRegistryId); + configureTasks(project, beanRegistryBuildServiceProvider, frontendExtension, + new SystemProviders(project.getProviders())); } /** * Creates a bean registry and registers concrete implementations for injection. * * @param project Project. - * @param systemExtension Extension providing system properties. - * @param frontendExtension Extension providing frontend properties. - * @return ID of the bean registry. - */ - protected String configureBeanRegistry(final Project project, final SystemExtension systemExtension, - final FrontendExtension frontendExtension) { - final String beanRegistryId = Beans.getBeanRegistryId(project.getLayout().getProjectDirectory().toString()); - final SystemSettingsProvider systemSettingsProvider = new SystemSettingsProviderImpl(systemExtension, - DEFAULT_HTTP_PROXY_PORT, DEFAULT_HTTPS_PROXY_PORT); - final PlatformProvider platformProvider = new PlatformProviderImpl(systemSettingsProvider); - final GradleSettings gradleSettings = new GradleSettings(project.getLogging().getLevel(), - project.getGradle().getStartParameter().getLogLevel()); - Beans.initBeanRegistry(beanRegistryId); - Beans.registerBean(beanRegistryId, frontendExtension); - Beans.registerBean(beanRegistryId, systemSettingsProvider); - Beans.registerBean(beanRegistryId, platformProvider); - Beans.registerBean(beanRegistryId, gradleSettings); - Beans.registerBean(beanRegistryId, GradleLoggerAdapter.class); - Beans.registerBean(beanRegistryId, TaskLoggerConfigurer.class); - Beans.registerBean(beanRegistryId, FileManagerImpl.class); - Beans.registerBean(beanRegistryId, ChannelProviderImpl.class); - Beans.registerBean(beanRegistryId, ArchiverProviderImpl.class); - Beans.registerBean(beanRegistryId, HttpClientProviderImpl.class); - return beanRegistryId; + * @param beanClassesOrInstances Classes or instances of bean to register. + * @return Provider of the bean registry. + */ + protected Provider configureBeanRegistry(final Project project, + final Set beanClassesOrInstances) { + final BeanRegistry beanRegistry = new BeanRegistry(); + beanClassesOrInstances.forEach(beanClassOrInstance -> { + if (beanClassOrInstance instanceof Class) { + beanRegistry.registerBeanClass((Class) beanClassOrInstance); + } else { + beanRegistry.registerBean(beanClassOrInstance); + } + }); + return project + .getGradle() + .getSharedServices() + .registerIfAbsent(BeanRegistryBuildService.buildName(project), BeanRegistryBuildService.class, + buildServiceSpec -> buildServiceSpec.getParameters().getBeanRegistry().set(beanRegistry)); } /** * Registers plugin tasks. * * @param project Project. - * @param beanRegistryId Bean registry ID. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. + * @param frontendExtension Frontend extension. + * @param systemProviders Providers of system properties. */ - protected void configureTasks(final Project project, final String beanRegistryId) { + protected void configureTasks(final Project project, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { final TaskContainer taskContainer = project.getTasks(); - final FrontendExtension frontendExtension = getBeanOrFail(beanRegistryId, FrontendExtension.class); taskContainer.register(INSTALL_NODE_TASK_NAME, InstallNodeTask.class, - task -> configureInstallNodeTask(task, beanRegistryId, frontendExtension)); + task -> configureInstallNodeTask(task, beanRegistryBuildServiceProvider, frontendExtension, + systemProviders)); + taskContainer.register(INSTALL_COREPACK_TASK_NAME, InstallCorepackTask.class, + task -> configureInstallCorepackTask(task, taskContainer, beanRegistryBuildServiceProvider, + frontendExtension, systemProviders)); taskContainer.register(RESOLVE_PACKAGE_MANAGER_TASK_NAME, ResolvePackageManagerTask.class, - task -> configureResolvePackageManagerTask(task, taskContainer, frontendExtension)); + task -> configureResolvePackageManagerTask(task, taskContainer, beanRegistryBuildServiceProvider, + frontendExtension, systemProviders)); taskContainer.register(INSTALL_PACKAGE_MANAGER_TASK_NAME, InstallPackageManagerTask.class, - task -> configureInstallPackageManagerTask(task, beanRegistryId, taskContainer, frontendExtension)); + task -> configureInstallPackageManagerTask(task, taskContainer, beanRegistryBuildServiceProvider, + frontendExtension, systemProviders)); taskContainer.register(INSTALL_FRONTEND_TASK_NAME, InstallFrontendTask.class, - task -> configureInstallFrontendTask(task, beanRegistryId, taskContainer, frontendExtension)); + task -> configureInstallFrontendTask(task, taskContainer, beanRegistryBuildServiceProvider, + frontendExtension, systemProviders)); taskContainer.register(CLEAN_TASK_NAME, CleanTask.class, - task -> configureCleanTask(task, beanRegistryId, taskContainer, frontendExtension)); + task -> configureCleanFrontendTask(task, taskContainer, beanRegistryBuildServiceProvider, frontendExtension, + systemProviders)); taskContainer.register(CHECK_TASK_NAME, CheckTask.class, - task -> configureCheckTask(task, beanRegistryId, taskContainer, frontendExtension)); + task -> configureCheckFrontendTask(task, taskContainer, beanRegistryBuildServiceProvider, frontendExtension, + systemProviders)); taskContainer.register(ASSEMBLE_TASK_NAME, AssembleTask.class, - task -> configureAssembleTask(task, beanRegistryId, taskContainer, frontendExtension)); + task -> configureAssembleFrontendTask(task, taskContainer, beanRegistryBuildServiceProvider, + frontendExtension, systemProviders)); taskContainer.register(PUBLISH_TASK_NAME, PublishTask.class, - task -> configurePublishTask(task, beanRegistryId, taskContainer, frontendExtension)); + task -> configurePublishFrontendTask(task, taskContainer, beanRegistryBuildServiceProvider, + frontendExtension, systemProviders)); // Configure dependencies with Gradle built-in tasks. configureDependency(taskContainer, GRADLE_CLEAN_TASK_NAME, CLEAN_TASK_NAME, CleanTask.class); @@ -311,13 +316,17 @@ protected void configureTasks(final Project project, final String beanRegistryId * Configures the given task with the plugin extension. * * @param task Task. - * @param beanRegistryId Bean registry ID. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ - protected void configureInstallNodeTask(final InstallNodeTask task, final String beanRegistryId, - final FrontendExtension frontendExtension) { + protected void configureInstallNodeTask(final InstallNodeTask task, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Downloads and installs a Node.js distribution."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + task.getNodeVersion().set(frontendExtension.getNodeVersion()); task.getNodeDistributionUrlRoot().set(frontendExtension.getNodeDistributionUrlRoot()); task.getNodeDistributionUrlPathPattern().set(frontendExtension.getNodeDistributionUrlPathPattern()); @@ -336,18 +345,53 @@ protected void configureInstallNodeTask(final InstallNodeTask task, final String .getNodeExecutableFile() .fileProvider(frontendExtension .getNodeInstallDirectory() - .map(directory -> getBeanOrFail(beanRegistryId, ResolveNodeExecutablePath.class) - .execute(ResolveExecutablePathCommand - .builder() - .nodeInstallDirectoryPath(directory.getAsFile().toPath()) - .platform(getBeanOrFail(beanRegistryId, PlatformProvider.class).getPlatform()) - .build()) - .toFile())); + .flatMap(directory -> beanRegistryBuildServiceProvider.map(beanRegistryBuildService -> { + final BeanRegistry beanRegistry = beanRegistryBuildService.getBeanRegistry(); + return getBeanOrFail(beanRegistry, ResolveNodeExecutablePath.class) + .execute(ResolveExecutablePathCommand + .builder() + .nodeInstallDirectoryPath(directory.getAsFile().toPath()) + .platform(Platform + .builder() + .jvmArch(systemProviders.getJvmArch().get()) + .osName(systemProviders.getOsName().get()) + .build()) + .build()) + .toFile(); + }))); task.getMaxDownloadAttempts().set(frontendExtension.getMaxDownloadAttempts()); task.getRetryHttpStatuses().set(frontendExtension.getRetryHttpStatuses()); task.getRetryInitialIntervalMs().set(frontendExtension.getRetryInitialIntervalMs()); task.getRetryIntervalMultiplier().set(frontendExtension.getRetryIntervalMultiplier()); task.getRetryMaxIntervalMs().set(frontendExtension.getRetryMaxIntervalMs()); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + task.getSystemHttpProxyHost().set(systemProviders.getHttpProxyHost()); + task + .getSystemHttpProxyPort() + .set(systemProviders + .getHttpProxyPort() + .filter(port -> !port.isBlank()) + .map(Integer::parseInt) + .orElse(DEFAULT_HTTP_PROXY_PORT)); + task.getSystemHttpsProxyHost().set(systemProviders.getHttpsProxyHost()); + task + .getSystemHttpsProxyPort() + .set(systemProviders + .getHttpsProxyPort() + .filter(port -> !port.isBlank()) + .map(Integer::parseInt) + .orElse(DEFAULT_HTTPS_PROXY_PORT)); + task + .getSystemNonProxyHosts() + .set(systemProviders + .getNonProxyHosts() + .filter(nonProxyHosts -> !nonProxyHosts.isBlank()) + .map(nonProxyHosts -> nonProxyHosts.split(SystemProperties.NON_PROXY_HOSTS_SPLIT_PATTERN)) + .map(Set::of) + // https://github.com/gradle/gradle/issues/26942 + // Do not use JDK 11 method "Set.of" that is not serialized correctly by Gradle + .orElse(Collections.emptySet())); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); task.setOnlyIf(t -> !frontendExtension.getNodeDistributionProvided().get()); } @@ -356,23 +400,66 @@ protected void configureInstallNodeTask(final InstallNodeTask task, final String * * @param task Task. * @param taskContainer Gradle task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. + * @param frontendExtension Plugin extension. + */ + protected void configureInstallCorepackTask(final InstallCorepackTask task, final TaskContainer taskContainer, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { + task.setGroup(TASK_GROUP); + task.setDescription( + "Installs a specific version of Corepack, overriding the one provided by default in Node.js distribution."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + + task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().getAsFile()); + task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); + task.getCorepackVersion().set(frontendExtension.getCorepackVersion()); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); + task.setOnlyIf(t -> frontendExtension.getCorepackVersion().isPresent()); + + configureDependency(taskContainer, task, INSTALL_NODE_TASK_NAME, InstallNodeTask.class); + } + + /** + * Configures the given task with the plugin extension. + * + * @param task Task. + * @param taskContainer Gradle task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ protected void configureResolvePackageManagerTask(final ResolvePackageManagerTask task, - final TaskContainer taskContainer, final FrontendExtension frontendExtension) { + final TaskContainer taskContainer, final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Resolves the package manager."); - final Provider packageJsonFileProvider = frontendExtension - .getPackageJsonDirectory() - .file(PACKAGE_JSON_FILE_NAME) - .map(RegularFile::getAsFile); - task.getPackageJsonFile().fileProvider(packageJsonFileProvider); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + + task + .getPackageJsonFile() + .fileProvider(frontendExtension + .getPackageJsonDirectory() + .file(PACKAGE_JSON_FILE_NAME) + .map(RegularFile::getAsFile) + .filter(packageJsonFile -> Files.isRegularFile(packageJsonFile.toPath()))); task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); - task.getPackageManagerSpecificationFile().set(frontendExtension.getInternalPackageManagerSpecificationFile()); - task.getPackageManagerExecutablePathFile().set(frontendExtension.getInternalPackageManagerExecutablePathFile()); - // The task is skipped when there's no package.json file. It allows to define a project that installs only a - // Node.js distribution. - task.setOnlyIf(t -> packageJsonFileProvider.map(File::toPath).map(Files::isRegularFile).getOrElse(false)); + task + .getPackageManagerSpecificationFile() + .set(frontendExtension + .getCacheDirectory() + .dir(RESOLVE_PACKAGE_MANAGER_TASK_NAME) + .map(directory -> directory.file(PACKAGE_MANAGER_SPECIFICATION_FILE_NAME))); + task + .getPackageManagerExecutablePathFile() + .set(frontendExtension + .getCacheDirectory() + .dir(RESOLVE_PACKAGE_MANAGER_TASK_NAME) + .map(directory -> directory.file(PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME))); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); configureDependency(taskContainer, task, INSTALL_NODE_TASK_NAME, InstallNodeTask.class); } @@ -381,25 +468,20 @@ protected void configureResolvePackageManagerTask(final ResolvePackageManagerTas * Configures the given task with the plugin extension. * * @param task Task. - * @param beanRegistryId Bean registry ID. * @param taskContainer Task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ - protected void configureInstallPackageManagerTask(final InstallPackageManagerTask task, final String beanRegistryId, - final TaskContainer taskContainer, final FrontendExtension frontendExtension) { + protected void configureInstallPackageManagerTask(final InstallPackageManagerTask task, + final TaskContainer taskContainer, final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Installs the package manager."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().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 not found: " + nodeInstallDirectoryPath); - } - return nodeInstallDirectory.getAsFile(); - })); + task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); final Provider resolvePackageManagerTaskProvider = taskContainer.named( RESOLVE_PACKAGE_MANAGER_TASK_NAME, ResolvePackageManagerTask.class); task @@ -418,9 +500,10 @@ protected void configureInstallPackageManagerTask(final InstallPackageManagerTas // touched by Gradle. return null; } + final BeanRegistry beanRegistry = beanRegistryBuildServiceProvider.get().getBeanRegistry(); try { return Paths - .get(getBeanOrFail(beanRegistryId, FileManager.class).readString(filePath, + .get(getBeanOrFail(beanRegistry, FileManager.class).readString(filePath, StandardCharsets.UTF_8)) .toFile(); } catch (final IOException e) { @@ -428,26 +511,40 @@ protected void configureInstallPackageManagerTask(final InstallPackageManagerTas "Cannot read path to package manager executable from file: " + filePath, e); } })); - task.setOnlyIf(t -> isTaskExecuted(taskContainer, RESOLVE_PACKAGE_MANAGER_TASK_NAME)); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); + // The task is skipped when there's no package.json file. It allows to define a project that installs only a + // Node.js distribution. + task.setOnlyIf(t -> packageJsonFileExists(frontendExtension)); + + configureDependency(taskContainer, task, INSTALL_COREPACK_TASK_NAME, InstallCorepackTask.class); } /** * Configures the given task with the plugin extension. * * @param task Task. - * @param beanRegistryId Bean registry ID. * @param taskContainer Task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ - protected void configureInstallFrontendTask(final InstallFrontendTask task, final String beanRegistryId, - final TaskContainer taskContainer, final FrontendExtension frontendExtension) { + protected void configureInstallFrontendTask(final InstallFrontendTask task, final TaskContainer taskContainer, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Installs frontend dependencies."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + + final BeanRegistry beanRegistry = beanRegistryBuildServiceProvider.get().getBeanRegistry(); task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().getAsFile()); task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); - task.getExecutableType().set(getExecutableType(taskContainer, beanRegistryId)); + task.getExecutableType().set(getExecutableType(taskContainer, beanRegistry)); task.getInstallScript().set(frontendExtension.getInstallScript()); - task.setOnlyIf(t -> isTaskExecuted(taskContainer, INSTALL_PACKAGE_MANAGER_TASK_NAME)); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); + task.setOnlyIf(t -> packageJsonFileExists(frontendExtension)); + configureDependency(taskContainer, task, INSTALL_PACKAGE_MANAGER_TASK_NAME, InstallPackageManagerTask.class); } @@ -455,21 +552,27 @@ protected void configureInstallFrontendTask(final InstallFrontendTask task, fina * Configures the given task with the plugin extension. * * @param task Task. - * @param beanRegistryId Bean registry ID. * @param taskContainer Task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ - protected void configureCleanTask(final CleanTask task, final String beanRegistryId, - final TaskContainer taskContainer, final FrontendExtension frontendExtension) { + protected void configureCleanFrontendTask(final CleanTask task, final TaskContainer taskContainer, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Cleans frontend resources outside the build directory by running a specific script."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + + final BeanRegistry beanRegistry = beanRegistryBuildServiceProvider.get().getBeanRegistry(); task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().getAsFile()); task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); - task.getExecutableType().set(getExecutableType(taskContainer, beanRegistryId)); + task.getExecutableType().set(getExecutableType(taskContainer, beanRegistry)); task.getCleanScript().set(frontendExtension.getCleanScript()); - task.setOnlyIf(t -> isTaskExecuted(taskContainer, INSTALL_FRONTEND_TASK_NAME) && frontendExtension - .getCleanScript() - .isPresent()); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); + task.setOnlyIf(t -> packageJsonFileExists(frontendExtension) && frontendExtension.getCleanScript().isPresent()); + configureDependency(taskContainer, task, INSTALL_FRONTEND_TASK_NAME, InstallFrontendTask.class); } @@ -477,21 +580,27 @@ protected void configureCleanTask(final CleanTask task, final String beanRegistr * Configures the given task with the plugin extension. * * @param task Task. - * @param beanRegistryId Bean registry ID. * @param taskContainer Task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ - protected void configureCheckTask(final CheckTask task, final String beanRegistryId, - final TaskContainer taskContainer, final FrontendExtension frontendExtension) { + protected void configureCheckFrontendTask(final CheckTask task, final TaskContainer taskContainer, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Checks frontend by running a specific script."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + + final BeanRegistry beanRegistry = beanRegistryBuildServiceProvider.get().getBeanRegistry(); task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().getAsFile()); task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); - task.getExecutableType().set(getExecutableType(taskContainer, beanRegistryId)); + task.getExecutableType().set(getExecutableType(taskContainer, beanRegistry)); task.getCheckScript().set(frontendExtension.getCheckScript()); - task.setOnlyIf(t -> isTaskExecuted(taskContainer, INSTALL_FRONTEND_TASK_NAME) && frontendExtension - .getCheckScript() - .isPresent()); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); + task.setOnlyIf(t -> packageJsonFileExists(frontendExtension) && frontendExtension.getCheckScript().isPresent()); + configureDependency(taskContainer, task, INSTALL_FRONTEND_TASK_NAME, InstallFrontendTask.class); } @@ -499,21 +608,28 @@ protected void configureCheckTask(final CheckTask task, final String beanRegistr * Configures the given task with the plugin extension. * * @param task Task. - * @param beanRegistryId Bean registry ID. * @param taskContainer Task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ - protected void configureAssembleTask(final AssembleTask task, final String beanRegistryId, - final TaskContainer taskContainer, final FrontendExtension frontendExtension) { + protected void configureAssembleFrontendTask(final AssembleTask task, final TaskContainer taskContainer, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Assembles frontend artifacts by running a specific script."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + + final BeanRegistry beanRegistry = beanRegistryBuildServiceProvider.get().getBeanRegistry(); task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().getAsFile()); task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); - task.getExecutableType().set(getExecutableType(taskContainer, beanRegistryId)); + task.getExecutableType().set(getExecutableType(taskContainer, beanRegistry)); task.getAssembleScript().set(frontendExtension.getAssembleScript()); - task.setOnlyIf(t -> isTaskExecuted(taskContainer, INSTALL_FRONTEND_TASK_NAME) && frontendExtension - .getAssembleScript() - .isPresent()); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); + task.setOnlyIf( + t -> packageJsonFileExists(frontendExtension) && frontendExtension.getAssembleScript().isPresent()); + configureDependency(taskContainer, task, INSTALL_FRONTEND_TASK_NAME, InstallFrontendTask.class); } @@ -521,38 +637,47 @@ protected void configureAssembleTask(final AssembleTask task, final String beanR * Configures the given task with the plugin extension. * * @param task Task. - * @param beanRegistryId Bean registry ID. * @param taskContainer Task container. + * @param beanRegistryBuildServiceProvider Bean registry build service provider. * @param frontendExtension Plugin extension. */ - protected void configurePublishTask(final PublishTask task, final String beanRegistryId, - final TaskContainer taskContainer, final FrontendExtension frontendExtension) { + protected void configurePublishFrontendTask(final PublishTask task, final TaskContainer taskContainer, + final Provider beanRegistryBuildServiceProvider, + final FrontendExtension frontendExtension, final SystemProviders systemProviders) { task.setGroup(TASK_GROUP); task.setDescription("Publishes frontend artifacts by running a specific script."); + task.getBeanRegistryBuildService().set(beanRegistryBuildServiceProvider); + task.usesService(beanRegistryBuildServiceProvider); + + final BeanRegistry beanRegistry = beanRegistryBuildServiceProvider.get().getBeanRegistry(); task.getPackageJsonDirectory().set(frontendExtension.getPackageJsonDirectory().getAsFile()); task.getNodeInstallDirectory().set(frontendExtension.getNodeInstallDirectory().getAsFile()); - task.getExecutableType().set(getExecutableType(taskContainer, beanRegistryId)); + task.getExecutableType().set(getExecutableType(taskContainer, beanRegistry)); task.getPublishScript().set(frontendExtension.getPublishScript()); - task.setOnlyIf(t -> isTaskExecuted(taskContainer, INSTALL_FRONTEND_TASK_NAME) && frontendExtension - .getAssembleScript() - .isPresent() && frontendExtension.getPublishScript().isPresent()); + task.getVerboseModeEnabled().set(frontendExtension.getVerboseModeEnabled()); + bindSystemArchPropertiesToTaskInputs(systemProviders, task.getSystemJvmArch(), task.getSystemOsName()); + + task.setOnlyIf( + t -> packageJsonFileExists(frontendExtension) && frontendExtension.getAssembleScript().isPresent() + && frontendExtension.getPublishScript().isPresent()); configureDependency(taskContainer, task, ASSEMBLE_TASK_NAME, AssembleTask.class); } - private Provider getExecutableType(final TaskContainer taskContainer, final String beanRegistryId) { + private Provider getExecutableType(final TaskContainer taskContainer, + final BeanRegistry beanRegistry) { return taskContainer .named(RESOLVE_PACKAGE_MANAGER_TASK_NAME, ResolvePackageManagerTask.class) .flatMap(ResolvePackageManagerTask::getPackageManagerSpecificationFile) .map(f -> { final Path packageManagerSpecificationFilePath = f.getAsFile().toPath(); try { - return getBeanOrFail(beanRegistryId, ParsePackageManagerSpecification.class) - .execute(getBeanOrFail(beanRegistryId, FileManager.class).readString( + return getBeanOrFail(beanRegistry, ParsePackageManagerSpecification.class) + .execute(getBeanOrFail(beanRegistry, FileManager.class).readString( packageManagerSpecificationFilePath, StandardCharsets.UTF_8)) .getType() .getExecutableType(); } catch (final IOException | MalformedPackageManagerSpecification | - UnsupportedPackageManagerException e) { + UnsupportedPackageManagerException e) { throw new GradleException( "Cannot read package manager specification from file: " + packageManagerSpecificationFilePath, e); @@ -593,31 +718,33 @@ private void configureDependency(final TaskCont /** * Returns a bean from a registry of throws an error if no bean is registered or is instanciable. * - * @param beanRegistryId ID of the bean registry. + * @param beanRegistry Bean registry. * @param beanClass Class of the bean to be found/instanciated. * @param Type of bean. * @return The bean. */ - private T getBeanOrFail(final String beanRegistryId, final Class beanClass) { + private T getBeanOrFail(final BeanRegistry beanRegistry, final Class beanClass) { try { - return Beans.getBean(beanRegistryId, beanClass); + return beanRegistry.getBean(beanClass); } catch (final BeanInstanciationException | TooManyCandidateBeansException | - ZeroOrMultiplePublicConstructorsException e) { + ZeroOrMultiplePublicConstructorsException e) { throw new GradleException(e.getClass().getName() + ": " + e.getMessage(), e); } } - /** - * Tells whether a task has been executed in the current build. - * - * @param taskContainer Task container. - * @param taskName Task name. - * @return {@code true} if the task was executed (i.e. not skipped or up-to-date). - */ - private boolean isTaskExecuted(final TaskContainer taskContainer, final String taskName) { - return taskContainer.named(taskName).map(task -> { - final TaskState taskState = task.getState(); - return taskState.getUpToDate() || !taskState.getSkipped(); - }).getOrElse(false); + private void bindSystemArchPropertiesToTaskInputs(final SystemProviders systemProviders, + final Property systemJvmArch, final Property systemOsName) { + systemJvmArch.set(systemProviders.getJvmArch()); + systemOsName.set(systemProviders.getOsName()); + } + + private boolean packageJsonFileExists(final FrontendExtension frontendExtension) { + return frontendExtension + .getPackageJsonDirectory() + .file(PACKAGE_JSON_FILE_NAME) + .map(RegularFile::getAsFile) + .map(File::toPath) + .map(Files::isRegularFile) + .get(); } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ExecutionSettings.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ExecutionSettings.java index e9395e5b..b406f7ef 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ExecutionSettings.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ExecutionSettings.java @@ -2,6 +2,7 @@ import java.nio.file.Path; import java.util.List; +import java.util.Map; import java.util.Set; import lombok.Builder; @@ -42,6 +43,14 @@ public class ExecutionSettings { @ToString.Include private final List arguments; + /** + * Additional environment variables to pass to the process. + * + * @since 8.1.0 + */ + @ToString.Include + private final Map environmentVariables; + /** * Builds execution settings. * @@ -51,10 +60,11 @@ public class ExecutionSettings { * @param arguments List of arguments. */ public ExecutionSettings(final Path workingDirectoryPath, final Set additionalExecutablePaths, - final Path executablePath, final List arguments) { + final Path executablePath, final List arguments, final Map environmentVariables) { this.workingDirectoryPath = workingDirectoryPath; this.additionalExecutablePaths = Set.copyOf(additionalExecutablePaths); this.executablePath = executablePath; this.arguments = List.copyOf(arguments); + this.environmentVariables = Map.copyOf(environmentVariables); } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/FileManager.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/FileManager.java index eb072c8f..58210d4a 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/FileManager.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/FileManager.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.Serializable; import java.nio.charset.Charset; import java.nio.file.CopyOption; import java.nio.file.OpenOption; @@ -17,7 +18,7 @@ * * @since 2.0.0 */ -public interface FileManager { +public interface FileManager extends Serializable { /** * Copies all bytes from an input stream into a file. diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/GetExecutablePath.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/GetExecutablePath.java index 99edba76..72a3e4c2 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/GetExecutablePath.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/GetExecutablePath.java @@ -30,7 +30,7 @@ public class GetExecutablePath { * @see ExecutableType */ public Path execute(final GetExecutablePathCommand command) { - final ResolveExecutablePathCommand resolveGlobalExecutablePathCommand = ResolveExecutablePathCommand + final ResolveExecutablePathCommand resolveExecutablePathCommand = ResolveExecutablePathCommand .builder() .platform(command.getPlatform()) .nodeInstallDirectoryPath(command.getNodeInstallDirectoryPath()) @@ -38,15 +38,15 @@ public Path execute(final GetExecutablePathCommand command) { final ExecutableType executableType = command.getExecutableType(); switch (executableType) { case COREPACK: - return getCorepackExecutablePath.execute(resolveGlobalExecutablePathCommand); + return getCorepackExecutablePath.execute(resolveExecutablePathCommand); case NODE: - return getNodeExecutablePath.execute(resolveGlobalExecutablePathCommand); + return getNodeExecutablePath.execute(resolveExecutablePathCommand); case NPM: - return getNpmExecutablePath.execute(resolveGlobalExecutablePathCommand); + return getNpmExecutablePath.execute(resolveExecutablePathCommand); case PNPM: - return getPnpmExecutablePath.execute(resolveGlobalExecutablePathCommand); + return getPnpmExecutablePath.execute(resolveExecutablePathCommand); case YARN: - return getYarnExecutablePath.execute(resolveGlobalExecutablePathCommand); + return getYarnExecutablePath.execute(resolveExecutablePathCommand); default: throw new IllegalArgumentException("Unsupported type of executable: " + executableType); } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ParsePackageManagerFromPackageJsonFile.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ParsePackageManagerFromPackageJsonFile.java index feb9857c..2fa7a060 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ParsePackageManagerFromPackageJsonFile.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ParsePackageManagerFromPackageJsonFile.java @@ -46,7 +46,8 @@ public PackageManager execute(final Path packageJsonFilePath) throw new InvalidJsonFileException(packageJsonFilePath); } final PackageManager packageManager = parsePackageManagerSpecification.execute(packageManagerSpecification); - logger.info("Package manager: {} v{}", packageManager.getType().getPackageManagerName(), packageManager.getVersion()); + logger.info("Package manager: {} v{}", packageManager.getType().getPackageManagerName(), + packageManager.getVersion()); return packageManager; } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/Platform.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/Platform.java index 43a55e7f..ea252b33 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/Platform.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/Platform.java @@ -30,14 +30,14 @@ public class Platform { private static final String[] SUPPORTED_WINDOWS_OS_IDS = new String[] {"windows"}; /** - * Architecture on which JVM runs. + * Architecture of the underlying JVM. */ @EqualsAndHashCode.Include @ToString.Include private final String jvmArch; /** - * Name of the underlying O/S. + * System name of the O/S. */ @EqualsAndHashCode.Include @ToString.Include diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/PlatformProvider.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/PlatformProvider.java deleted file mode 100644 index fe1cb744..00000000 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/PlatformProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.siouan.frontendgradleplugin.domain; - -/** - * A provider of {@link Platform} instances. - * - * @since 7.0.0 - */ -public interface PlatformProvider { - - /** - * Gets a descriptor of the underlying platform. - * - * @return Platform. - */ - Platform getPlatform(); -} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettings.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettings.java index 15e9118d..f922fccc 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettings.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettings.java @@ -78,7 +78,8 @@ public ExecutionSettings execute(final ResolveExecutionSettingsCommand command) args.add(WINDOWS_EXECUTABLE_AUTOEXIT_FLAG); // The command that must be executed in the terminal must be a single argument on itself (like if it was // quoted). - args.add(escapeWhitespacesFromCommandLineToken(executablePath) + " " + command.getScript().trim()); + args.add( + escapeWhitespacesFromCommandLineToken(executablePath) + " " + command.getScript().trim()); } else { executable = UNIX_EXECUTABLE_PATH; args.add(UNIX_EXECUTABLE_AUTOEXIT_FLAG); @@ -97,7 +98,8 @@ public ExecutionSettings execute(final ResolveExecutionSettingsCommand command) } } - return new ExecutionSettings(command.getPackageJsonDirectoryPath(), executablePaths, executable, args); + return new ExecutionSettings(command.getPackageJsonDirectoryPath(), executablePaths, executable, args, + command.getEnvironmentVariables()); } private String escapeWhitespacesFromCommandLineToken(Path path) { diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsCommand.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsCommand.java index eb0ec3f6..fdd1c2aa 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsCommand.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsCommand.java @@ -1,6 +1,7 @@ package org.siouan.frontendgradleplugin.domain; import java.nio.file.Path; +import java.util.Map; import lombok.Builder; import lombok.EqualsAndHashCode; @@ -45,4 +46,12 @@ public class ResolveExecutionSettingsCommand { */ @EqualsAndHashCode.Include private final String script; + + /** + * Additional environment variables to pass to the process. + * + * @since 8.1.0 + */ + @EqualsAndHashCode.Include + private final Map environmentVariables; } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManager.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManager.java index be183e2c..d15d3b86 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManager.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManager.java @@ -32,18 +32,23 @@ public class ResolvePackageManager { public void execute(final ResolvePackageManagerCommand command) throws InvalidJsonFileException, UnsupportedPackageManagerException, IOException, MalformedPackageManagerSpecification { - final PackageManager packageManager = parsePackageManagerFromPackageJsonFile.execute( - command.getPackageJsonFilePath()); - fileManager.writeString(command.getPackageManagerSpecificationFilePath(), - packageManager.getType().getPackageManagerName() + '@' + packageManager.getVersion(), - StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - fileManager.writeString(command.getPackageManagerExecutablePathFilePath(), getExecutablePath - .execute(GetExecutablePathCommand - .builder() - .executableType(packageManager.getType().getExecutableType()) - .nodeInstallDirectoryPath(command.getNodeInstallDirectoryPath()) - .platform(command.getPlatform()) - .build()) - .toString(), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + if (command.getPackageJsonFilePath() == null) { + fileManager.deleteIfExists(command.getPackageManagerSpecificationFilePath()); + fileManager.deleteIfExists(command.getPackageManagerExecutablePathFilePath()); + } else { + final PackageManager packageManager = parsePackageManagerFromPackageJsonFile.execute( + command.getPackageJsonFilePath()); + fileManager.writeString(command.getPackageManagerSpecificationFilePath(), + packageManager.getType().getPackageManagerName() + '@' + packageManager.getVersion(), + StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + fileManager.writeString(command.getPackageManagerExecutablePathFilePath(), getExecutablePath + .execute(GetExecutablePathCommand + .builder() + .executableType(packageManager.getType().getExecutableType()) + .nodeInstallDirectoryPath(command.getNodeInstallDirectoryPath()) + .platform(command.getPlatform()) + .build()) + .toString(), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + } } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/SystemProperties.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/SystemProperties.java index e0dc1a7c..ee5a5a1e 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/SystemProperties.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/SystemProperties.java @@ -8,7 +8,7 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SystemProperties { - public static final String JVM_ARCH_PROPERTY = "os.arch"; + public static final String JVM_ARCH = "os.arch"; public static final String HTTP_PROXY_HOST = "http.proxyHost"; @@ -22,5 +22,5 @@ public final class SystemProperties { public static final String NON_PROXY_HOSTS_SPLIT_PATTERN = Pattern.quote("|"); - public static final String OS_NAME_PROPERTY = "os.name"; + public static final String OS_NAME = "os.name"; } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/SystemSettingsProvider.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/SystemSettingsProvider.java deleted file mode 100644 index af6d7199..00000000 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/SystemSettingsProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.siouan.frontendgradleplugin.domain; - -import java.util.Set; - -/** - * System-wide settings provider. - * - * @since 5.2.0 - */ -public interface SystemSettingsProvider { - - /** - * Gets a list of hosts that should be reached directly, bypassing the proxy. - * - * @return Set of patterns separated by '|'. The patterns may start or end with a '*' for wildcards. Any host - * matching one of these patterns will be reached through a direct connection instead of through a proxy. - */ - Set getNonProxyHosts(); - - /** - * Gets the host name of the proxy server for HTTP requests. - * - * @return Host name. - */ - String getHttpProxyHost(); - - /** - * Gets the port number of the proxy server for HTTP requests. - * - * @return Port number. - */ - int getHttpProxyPort(); - - /** - * Gets the host name of the proxy server for HTTPS requests. - * - * @return Host name. - */ - String getHttpsProxyHost(); - - /** - * Gets the port number of the proxy server for HTTPS requests. - * - * @return Port number. - */ - int getHttpsProxyPort(); - - /** - * Gets the current JVM architecture. - * - * @return String describing the JVM architecture. - */ - String getSystemJvmArch(); - - /** - * Gets the current O/S name. - * - * @return String describing the O/S. - */ - String getSystemOsName(); -} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/HashFile.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/HashFile.java index d7084c5a..57e3f543 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/HashFile.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/HashFile.java @@ -32,7 +32,7 @@ public class HashFile { private final MessageDigest messageDigest; /** - * Builds a hasher using the SHA-256 algorithm. + * Builds a hash service using the SHA-256 algorithm. * * @param channelProvider Channel provider. * @param convertToHexadecimalString Converter of byte buffer to hexadecimal string. diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/InstallNodeDistribution.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/InstallNodeDistribution.java index c8b58874..5f711abd 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/InstallNodeDistribution.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/InstallNodeDistribution.java @@ -55,8 +55,8 @@ public void execute(final InstallNodeDistributionCommand command) final GetDistributionCommand getDistributionCommand = new GetDistributionCommand(command.getPlatform(), command.getVersion(), command.getDistributionUrlRoot(), command.getDistributionUrlPathPattern(), - command.getDistributionServerCredentials(), command.getProxySettings(), - command.getRetrySettings(), command.getTemporaryDirectoryPath()); + command.getDistributionServerCredentials(), command.getProxySettings(), command.getRetrySettings(), + command.getTemporaryDirectoryPath()); final Path distributionFilePath = getDistribution.execute(getDistributionCommand); // Deploys the distribution diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrl.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrl.java index 99e6e001..2db8e9ad 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrl.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrl.java @@ -3,7 +3,6 @@ import java.net.URL; import lombok.RequiredArgsConstructor; -import org.siouan.frontendgradleplugin.domain.SystemSettingsProvider; /** * Resolves proxy settings for a given URL. @@ -19,8 +18,6 @@ public class ResolveProxySettingsByUrl { private static final String HTTPS_PROTOCOL = "https"; - private final SystemSettingsProvider systemSettingsProvider; - private final IsNonProxyHost isNonProxyHost; private final SelectProxySettings selectProxySettings; @@ -31,7 +28,7 @@ public ProxySettings execute(final ResolveProxySettingsByUrlCommand command) { if (resourceProtocol.equals(HTTP_PROTOCOL) || resourceProtocol.equals(HTTPS_PROTOCOL)) { if (isNonProxyHost.execute(IsNonProxyHostCommand .builder() - .nonProxyHosts(systemSettingsProvider.getNonProxyHosts()) + .nonProxyHosts(command.getSystemNonProxyHosts()) .hostNameOrIpAddress(resourceUrl.getHost()) .build())) { return ProxySettings.NONE; @@ -39,15 +36,15 @@ public ProxySettings execute(final ResolveProxySettingsByUrlCommand command) { final SelectProxySettingsCommand.SelectProxySettingsCommandBuilder selectProxySettingsCommandBuilder = SelectProxySettingsCommand.builder(); if (resourceProtocol.equals(HTTPS_PROTOCOL)) { selectProxySettingsCommandBuilder - .systemProxyHost(systemSettingsProvider.getHttpsProxyHost()) - .systemProxyPort(systemSettingsProvider.getHttpsProxyPort()) + .systemProxyHost(command.getSystemHttpsProxyHost()) + .systemProxyPort(command.getSystemHttpsProxyPort()) .proxyHost(command.getHttpsProxyHost()) .proxyPort(command.getHttpsProxyPort()) .proxyCredentials(command.getHttpsProxyCredentials()); } else { selectProxySettingsCommandBuilder - .systemProxyHost(systemSettingsProvider.getHttpProxyHost()) - .systemProxyPort(systemSettingsProvider.getHttpProxyPort()) + .systemProxyHost(command.getSystemHttpProxyHost()) + .systemProxyPort(command.getSystemHttpProxyPort()) .proxyHost(command.getHttpProxyHost()) .proxyPort(command.getHttpProxyPort()) .proxyCredentials(command.getHttpProxyCredentials()); diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlCommand.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlCommand.java index ef99a433..ed48db9e 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlCommand.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlCommand.java @@ -1,6 +1,7 @@ package org.siouan.frontendgradleplugin.domain.installer; import java.net.URL; +import java.util.Set; import lombok.Builder; import lombok.Getter; @@ -27,4 +28,14 @@ public class ResolveProxySettingsByUrlCommand { private final Credentials httpsProxyCredentials; private final URL resourceUrl; + + private final String systemHttpProxyHost; + + private final int systemHttpProxyPort; + + private final String systemHttpsProxyHost; + + private final int systemHttpsProxyPort; + + private final Set systemNonProxyHosts; } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/archiver/AbstractArchiver.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/archiver/AbstractArchiver.java index ed864f6b..2b647e12 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/archiver/AbstractArchiver.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/domain/installer/archiver/AbstractArchiver.java @@ -3,6 +3,7 @@ import static java.util.stream.Collectors.toSet; import java.io.IOException; +import java.io.Serializable; import java.nio.file.Path; import java.nio.file.attribute.PosixFilePermission; import java.util.Map; @@ -27,7 +28,10 @@ * @since 1.1.3 */ @RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public abstract class AbstractArchiver implements Archiver { +public abstract class AbstractArchiver + implements Archiver, Serializable { + + private static final long serialVersionUID = -3028639659907720045L; /** * Map of binary masks used on Unix modes to extract a single permission. @@ -57,8 +61,9 @@ public abstract class AbstractArchiver { + private static final long serialVersionUID = -1649165974155881017L; + private final byte[] buffer; public TarArchiver(final FileManager fileManager) { @@ -81,7 +83,7 @@ TarArchiveInputStream buildLowLevelInputStream(final InputStream inputStream) { @Override protected Optional getNextEntry(final TarArchiverContext context) throws IOException { - return Optional.ofNullable(context.getInputStream().getNextTarEntry()).map(TarEntry::new); + return Optional.ofNullable(context.getInputStream().getNextEntry()).map(TarEntry::new); } @Override diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/TarEntry.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/TarEntry.java index 70282b7d..5f171a3b 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/TarEntry.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/TarEntry.java @@ -14,7 +14,7 @@ */ @Builder @Getter -class TarEntry implements ArchiveEntry { +public class TarEntry implements ArchiveEntry { /** * Low-level entry mapped to this entry. diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiver.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiver.java index 87f9d136..63d3f704 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiver.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiver.java @@ -26,13 +26,16 @@ */ public class ZipArchiver extends AbstractArchiver { + private static final long serialVersionUID = -6879163434284590850L; + public ZipArchiver(final FileManager fileManager) { super(fileManager); } @Override protected ZipArchiverContext initializeContext(final ExplodeCommand explodeCommand) throws IOException { - return new ZipArchiverContext(explodeCommand, new ZipFile(explodeCommand.getArchiveFilePath().toFile())); + return new ZipArchiverContext(explodeCommand, + ZipFile.builder().setFile(explodeCommand.getArchiveFilePath().toFile()).get()); } @Override diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistry.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistry.java index 0f002666..51e0aaba 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistry.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistry.java @@ -2,13 +2,18 @@ import static java.util.stream.Collectors.toSet; +import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import lombok.extern.slf4j.Slf4j; + /** * This class is a simple implementation of Inversion of Control and dependency injection: it provides a minimal set of * features to ease bean instanciation and reusability, externalize instanciation flow, for the needs of the plugin @@ -16,12 +21,15 @@ * plugins with modularity. Bean classes are instanciated when needed using the one and only one public constructor * available. The registry handles recursive instanciation of constructor parameters, using reflection. However, the * registry does not provide a package-scan feature, e.g. to search for implementations of non-instanciable classes. - * Some implementations must be registered explicitly using the {@link #registerBean(Class)} method or the + * Some implementations must be registered explicitly using the {@link #registerBeanClass(Class)} method or the * {@link #registerBean(Object)} method. The registry handles singleton instances only. * * @since 2.0.0 */ -public class BeanRegistry { +@Slf4j +public class BeanRegistry implements Serializable { + + private static final long serialVersionUID = 8882478289468756368L; /** * Set of types available for injection. When a bean is instanciated, it is placed in the map of {@link #singletons} @@ -40,7 +48,9 @@ public class BeanRegistry { * Builds an initializes the registry with {@link #init()}. */ public BeanRegistry() { - this.registeredBeanTypes = ConcurrentHashMap.newKeySet(); + // Do not use method "ConcurrentHashMap.newKeySet()" since serialization of class KeySetView requires + // '--add-opens' JVM arg. + this.registeredBeanTypes = Collections.newSetFromMap(new ConcurrentHashMap<>()); this.singletons = new ConcurrentHashMap<>(); init(); } @@ -75,18 +85,41 @@ public void init() { */ public T getBean(final Class beanClass) throws BeanInstanciationException, TooManyCandidateBeansException, ZeroOrMultiplePublicConstructorsException { + LOGGER.debug("Requesting: {}", beanClass.getSimpleName()); + return getBean(beanClass, 0); + } + + /** + * Gets an instance of a bean of the given class. If no instance is found, the class is registered and a new + * instance is created and returned. If no bean with the exact same class is registered, this method looks up for an + * assignable child class registered. + * + * @param beanClass Bean class. + * @param Type of bean. + * @return Bean. + * @throws ZeroOrMultiplePublicConstructorsException If the bean class does not contain one and only one public + * constructor, or if a parameter class in the public constructor does not match the same requirement. + * @throws TooManyCandidateBeansException If multiple instances of the bean class are available in the registry, + * generally because these instances are child classes of the bean class. + * @throws BeanInstanciationException If the bean cannot be instanciated. + */ + private T getBean(final Class beanClass, final int nestedLevel) + throws BeanInstanciationException, TooManyCandidateBeansException, ZeroOrMultiplePublicConstructorsException { + final String logEnteringPrefix = " ".repeat(nestedLevel + 1); final T existingBean = (T) singletons.get(beanClass); if (existingBean != null) { + LOGGER.debug("{}< Found: {}", logEnteringPrefix, beanClass.getSimpleName()); return existingBean; } final Class assignableClass = getAssignableClass(beanClass); if (assignableClass != null) { - return getBean(assignableClass); + return getBean(assignableClass, nestedLevel); } + LOGGER.debug("{}+ Instantiating: {}", logEnteringPrefix, beanClass.getSimpleName()); assertBeanClassIsInstanciable(beanClass); - final T newBean = createInstance(beanClass); + final T newBean = createInstance(beanClass, nestedLevel); registerBean(beanClass, newBean); return newBean; } @@ -99,8 +132,9 @@ public T getBean(final Class beanClass) * @param beanClass Bean class. * @param Type of bean. */ - public void registerBean(final Class beanClass) { - if (isBeanRegistered(beanClass)) { + public void registerBeanClass(final Class beanClass) { + LOGGER.debug("Registering class: {}", beanClass.getSimpleName()); + if (isBeanClassRegistered(beanClass)) { return; } assertBeanClassIsInstanciable(beanClass); @@ -116,7 +150,8 @@ public void registerBean(final Class beanClass) { */ public void registerBean(final T bean) { final Class beanClass = (Class) bean.getClass(); - if (isBeanRegistered(beanClass)) { + LOGGER.debug("Registering bean: {}", beanClass.getSimpleName()); + if (isBeanClassRegistered(beanClass)) { return; } registerBean(beanClass, bean); @@ -145,7 +180,7 @@ private void registerBean(final Class beanClass, final T bean) { * @param Type of bean. * @return {@code true} if the bean class is already registered, or is an instance of a bean registry. */ - private boolean isBeanRegistered(final Class beanClass) { + private boolean isBeanClassRegistered(final Class beanClass) { return getClass().isAssignableFrom(beanClass) || registeredBeanTypes.contains(beanClass); } @@ -202,7 +237,7 @@ private Class getAssignableClass(final Class beanClass) * @throws TooManyCandidateBeansException If multiple valid child candidates were found in the registry for a * constructor parameter. */ - private T createInstance(final Class beanClass) + private T createInstance(final Class beanClass, final int nestedLevel) throws BeanInstanciationException, ZeroOrMultiplePublicConstructorsException, TooManyCandidateBeansException { final Constructor[] constructors = beanClass.getConstructors(); if (constructors.length != 1) { @@ -212,7 +247,7 @@ private T createInstance(final Class beanClass) final Class[] parameterTypes = constructors[0].getParameterTypes(); final Object[] parameters = new Object[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { - parameters[i] = getBean(parameterTypes[i]); + parameters[i] = getBean(parameterTypes[i], nestedLevel + 1); } try { return (T) beanClass.getConstructors()[0].newInstance(parameters); @@ -220,4 +255,11 @@ private T createInstance(final Class beanClass) throw new BeanInstanciationException(beanClass, e); } } + + @Override + public String toString() { + return BeanRegistry.class.getName() + " {\n" + "registeredBeanTypes=" + Arrays.toString( + registeredBeanTypes.stream().map(Class::getSimpleName).toArray()) + ", singletons=" + Arrays.toString( + singletons.keySet().stream().map(Class::getSimpleName).toArray()) + "}"; + } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/bean/Beans.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/bean/Beans.java deleted file mode 100644 index 468b89c2..00000000 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/bean/Beans.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.bean; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; - -/** - * This class consists exclusively of static methods, that will delegate to a singleton bean registry instance. It - * allows to access a bean registry where dependency injection is not possible. - * - * @since 2.0.0 - */ -public final class Beans { - - private static final Beans INSTANCE = new Beans(); - - private final Map beanRegistryByIds; - - private Beans() { - beanRegistryByIds = new ConcurrentHashMap<>(); - } - - /** - * Instantiates and initializes a new bean registry. If a registry already exists with the given ID, it is reset. - * - * @param registryId Registry ID. - */ - public static void initBeanRegistry(final String registryId) { - INSTANCE - .findBeanRegistryById(registryId) - .ifPresentOrElse(BeanRegistry::init, () -> INSTANCE.addBeanRegistry(registryId, new BeanRegistry())); - } - - public static String getBeanRegistryId(final String decodedId) { - return Base64.getEncoder().encodeToString(decodedId.getBytes(StandardCharsets.UTF_8)); - } - - public static T getBean(final String registryId, final Class beanClass) - throws BeanInstanciationException, TooManyCandidateBeansException, ZeroOrMultiplePublicConstructorsException { - return INSTANCE.findBeanRegistryByIdOrFail(registryId).getBean(beanClass); - } - - public static void registerBean(final String registryId, final Class beanClass) { - INSTANCE.findBeanRegistryByIdOrFail(registryId).registerBean(beanClass); - } - - public static void registerBean(final String registryId, final T bean) { - INSTANCE.findBeanRegistryByIdOrFail(registryId).registerBean(bean); - } - - public void addBeanRegistry(final String registryId, final BeanRegistry beanRegistry) { - beanRegistryByIds.put(registryId, beanRegistry); - } - - public BeanRegistry findBeanRegistryByIdOrFail(final String registryId) { - return findBeanRegistryById(registryId).orElseThrow( - () -> new IllegalArgumentException("No registry was found with ID " + registryId)); - } - - public Optional findBeanRegistryById(final String registryId) { - return Optional.ofNullable(beanRegistryByIds.get(registryId)); - } -} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTask.java index 8dc45c65..91a312b7 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTask.java @@ -1,10 +1,11 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; import java.io.File; +import java.util.Map; import org.gradle.api.DefaultTask; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Internal; @@ -12,9 +13,8 @@ import org.gradle.process.ExecOperations; import org.siouan.frontendgradleplugin.domain.ExecutableType; import org.siouan.frontendgradleplugin.domain.Platform; -import org.siouan.frontendgradleplugin.domain.PlatformProvider; +import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistry; import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistryException; -import org.siouan.frontendgradleplugin.infrastructure.bean.Beans; /** * This abstract class provides the reusable logic to run a command with an executable. Sub-classes must expose inputs @@ -25,19 +25,20 @@ public abstract class AbstractRunCommandTask extends DefaultTask { protected final ExecOperations execOperations; /** - * Bean registry ID. + * Bean registry service provider. * - * @since 5.2.0 + * @since 8.1.0 */ - protected final String beanRegistryId; + protected final Property beanRegistryBuildService; /** - * Directory where the 'package.json' file is located. + * Directory where the 'package.json' file is located, and used as the working directory when the command is + * executed. */ protected final Property packageJsonDirectory; /** - * Directory where the Node.js distribution is installed. + * Directory where the Node.js distribution is installed, and used to find the executables. */ protected final Property nodeInstallDirectory; @@ -51,14 +52,50 @@ public abstract class AbstractRunCommandTask extends DefaultTask { */ protected final Property script; - AbstractRunCommandTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { + /** + * Whether the task should produce log messages for the end-user. + * + * @since 8.1.0 + */ + protected final Property verboseModeEnabled; + + /** + * Architecture of the underlying JVM. + * + * @since 8.1.0 + */ + protected final Property systemJvmArch; + + /** + * System name of the O/S. + * + * @since 8.1.0 + */ + protected final Property systemOsName; + + /** + * Additional environment variables to pass when executing the script. + * + * @since 8.1.0 + */ + protected final MapProperty environmentVariables; + + AbstractRunCommandTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { this.execOperations = execOperations; - this.beanRegistryId = Beans.getBeanRegistryId(projectLayout.getProjectDirectory().toString()); + this.beanRegistryBuildService = objectFactory.property(BeanRegistryBuildService.class); this.packageJsonDirectory = objectFactory.property(File.class); this.nodeInstallDirectory = objectFactory.property(File.class); this.executableType = objectFactory.property(ExecutableType.class); this.script = objectFactory.property(String.class); + this.verboseModeEnabled = objectFactory.property(Boolean.class); + this.systemJvmArch = objectFactory.property(String.class); + this.systemOsName = objectFactory.property(String.class); + this.environmentVariables = objectFactory.mapProperty(String.class, String.class); + } + + @Internal + public Property getBeanRegistryBuildService() { + return beanRegistryBuildService; } @Internal @@ -66,6 +103,27 @@ public Property getExecutableType() { return executableType; } + @Internal + public Property getVerboseModeEnabled() { + return verboseModeEnabled; + } + + @Internal + public Property getSystemJvmArch() { + return systemJvmArch; + } + + @Internal + public Property getSystemOsName() { + return systemOsName; + } + + @Internal + @SuppressWarnings("unused") + public MapProperty getEnvironmentVariables() { + return environmentVariables; + } + @Input public Property getPackageJsonDirectory() { return packageJsonDirectory; @@ -98,12 +156,14 @@ protected void assertThatTaskIsRunnable() throws NonRunnableTaskException { public void execute() throws NonRunnableTaskException, BeanRegistryException { assertThatTaskIsRunnable(); - Beans.getBean(beanRegistryId, TaskLoggerConfigurer.class).initLoggerAdapter(this); + final BeanRegistry beanRegistry = beanRegistryBuildService.get().getBeanRegistry(); + TaskLoggerInitializer.initAdapter(this, verboseModeEnabled.get(), + beanRegistry.getBean(GradleLoggerAdapter.class), beanRegistry.getBean(GradleSettings.class)); - final Platform platform = Beans.getBean(beanRegistryId, PlatformProvider.class).getPlatform(); + final Platform platform = Platform.builder().jvmArch(systemJvmArch.get()).osName(systemOsName.get()).build(); getLogger().debug("Platform: {}", platform); - Beans - .getBean(beanRegistryId, GradleScriptRunnerAdapter.class) + beanRegistry + .getBean(GradleScriptRunnerAdapter.class) .execute(ScriptProperties .builder() .execOperations(execOperations) @@ -112,6 +172,7 @@ public void execute() throws NonRunnableTaskException, BeanRegistryException { .nodeInstallDirectoryPath(nodeInstallDirectory.map(File::toPath).get()) .script(script.get()) .platform(platform) + .environmentVariables(environmentVariables.getOrElse(Map.of())) .build()); } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTaskType.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTaskType.java index 230c6625..a8aadbaa 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTaskType.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AbstractRunCommandTaskType.java @@ -1,11 +1,10 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; -import org.gradle.api.GradleException; -import org.gradle.api.file.ProjectLayout; +import org.gradle.api.Project; import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.Provider; +import org.gradle.api.services.BuildServiceRegistration; import org.gradle.process.ExecOperations; -import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistryException; -import org.siouan.frontendgradleplugin.infrastructure.bean.Beans; /** * This abstract class provides the required bindings for task types, to run a command with an executable. Sub-classes @@ -13,16 +12,22 @@ */ public abstract class AbstractRunCommandTaskType extends AbstractRunCommandTask { - AbstractRunCommandTaskType(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); - final FrontendExtension frontendExtension; - try { - frontendExtension = Beans.getBean(beanRegistryId, FrontendExtension.class); - } catch (final BeanRegistryException e) { - throw new GradleException(e.getClass().getName() + ": " + e.getMessage(), e); - } - this.packageJsonDirectory.set(frontendExtension.getPackageJsonDirectory().getAsFile()); - this.nodeInstallDirectory.set(frontendExtension.getNodeInstallDirectory().getAsFile()); + AbstractRunCommandTaskType(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); + final Project project = getProject(); + final FrontendExtension frontendExtension = project.getExtensions().getByType(FrontendExtension.class); + final Provider beanRegistryBuildServiceProvider = (Provider) project + .getGradle() + .getSharedServices() + .getRegistrations() + .named(BeanRegistryBuildService.buildName(project)) + .flatMap(BuildServiceRegistration::getService); + beanRegistryBuildService.set(beanRegistryBuildServiceProvider); + packageJsonDirectory.set(frontendExtension.getPackageJsonDirectory().getAsFile()); + nodeInstallDirectory.set(frontendExtension.getNodeInstallDirectory().getAsFile()); + verboseModeEnabled.set(frontendExtension.getVerboseModeEnabled()); + final SystemProviders systemProviders = new SystemProviders(project.getProviders()); + systemJvmArch.set(systemProviders.getJvmArch()); + systemOsName.set(systemProviders.getOsName()); } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleTask.java index 55efc3fe..215fb867 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/AssembleTask.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -10,14 +9,13 @@ import org.gradle.process.ExecOperations; /** - * This task assembles frontend artifacts. + * This task assembles project artifacts. */ public class AssembleTask extends AbstractRunCommandTask { @Inject - public AssembleTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public AssembleTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); } @Input diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/BeanRegistryBuildService.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/BeanRegistryBuildService.java new file mode 100644 index 00000000..ae698c08 --- /dev/null +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/BeanRegistryBuildService.java @@ -0,0 +1,53 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +import lombok.Getter; +import org.gradle.api.Project; +import org.gradle.api.provider.Property; +import org.gradle.api.services.BuildService; +import org.gradle.api.services.BuildServiceParameters; +import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistry; + +/** + * Build service providing the project bean registry to tasks. + * + * @since 8.1.0 + */ +@Getter +public abstract class BeanRegistryBuildService implements BuildService { + + public static final String BEAN_REGISTRY_BUILD_SERVICE_NAME_PREFIX = "fgpBeanRegistryBuildService"; + + /** + * The project bean registry. + */ + private final BeanRegistry beanRegistry; + + public BeanRegistryBuildService() { + beanRegistry = getParameters().getBeanRegistry().get(); + } + + public interface Params extends BuildServiceParameters { + + Property getBeanRegistry(); + } + + /** + * Gets the name of the build service instance registered in the given project. + * + * @param project Project. + * @return Name. + */ + public static String buildName(final Project project) { + return BEAN_REGISTRY_BUILD_SERVICE_NAME_PREFIX + Base64 + .getEncoder() + .encodeToString(project + .getLayout() + .getProjectDirectory() + .getAsFile() + .getAbsolutePath() + .getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckTask.java index 42030f68..7f561f9b 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CheckTask.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -10,14 +9,13 @@ import org.gradle.process.ExecOperations; /** - * This task executes frontend tests. + * This task checks the project. */ public class CheckTask extends AbstractRunCommandTask { @Inject - public CheckTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public CheckTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); } @Input diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanTask.java index 54757025..087091a7 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/CleanTask.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -10,14 +9,13 @@ import org.gradle.process.ExecOperations; /** - * This task cleans frontend resources, using a custom script. + * This task cleans project artifacts. */ public class CleanTask extends AbstractRunCommandTask { @Inject - public CleanTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public CleanTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); } @Input diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecAction.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecAction.java index 32fa4167..95f9ac4a 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecAction.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecAction.java @@ -1,11 +1,15 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; -import static java.util.stream.Collectors.joining; - import java.io.File; import java.nio.file.Path; +import java.util.HashMap; import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.Builder; import lombok.Getter; @@ -20,6 +24,8 @@ @Getter public class ExecSpecAction implements Action { + public static final String PATH_VARIABLE_NAME = "PATH"; + /** * Execution settings. */ @@ -38,43 +44,48 @@ public class ExecSpecAction implements Action { @Override public void execute(final ExecSpec execSpec) { execSpec.setWorkingDir(executionSettings.getWorkingDirectoryPath().toString()); + execSpec.setExecutable(executionSettings.getExecutablePath().toString()); + execSpec.setArgs(executionSettings.getArguments()); + + final Map userEnvironmentVariables = new HashMap<>(executionSettings.getEnvironmentVariables()); + final Map currentEnvironmentVariables = execSpec.getEnvironment(); - // Prepend directories containing the Node and Yarn executables to the 'PATH' environment variable. - // npm is in the same directory than Node, do nothing for it. - final Map environment = execSpec.getEnvironment(); - final String pathVariable = findPathVariable(environment); - final String executablePaths = executionSettings - .getAdditionalExecutablePaths() + // Put all user-defined environment variables except an eventual PATH environment variable which is processed + // separately. + final Optional> userPathVariable = userEnvironmentVariables + .entrySet() .stream() - .map(Path::toString) - .collect(joining(File.pathSeparator)); - final StringBuilder pathValue = new StringBuilder(); - if (!executablePaths.isEmpty()) { - pathValue.append(executablePaths); - pathValue.append(File.pathSeparatorChar); - } - pathValue.append((String) environment.getOrDefault(pathVariable, "")); + .filter(entry -> entry.getKey().equalsIgnoreCase(PATH_VARIABLE_NAME)) + .findAny(); + userPathVariable.map(Map.Entry::getKey).ifPresent(userEnvironmentVariables::remove); - execSpec.environment(pathVariable, pathValue.toString()); - execSpec.setExecutable(executionSettings.getExecutablePath()); - execSpec.setArgs(executionSettings.getArguments()); - afterConfiguredConsumer.accept(execSpec); - } + if (!userEnvironmentVariables.isEmpty()) { + execSpec.environment(userEnvironmentVariables); + } - /** - * Finds the name of the 'PATH' variable. Depending on the O/S, it may be have a different case than the exact - * 'PATH' name. - * - * @param environment Map of environment variables. - * @return The name of the 'PATH' variable. - */ - private String findPathVariable(final Map environment) { - final String pathVariable; - if (environment.containsKey("Path")) { - pathVariable = "Path"; - } else { - pathVariable = "PATH"; + // If the user overrides the 'PATH' environment variable, it takes precedence over the current value in the + // environment. Otherwise, the original 'PATH' is appended, if any. + final Optional> systemPathVariable = currentEnvironmentVariables + .entrySet() + .stream() + .filter(entry -> entry.getKey().equalsIgnoreCase(PATH_VARIABLE_NAME)) + .findAny(); + // Let's prepare the value of the PATH variable by using the eventual override from the user, or the system + // value. + final Optional basePathVariableValue = userPathVariable + .map(Map.Entry::getValue) + .or(() -> systemPathVariable.map(Map.Entry::getValue).map(Objects::toString)); + // Prepare directories containing executables to be prepended to the 'PATH' environment variable. + final Stream.Builder pathVariableBuilder = Stream.builder(); + final Set additionalExecutablePaths = executionSettings.getAdditionalExecutablePaths(); + if (!additionalExecutablePaths.isEmpty() || basePathVariableValue.isPresent()) { + additionalExecutablePaths.forEach( + additionalExecutablePath -> pathVariableBuilder.accept(additionalExecutablePath.toString())); + basePathVariableValue.ifPresent(pathVariableBuilder); + execSpec.environment(PATH_VARIABLE_NAME, + pathVariableBuilder.build().collect(Collectors.joining(File.pathSeparator))); } - return pathVariable; + + afterConfiguredConsumer.accept(execSpec); } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/FrontendExtension.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/FrontendExtension.java index 79c12ef9..9040691d 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/FrontendExtension.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/FrontendExtension.java @@ -2,7 +2,6 @@ import lombok.Getter; import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.file.RegularFileProperty; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.provider.SetProperty; @@ -88,6 +87,13 @@ public class FrontendExtension { */ private final DirectoryProperty packageJsonDirectory; + /** + * Version of Corepack. + * + * @since 8.1.0 + */ + private final Property corepackVersion; + /** * Proxy host used to download resources with HTTP protocol. * @@ -186,24 +192,6 @@ public class FrontendExtension { */ private final DirectoryProperty cacheDirectory; - /** - * WARNING: THIS IS AN INTERNAL PROPERTY, WHICH MUST NOT BE USED/OVERRIDDEN IN GRADLE BUILD FILES. - *

File derived from the {@link #cacheDirectory} property where task "resolvePackageManager" stores the name and - * the version of the package manager.

- * - * @since 7.0.0 - */ - private final RegularFileProperty internalPackageManagerSpecificationFile; - - /** - * WARNING: THIS IS AN INTERNAL PROPERTY, WHICH MUST NOT BE USED/OVERRIDDEN IN GRADLE BUILD FILES. - *

File derived from the {@link #cacheDirectory} property where task "resolvePackageManager" stores the path of - * the package manager executable.

- * - * @since 7.0.0 - */ - private final RegularFileProperty internalPackageManagerExecutablePathFile; - /** * Whether verbose mode is enabled. * @@ -225,6 +213,7 @@ public FrontendExtension(final ObjectFactory objectFactory) { checkScript = objectFactory.property(String.class); publishScript = objectFactory.property(String.class); packageJsonDirectory = objectFactory.directoryProperty(); + corepackVersion = objectFactory.property(String.class); httpProxyHost = objectFactory.property(String.class); httpProxyPort = objectFactory.property(Integer.class); httpProxyUsername = objectFactory.property(String.class); @@ -239,8 +228,6 @@ public FrontendExtension(final ObjectFactory objectFactory) { retryIntervalMultiplier = objectFactory.property(Double.class); retryMaxIntervalMs = objectFactory.property(Integer.class); cacheDirectory = objectFactory.directoryProperty(); - internalPackageManagerSpecificationFile = objectFactory.fileProperty(); - internalPackageManagerExecutablePathFile = objectFactory.fileProperty(); verboseModeEnabled = objectFactory.property(Boolean.class); } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleLoggerAdapter.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleLoggerAdapter.java index 76143ae5..8d5e8756 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleLoggerAdapter.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleLoggerAdapter.java @@ -1,5 +1,7 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import java.io.Serializable; + import org.gradle.api.logging.LogLevel; import org.siouan.frontendgradleplugin.domain.Logger; @@ -8,15 +10,17 @@ * * @since 2.0.0 */ -public class GradleLoggerAdapter implements Logger { +public class GradleLoggerAdapter implements Logger, Serializable { + + private static final long serialVersionUID = 7961046158160963130L; - private org.gradle.api.logging.Logger gradleLogger; + private transient org.gradle.api.logging.Logger gradleLogger; private LogLevel loggingLevel; private boolean verboseModeEnabled; - private String prefix; + private transient String prefix; public GradleLoggerAdapter() { this.loggingLevel = LogLevel.LIFECYCLE; diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapter.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapter.java index 2b496fcb..dd22b876 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapter.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapter.java @@ -33,6 +33,7 @@ public void execute(final ScriptProperties scriptProperties) { .nodeInstallDirectoryPath(scriptProperties.getNodeInstallDirectoryPath()) .platform(scriptProperties.getPlatform()) .script(scriptProperties.getScript()) + .environmentVariables(scriptProperties.getEnvironmentVariables()) .build()); logger.debug("Execution settings: {}", executionSettings); diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleSettings.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleSettings.java index d396dea0..08fc000d 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleSettings.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleSettings.java @@ -1,5 +1,10 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import java.io.Serializable; + +import lombok.Builder; +import lombok.Getter; +import org.gradle.api.Project; import org.gradle.api.logging.LogLevel; /** @@ -7,22 +12,18 @@ * * @since 5.2.0 */ -public class GradleSettings { +@Getter +@Builder +public class GradleSettings implements Serializable { + + private static final long serialVersionUID = 8563728350729514612L; private final LogLevel projectLogLevel; private final LogLevel commandLineLogLevel; - public GradleSettings(final LogLevel projectLogLevel, final LogLevel commandLineLogLevel) { - this.projectLogLevel = projectLogLevel; - this.commandLineLogLevel = commandLineLogLevel; - } - - public LogLevel getProjectLogLevel() { - return projectLogLevel; - } - - public LogLevel getCommandLineLogLevel() { - return commandLineLogLevel; + public static GradleSettings ofProject(final Project project) { + return new GradleSettings(project.getLogging().getLevel(), + project.getGradle().getStartParameter().getLogLevel()); } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallCorepackTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallCorepackTask.java new file mode 100644 index 00000000..30483648 --- /dev/null +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallCorepackTask.java @@ -0,0 +1,89 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import javax.inject.Inject; + +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.OutputDirectory; +import org.gradle.process.ExecOperations; +import org.siouan.frontendgradleplugin.domain.ExecutableType; +import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistryException; + +/** + * This task installs a specific version of Corepack, which will override the default version embedded in the Node.js + * distribution (by executing command {@code node -g install corepack[@]}). + * + * @since 8.1.0 + */ +public class InstallCorepackTask extends AbstractRunCommandTask { + + /** + * NPM command to install globally Corepack. + */ + private static final String INSTALL_COREPACK_COMMAND = "install -g corepack"; + + /** + * Value for the {@link #corepackVersion} property that will lead to the installation of the latest version of + * Corepack. + */ + public static final String LATEST_VERSION_ARGUMENT = "latest"; + + /** + * Path to the Corepack distribution file relative to the Node.js root directory. + */ + public static final String COREPACK_MODULE_PATH = "node_modules/corepack"; + + /** + * Name of the environment variable that prevents Corepack to fail during update with NPM, if the project uses + * another package manager. + */ + public static final String COREPACK_ENABLE_STRICT_VARIABLE = "COREPACK_ENABLE_STRICT"; + + /** + * Version of Corepack that should be installed: may be a specific version number such as {@code X.Y.Z} or the + * {@link #LATEST_VERSION_ARGUMENT} keyword to install the latest version available. + */ + private final Property corepackVersion; + + /** + * Directory containing the Corepack module for Node.js. + */ + private final DirectoryProperty corepackModuleDirectory; + + @Inject + public InstallCorepackTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); + executableType.set(ExecutableType.NPM); + corepackVersion = objectFactory.property(String.class); + corepackModuleDirectory = objectFactory.directoryProperty(); + corepackModuleDirectory.set(getProject() + .getLayout() + .dir(getNodeInstallDirectory().map(f -> f.toPath().resolve(COREPACK_MODULE_PATH).toFile()))); + } + + @Input + public Property getCorepackVersion() { + return corepackVersion; + } + + @OutputDirectory + public DirectoryProperty getCorepackModuleDirectory() { + return corepackModuleDirectory; + } + + @Override + public void execute() throws NonRunnableTaskException, BeanRegistryException { + final StringBuilder scriptBuilder = new StringBuilder(INSTALL_COREPACK_COMMAND); + final String version = corepackVersion.get(); + if (!version.equals(LATEST_VERSION_ARGUMENT)) { + scriptBuilder.append("@"); + scriptBuilder.append(version); + } + this.script.set(scriptBuilder.toString()); + this.environmentVariables.put(COREPACK_ENABLE_STRICT_VARIABLE, "0"); + + super.execute(); + } +} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTask.java index fca8531e..e96f5f27 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallFrontendTask.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -15,9 +14,8 @@ public class InstallFrontendTask extends AbstractRunCommandTask { @Inject - public InstallFrontendTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public InstallFrontendTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); } @Input diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTask.java index d17b80a2..8d3ced38 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallNodeTask.java @@ -6,7 +6,6 @@ import javax.inject.Inject; import org.gradle.api.DefaultTask; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; @@ -17,7 +16,6 @@ import org.gradle.api.tasks.TaskAction; import org.siouan.frontendgradleplugin.domain.FrontendException; import org.siouan.frontendgradleplugin.domain.Platform; -import org.siouan.frontendgradleplugin.domain.PlatformProvider; import org.siouan.frontendgradleplugin.domain.UnsupportedPlatformException; import org.siouan.frontendgradleplugin.domain.installer.Credentials; import org.siouan.frontendgradleplugin.domain.installer.InstallNodeDistribution; @@ -30,8 +28,8 @@ import org.siouan.frontendgradleplugin.domain.installer.RetrySettings; import org.siouan.frontendgradleplugin.domain.installer.UnsupportedDistributionArchiveException; import org.siouan.frontendgradleplugin.domain.installer.archiver.ArchiverException; +import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistry; import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistryException; -import org.siouan.frontendgradleplugin.infrastructure.bean.Beans; /** * Task that downloads and installs a Node distribution. @@ -39,11 +37,11 @@ public class InstallNodeTask extends DefaultTask { /** - * Bean registry ID. + * Bean registry service provider. * - * @since 5.2.0 + * @since 8.1.0 */ - protected final String beanRegistryId; + protected final Property beanRegistryBuildService; /** * Version of the Node distribution to download. @@ -174,6 +172,13 @@ public class InstallNodeTask extends DefaultTask { */ private final Property retryIntervalMultiplier; + /** + * Whether the task should produce log messages for the end-user. + * + * @since 8.1.0 + */ + private final Property verboseModeEnabled; + /** * Maximum interval between retry attempts. * @@ -181,9 +186,58 @@ public class InstallNodeTask extends DefaultTask { */ private final Property retryMaxIntervalMs; + /** + * System-level configuration of the HTTP proxy host. + * + * @since 8.1.0 + */ + private final Property systemHttpProxyHost; + + /** + * System-level configuration of the HTTP proxy port. + * + * @since 8.1.0 + */ + private final Property systemHttpProxyPort; + + /** + * System-level configuration of the HTTPS proxy host. + * + * @since 8.1.0 + */ + private final Property systemHttpsProxyHost; + + /** + * System-level configuration of the HTTPS proxy port + * + * @since 8.1.0 + */ + private final Property systemHttpsProxyPort; + + /** + * System-level configuration of hosts for which direct connection is requested. + * + * @since 8.1.0 + */ + private final SetProperty systemNonProxyHosts; + + /** + * Architecture of the underlying JVM. + * + * @since 8.1.0 + */ + private final Property systemJvmArch; + + /** + * System name of the O/S. + * + * @since 8.1.0 + */ + private final Property systemOsName; + @Inject - public InstallNodeTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory) { - this.beanRegistryId = Beans.getBeanRegistryId(projectLayout.getProjectDirectory().toString()); + public InstallNodeTask(final ObjectFactory objectFactory) { + this.beanRegistryBuildService = objectFactory.property(BeanRegistryBuildService.class); this.nodeVersion = objectFactory.property(String.class); this.nodeInstallDirectory = objectFactory.property(File.class); this.nodeDistributionUrlRoot = objectFactory.property(String.class); @@ -204,6 +258,19 @@ public InstallNodeTask(final ProjectLayout projectLayout, final ObjectFactory ob this.retryInitialIntervalMs = objectFactory.property(Integer.class); this.retryIntervalMultiplier = objectFactory.property(Double.class); this.retryMaxIntervalMs = objectFactory.property(Integer.class); + this.verboseModeEnabled = objectFactory.property(Boolean.class); + this.systemHttpProxyHost = objectFactory.property(String.class); + this.systemHttpProxyPort = objectFactory.property(Integer.class); + this.systemHttpsProxyHost = objectFactory.property(String.class); + this.systemHttpsProxyPort = objectFactory.property(Integer.class); + this.systemNonProxyHosts = objectFactory.setProperty(String.class); + this.systemJvmArch = objectFactory.property(String.class); + this.systemOsName = objectFactory.property(String.class); + } + + @Internal + public Property getBeanRegistryBuildService() { + return beanRegistryBuildService; } @Input @@ -301,6 +368,46 @@ public Property getRetryMaxIntervalMs() { return retryMaxIntervalMs; } + @Internal + public Property getVerboseModeEnabled() { + return verboseModeEnabled; + } + + @Internal + public Property getSystemHttpProxyHost() { + return systemHttpProxyHost; + } + + @Internal + public Property getSystemHttpProxyPort() { + return systemHttpProxyPort; + } + + @Internal + public Property getSystemHttpsProxyHost() { + return systemHttpsProxyHost; + } + + @Internal + public Property getSystemHttpsProxyPort() { + return systemHttpsProxyPort; + } + + @Internal + public SetProperty getSystemNonProxyHosts() { + return systemNonProxyHosts; + } + + @Internal + public Property getSystemJvmArch() { + return systemJvmArch; + } + + @Internal + public Property getSystemOsName() { + return systemOsName; + } + @OutputFile public RegularFileProperty getNodeExecutableFile() { return nodeExecutableFile; @@ -319,7 +426,9 @@ public RegularFileProperty getNodeExecutableFile() { */ @TaskAction public void execute() throws BeanRegistryException, FrontendException, IOException { - Beans.getBean(beanRegistryId, TaskLoggerConfigurer.class).initLoggerAdapter(this); + final BeanRegistry beanRegistry = beanRegistryBuildService.get().getBeanRegistry(); + TaskLoggerInitializer.initAdapter(this, verboseModeEnabled.get(), + beanRegistry.getBean(GradleLoggerAdapter.class), beanRegistry.getBean(GradleSettings.class)); final Credentials distributionServerCredentials = nodeDistributionServerUsername .map(username -> Credentials @@ -335,10 +444,10 @@ public void execute() throws BeanRegistryException, FrontendException, IOExcepti .map(username -> Credentials.builder().username(username).password(httpsProxyPassword.get()).build()) .getOrNull(); - final Platform platform = Beans.getBean(beanRegistryId, PlatformProvider.class).getPlatform(); + final Platform platform = Platform.builder().jvmArch(systemJvmArch.get()).osName(systemOsName.get()).build(); getLogger().debug("Platform: {}", platform); - final ProxySettings proxySettings = Beans - .getBean(beanRegistryId, ResolveProxySettingsByUrl.class) + final ProxySettings proxySettings = beanRegistry + .getBean(ResolveProxySettingsByUrl.class) .execute(ResolveProxySettingsByUrlCommand .builder() .httpsProxyHost(httpsProxyHost.getOrNull()) @@ -348,9 +457,14 @@ public void execute() throws BeanRegistryException, FrontendException, IOExcepti .httpProxyPort(httpProxyPort.get()) .httpProxyCredentials(httpProxyCredentials) .resourceUrl(new URL(nodeDistributionUrlRoot.get())) + .systemHttpProxyHost(systemHttpProxyHost.getOrNull()) + .systemHttpProxyPort(systemHttpProxyPort.get()) + .systemHttpsProxyHost(systemHttpsProxyHost.getOrNull()) + .systemHttpsProxyPort(systemHttpsProxyPort.get()) + .systemNonProxyHosts(systemNonProxyHosts.get()) .build()); - Beans - .getBean(beanRegistryId, InstallNodeDistribution.class) + beanRegistry + .getBean(InstallNodeDistribution.class) .execute(InstallNodeDistributionCommand .builder() .platform(platform) diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTask.java index fae55213..36aa46ad 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/InstallPackageManagerTask.java @@ -5,7 +5,6 @@ import javax.inject.Inject; import org.gradle.api.GradleException; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.model.ObjectFactory; import org.gradle.api.tasks.InputFile; @@ -13,8 +12,8 @@ import org.gradle.process.ExecOperations; import org.siouan.frontendgradleplugin.domain.ExecutableType; import org.siouan.frontendgradleplugin.domain.FileManager; +import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistry; import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistryException; -import org.siouan.frontendgradleplugin.infrastructure.bean.Beans; /** * This task installs the relevant package manager for the current project (by executing command @@ -38,20 +37,10 @@ public class InstallPackageManagerTask extends AbstractRunCommandTask { private final RegularFileProperty packageManagerExecutableFile; @Inject - public InstallPackageManagerTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public InstallPackageManagerTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); this.executableType.set(ExecutableType.COREPACK); this.packageManagerSpecificationFile = objectFactory.fileProperty(); - this.script.set(packageManagerSpecificationFile.getAsFile().map(f -> { - try { - return String.join(" ", COREPACK_ENABLE_COMMAND, - Beans.getBean(beanRegistryId, FileManager.class).readString(f.toPath(), StandardCharsets.UTF_8) - .split("@")[0]); - } catch (final BeanRegistryException | IOException e) { - throw new GradleException(e.getClass().getName() + ": " + e.getMessage(), e); - } - })); this.packageManagerExecutableFile = objectFactory.fileProperty(); } @@ -64,4 +53,22 @@ public RegularFileProperty getPackageManagerSpecificationFile() { public RegularFileProperty getPackageManagerExecutableFile() { return packageManagerExecutableFile; } + + @Override + public void execute() throws NonRunnableTaskException, BeanRegistryException { + final BeanRegistry beanRegistry = beanRegistryBuildService.get().getBeanRegistry(); + + this.script.set(packageManagerSpecificationFile.getAsFile().map(f -> { + try { + return String.join(" ", COREPACK_ENABLE_COMMAND, beanRegistry + .getBean(FileManager.class) + .readString(f.toPath(), StandardCharsets.UTF_8) + .split("@")[0]); + } catch (final BeanRegistryException | IOException e) { + throw new GradleException(e.getClass().getName() + ": " + e.getMessage(), e); + } + })); + + super.execute(); + } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishTask.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishTask.java index b6b457f0..817355cc 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishTask.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/PublishTask.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -10,16 +9,13 @@ import org.gradle.process.ExecOperations; /** - * This task publishes frontend artifacts. - * - * @since 1.4.0 + * This task publishes project artifacts. */ public class PublishTask extends AbstractRunCommandTask { @Inject - public PublishTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public PublishTask(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); } @Input 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 0d3fdeb8..2d37654b 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 @@ -5,13 +5,14 @@ import javax.inject.Inject; import org.gradle.api.DefaultTask; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.Internal; +import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.PathSensitive; import org.gradle.api.tasks.PathSensitivity; @@ -19,12 +20,11 @@ import org.siouan.frontendgradleplugin.domain.InvalidJsonFileException; import org.siouan.frontendgradleplugin.domain.MalformedPackageManagerSpecification; import org.siouan.frontendgradleplugin.domain.Platform; -import org.siouan.frontendgradleplugin.domain.PlatformProvider; import org.siouan.frontendgradleplugin.domain.ResolvePackageManager; import org.siouan.frontendgradleplugin.domain.ResolvePackageManagerCommand; import org.siouan.frontendgradleplugin.domain.UnsupportedPackageManagerException; import org.siouan.frontendgradleplugin.infrastructure.bean.BeanInstanciationException; -import org.siouan.frontendgradleplugin.infrastructure.bean.Beans; +import org.siouan.frontendgradleplugin.infrastructure.bean.BeanRegistry; import org.siouan.frontendgradleplugin.infrastructure.bean.TooManyCandidateBeansException; import org.siouan.frontendgradleplugin.infrastructure.bean.ZeroOrMultiplePublicConstructorsException; @@ -38,9 +38,11 @@ public class ResolvePackageManagerTask extends DefaultTask { /** - * Bean registry ID. + * Bean registry service provider. + * + * @since 8.1.0 */ - private final String beanRegistryId; + protected final Property beanRegistryBuildService; /** * The 'package.json' file. @@ -53,7 +55,7 @@ public class ResolvePackageManagerTask extends DefaultTask { private final Property nodeInstallDirectory; /** - * File that will contain the specification of the package manager for the project. + * File that will contain the specification (name and version) of the package manager for the project. */ private final RegularFileProperty packageManagerSpecificationFile; @@ -62,17 +64,47 @@ public class ResolvePackageManagerTask extends DefaultTask { */ private final RegularFileProperty packageManagerExecutablePathFile; + /** + * Whether the task should produce log messages for the end-user. + * + * @since 8.1.0 + */ + private final Property verboseModeEnabled; + + /** + * Architecture of the underlying JVM. + * + * @since 8.1.0 + */ + private final Property systemJvmArch; + + /** + * System name of the O/S. + * + * @since 8.1.0 + */ + private final Property systemOsName; + @Inject - public ResolvePackageManagerTask(final ProjectLayout projectLayout, final ObjectFactory objectFactory) { - this.beanRegistryId = Beans.getBeanRegistryId(projectLayout.getProjectDirectory().toString()); + public ResolvePackageManagerTask(final ObjectFactory objectFactory) { + this.beanRegistryBuildService = objectFactory.property(BeanRegistryBuildService.class); this.packageJsonFile = objectFactory.fileProperty(); this.nodeInstallDirectory = objectFactory.property(File.class); this.packageManagerSpecificationFile = objectFactory.fileProperty(); this.packageManagerExecutablePathFile = objectFactory.fileProperty(); + this.verboseModeEnabled = objectFactory.property(Boolean.class); + this.systemJvmArch = objectFactory.property(String.class); + this.systemOsName = objectFactory.property(String.class); + } + + @Internal + public Property getBeanRegistryBuildService() { + return beanRegistryBuildService; } @InputFile @PathSensitive(PathSensitivity.ABSOLUTE) + @Optional public RegularFileProperty getPackageJsonFile() { return packageJsonFile; } @@ -82,6 +114,21 @@ public Property getNodeInstallDirectory() { return nodeInstallDirectory; } + @Internal + public Property getVerboseModeEnabled() { + return verboseModeEnabled; + } + + @Internal + public Property getSystemJvmArch() { + return systemJvmArch; + } + + @Internal + public Property getSystemOsName() { + return systemOsName; + } + @OutputFile public RegularFileProperty getPackageManagerSpecificationFile() { return packageManagerSpecificationFile; @@ -97,18 +144,20 @@ public void execute() throws BeanInstanciationException, TooManyCandidateBeansException, ZeroOrMultiplePublicConstructorsException, IOException, InvalidJsonFileException, MalformedPackageManagerSpecification, UnsupportedPackageManagerException { - Beans.getBean(beanRegistryId, TaskLoggerConfigurer.class).initLoggerAdapter(this); + final BeanRegistry beanRegistry = beanRegistryBuildService.get().getBeanRegistry(); + TaskLoggerInitializer.initAdapter(this, verboseModeEnabled.get(), + beanRegistry.getBean(GradleLoggerAdapter.class), beanRegistry.getBean(GradleSettings.class)); - final Platform platform = Beans.getBean(beanRegistryId, PlatformProvider.class).getPlatform(); + final Platform platform = Platform.builder().jvmArch(systemJvmArch.get()).osName(systemOsName.get()).build(); getLogger().debug("Platform: {}", platform); // Though it is not used by the plugin later, the version of the package manager is written in the specification // file so as other tasks using this file as an input are re-executed if the package manager is upgraded (same // package manager, different version). - Beans - .getBean(beanRegistryId, ResolvePackageManager.class) + beanRegistry + .getBean(ResolvePackageManager.class) .execute(ResolvePackageManagerCommand .builder() - .packageJsonFilePath(packageJsonFile.getAsFile().get().toPath()) + .packageJsonFilePath(packageJsonFile.getAsFile().map(File::toPath).getOrNull()) .nodeInstallDirectoryPath(nodeInstallDirectory.map(File::toPath).get()) .platform(platform) .packageManagerSpecificationFilePath(packageManagerSpecificationFile.getAsFile().get().toPath()) diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunCorepack.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunCorepack.java index 28da0232..ddfaa2bc 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunCorepack.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunCorepack.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -25,12 +24,11 @@ * * @since 7.0.0 */ -public class RunCorepack extends AbstractRunCommandTaskType { +public abstract class RunCorepack extends AbstractRunCommandTaskType { @Inject - public RunCorepack(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public RunCorepack(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); this.executableType.set(ExecutableType.COREPACK); } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNode.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNode.java index 606f98c6..c5b1b760 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNode.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNode.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -25,12 +24,11 @@ * * @since 1.2.0 */ -public class RunNode extends AbstractRunCommandTaskType { +public abstract class RunNode extends AbstractRunCommandTaskType { @Inject - public RunNode(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public RunNode(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); executableType.set(ExecutableType.NODE); } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNpm.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNpm.java index f3f672cf..e1755bf1 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNpm.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunNpm.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -25,12 +24,11 @@ * * @since 6.0.0 */ -public class RunNpm extends AbstractRunCommandTaskType { +public abstract class RunNpm extends AbstractRunCommandTaskType { @Inject - public RunNpm(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public RunNpm(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); executableType.set(ExecutableType.NPM); } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunPnpm.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunPnpm.java index a0882cdc..22e40d3e 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunPnpm.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunPnpm.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -25,12 +24,11 @@ * * @since 7.0.0 */ -public class RunPnpm extends AbstractRunCommandTaskType { +public abstract class RunPnpm extends AbstractRunCommandTaskType { @Inject - public RunPnpm(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public RunPnpm(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); executableType.set(ExecutableType.PNPM); } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunYarn.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunYarn.java index fb0c8817..98f16901 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunYarn.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/RunYarn.java @@ -2,7 +2,6 @@ import javax.inject.Inject; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -25,12 +24,11 @@ * * @since 6.0.0 */ -public class RunYarn extends AbstractRunCommandTaskType { +public abstract class RunYarn extends AbstractRunCommandTaskType { @Inject - public RunYarn(final ProjectLayout projectLayout, final ObjectFactory objectFactory, - final ExecOperations execOperations) { - super(projectLayout, objectFactory, execOperations); + public RunYarn(final ObjectFactory objectFactory, final ExecOperations execOperations) { + super(objectFactory, execOperations); executableType.set(ExecutableType.YARN); } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ScriptProperties.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ScriptProperties.java index adee57b4..719910ca 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ScriptProperties.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ScriptProperties.java @@ -1,6 +1,7 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; import java.nio.file.Path; +import java.util.Map; import lombok.Builder; import lombok.Getter; @@ -46,4 +47,23 @@ public class ScriptProperties { * Underlying platform. */ private final Platform platform; + + /** + * Additional environment variables to pass to the process. + * + * @since 8.1.0 + */ + private final Map environmentVariables; + + ScriptProperties(final ExecOperations execOperations, final Path packageJsonDirectoryPath, + final ExecutableType executableType, final Path nodeInstallDirectoryPath, final String script, + final Platform platform, final Map environmentVariables) { + this.execOperations = execOperations; + this.packageJsonDirectoryPath = packageJsonDirectoryPath; + this.executableType = executableType; + this.nodeInstallDirectoryPath = nodeInstallDirectoryPath; + this.script = script; + this.platform = platform; + this.environmentVariables = Map.copyOf(environmentVariables); + } } diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemExtension.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemExtension.java deleted file mode 100644 index 29113126..00000000 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemExtension.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.gradle; - -import org.gradle.api.provider.Provider; -import org.gradle.api.provider.ProviderFactory; -import org.siouan.frontendgradleplugin.domain.SystemProperties; - -/** - * Extension providing system settings. - * - * @since 5.2.0 - */ -public class SystemExtension { - - /** - * Proxy host used to download resources with HTTP protocol. - */ - private final Provider httpProxyHost; - - /** - * Proxy port used to download resources with HTTP protocol. - */ - private final Provider httpProxyPort; - - /** - * Proxy host used to download resources with HTTPS protocol. - */ - private final Provider httpsProxyHost; - - /** - * Proxy port used to download resources with HTTPS protocol. - */ - private final Provider httpsProxyPort; - - private final Provider nonProxyHosts; - - private final Provider jvmArch; - - private final Provider osName; - - public SystemExtension(final ProviderFactory providerFactory) { - this.httpProxyHost = providerFactory.systemProperty(SystemProperties.HTTP_PROXY_HOST); - this.httpProxyPort = providerFactory.systemProperty(SystemProperties.HTTP_PROXY_PORT); - this.httpsProxyHost = providerFactory.systemProperty(SystemProperties.HTTPS_PROXY_HOST); - this.httpsProxyPort = providerFactory.systemProperty(SystemProperties.HTTPS_PROXY_PORT); - this.nonProxyHosts = providerFactory.systemProperty(SystemProperties.NON_PROXY_HOSTS); - this.jvmArch = providerFactory.systemProperty(SystemProperties.JVM_ARCH_PROPERTY); - this.osName = providerFactory.systemProperty(SystemProperties.OS_NAME_PROPERTY); - } - - public Provider getHttpProxyHost() { - return httpProxyHost; - } - - public Provider getHttpProxyPort() { - return httpProxyPort; - } - - public Provider getHttpsProxyHost() { - return httpsProxyHost; - } - - public Provider getHttpsProxyPort() { - return httpsProxyPort; - } - - public Provider getNonProxyHosts() { - return nonProxyHosts; - } - - public Provider getJvmArch() { - return jvmArch; - } - - public Provider getOsName() { - return osName; - } -} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemProviders.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemProviders.java new file mode 100644 index 00000000..b5d6c62c --- /dev/null +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemProviders.java @@ -0,0 +1,54 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import lombok.Getter; +import org.gradle.api.provider.Provider; +import org.gradle.api.provider.ProviderFactory; +import org.siouan.frontendgradleplugin.domain.SystemProperties; + +/** + * Providers for system properties. + * + * @since 8.1.0 + */ +@Getter +public class SystemProviders { + + /** + * Proxy host used to download resources with HTTP protocol. + */ + private final Provider httpProxyHost; + + /** + * Proxy port used to download resources with HTTP protocol. + */ + private final Provider httpProxyPort; + + /** + * Proxy host used to download resources with HTTPS protocol. + */ + private final Provider httpsProxyHost; + + /** + * Proxy port used to download resources with HTTPS protocol. + */ + private final Provider httpsProxyPort; + + /** + * List of hosts that should be reached directly, bypassing the proxy. + */ + private final Provider nonProxyHosts; + + private final Provider jvmArch; + + private final Provider osName; + + public SystemProviders(final ProviderFactory providerFactory) { + httpProxyHost = providerFactory.systemProperty(SystemProperties.HTTP_PROXY_HOST); + httpProxyPort = providerFactory.systemProperty(SystemProperties.HTTP_PROXY_PORT); + httpsProxyHost = providerFactory.systemProperty(SystemProperties.HTTPS_PROXY_HOST); + httpsProxyPort = providerFactory.systemProperty(SystemProperties.HTTPS_PROXY_PORT); + nonProxyHosts = providerFactory.systemProperty(SystemProperties.NON_PROXY_HOSTS); + jvmArch = providerFactory.systemProperty(SystemProperties.JVM_ARCH); + osName = providerFactory.systemProperty(SystemProperties.OS_NAME); + } +} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemSettingsProviderImpl.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemSettingsProviderImpl.java deleted file mode 100644 index d325e032..00000000 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemSettingsProviderImpl.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.gradle; - -import java.util.Optional; -import java.util.Set; -import java.util.function.Predicate; - -import org.gradle.api.provider.Provider; -import org.siouan.frontendgradleplugin.domain.SystemProperties; -import org.siouan.frontendgradleplugin.domain.SystemSettingsProvider; - -/** - * System-wide proxy settings. - * - * @since 5.2.0 - */ -public class SystemSettingsProviderImpl implements SystemSettingsProvider { - - private final Provider httpProxyHost; - - private final Provider httpProxyPort; - - private final Provider httpsProxyHost; - - private final Provider httpsProxyPort; - - private final Provider nonProxyHosts; - - private final Provider jvmArch; - - private final Provider osName; - - private final int defaultHttpProxyPort; - - private final int defaultHttpsProxyPort; - - public SystemSettingsProviderImpl(final SystemExtension systemExtension, final int defaultHttpProxyPort, - final int defaultHttpsProxyPort) { - this.httpProxyHost = systemExtension.getHttpProxyHost(); - this.httpProxyPort = systemExtension.getHttpProxyPort(); - this.httpsProxyHost = systemExtension.getHttpsProxyHost(); - this.httpsProxyPort = systemExtension.getHttpsProxyPort(); - this.nonProxyHosts = systemExtension.getNonProxyHosts(); - this.jvmArch = systemExtension.getJvmArch(); - this.osName = systemExtension.getOsName(); - this.defaultHttpProxyPort = defaultHttpProxyPort; - this.defaultHttpsProxyPort = defaultHttpsProxyPort; - } - - @Override - public String getHttpProxyHost() { - return httpProxyHost.getOrNull(); - } - - @Override - public int getHttpProxyPort() { - return Optional - .ofNullable(httpProxyPort.getOrNull()) - .filter(port -> !port.isBlank()) - .map(Integer::parseInt) - .orElse(defaultHttpProxyPort); - } - - @Override - public String getHttpsProxyHost() { - return httpsProxyHost.getOrNull(); - } - - @Override - public int getHttpsProxyPort() { - return Optional - .ofNullable(httpsProxyPort.getOrNull()) - .filter(port -> !port.isBlank()) - .map(Integer::parseInt) - .orElse(defaultHttpsProxyPort); - } - - @Override - public Set getNonProxyHosts() { - return Optional - .ofNullable(nonProxyHosts.getOrNull()) - .filter(Predicate.not(String::isBlank)) - .map(hosts -> hosts.split(SystemProperties.NON_PROXY_HOSTS_SPLIT_PATTERN)) - .map(Set::of) - .orElseGet(Set::of); - } - - @Override - public String getSystemJvmArch() { - return jvmArch.get(); - } - - @Override - public String getSystemOsName() { - return osName.get(); - } -} diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerConfigurer.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerInitializer.java similarity index 64% rename from plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerConfigurer.java rename to plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerInitializer.java index 4b03da9e..939be719 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerConfigurer.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerInitializer.java @@ -1,5 +1,7 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.gradle.api.Task; import org.gradle.api.logging.LogLevel; import org.gradle.api.logging.LoggingManager; @@ -9,27 +11,15 @@ * * @since 2.0.0 */ -public class TaskLoggerConfigurer { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class TaskLoggerInitializer { - private final FrontendExtension extension; - - private final GradleLoggerAdapter gradleLoggerAdapter; - - private final GradleSettings gradleSettings; - - public TaskLoggerConfigurer(final FrontendExtension extension, final GradleLoggerAdapter gradleLoggerAdapter, - final GradleSettings gradleSettings) { - this.extension = extension; - this.gradleLoggerAdapter = gradleLoggerAdapter; - this.gradleSettings = gradleSettings; - } - - public void initLoggerAdapter(final Task task) { + public static void initAdapter(final Task task, final boolean verboseModeEnabled, + final GradleLoggerAdapter gradleLoggerAdapter, final GradleSettings gradleSettings) { task .getLogger() - .debug("Configuring logger for task '{}': verboseModeEnabled={}", task.getName(), - extension.getVerboseModeEnabled().get()); - gradleLoggerAdapter.init(task.getLogger(), resolveLogLevel(task), extension.getVerboseModeEnabled().get(), + .debug("Configuring logger for task '{}': verboseModeEnabled={}", task.getName(), verboseModeEnabled); + gradleLoggerAdapter.init(task.getLogger(), resolveLogLevel(task, gradleSettings), verboseModeEnabled, '[' + task.getName() + "] "); } @@ -42,7 +32,7 @@ public void initLoggerAdapter(final Task task) { * @param task Task. * @return Logging level. */ - private LogLevel resolveLogLevel(final Task task) { + private static LogLevel resolveLogLevel(final Task task, final GradleSettings gradleSettings) { LogLevel loggingLevel = task.getLogging().getLevel(); if (loggingLevel != null) { return loggingLevel; diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/httpclient/HttpClientProviderImpl.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/httpclient/HttpClientProviderImpl.java index 32a7efe0..c95cb58c 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/httpclient/HttpClientProviderImpl.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/httpclient/HttpClientProviderImpl.java @@ -1,5 +1,7 @@ package org.siouan.frontendgradleplugin.infrastructure.httpclient; +import java.io.Serializable; + import org.siouan.frontendgradleplugin.domain.installer.HttpClient; import org.siouan.frontendgradleplugin.domain.installer.HttpClientProvider; @@ -8,10 +10,12 @@ * * @since 4.0.1 */ -public class HttpClientProviderImpl implements HttpClientProvider { +public class HttpClientProviderImpl implements HttpClientProvider, Serializable { private static final HttpClient INSTANCE = new ApacheHttpClient(); + private static final long serialVersionUID = -5442300705570408127L; + @Override public HttpClient getInstance() { return INSTANCE; diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/ChannelProviderImpl.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/ChannelProviderImpl.java index 566a3a28..4f90d5e2 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/ChannelProviderImpl.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/ChannelProviderImpl.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; @@ -17,7 +18,9 @@ * * @since 2.0.0 */ -public class ChannelProviderImpl implements ChannelProvider { +public class ChannelProviderImpl implements ChannelProvider, Serializable { + + private static final long serialVersionUID = -5977105709250111639L; @Override public ReadableByteChannel getReadableByteChannel(final InputStream inputStream) { diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/FileManagerImpl.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/FileManagerImpl.java index 5321c207..7750dc30 100644 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/FileManagerImpl.java +++ b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/FileManagerImpl.java @@ -30,6 +30,8 @@ */ public class FileManagerImpl implements FileManager { + private static final long serialVersionUID = -4492951623732511344L; + @Override public long copy(final InputStream inputStream, final Path filePath) throws IOException { return Files.copy(inputStream, filePath); diff --git a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/PlatformProviderImpl.java b/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/PlatformProviderImpl.java deleted file mode 100644 index 4c996c6d..00000000 --- a/plugin/src/main/java/org/siouan/frontendgradleplugin/infrastructure/system/PlatformProviderImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.system; - -import lombok.RequiredArgsConstructor; -import org.siouan.frontendgradleplugin.domain.Platform; -import org.siouan.frontendgradleplugin.domain.PlatformProvider; -import org.siouan.frontendgradleplugin.domain.SystemSettingsProvider; - -/** - * Implementation of a platform provider. - * - * @since 7.0.0 - */ -@RequiredArgsConstructor -public class PlatformProviderImpl implements PlatformProvider { - - private final SystemSettingsProvider systemSettingsProvider; - - @Override - public Platform getPlatform() { - return Platform - .builder() - .jvmArch(systemSettingsProvider.getSystemJvmArch()) - .osName(systemSettingsProvider.getSystemOsName()) - .build(); - } -} diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/FrontendGradlePluginTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/FrontendGradlePluginTest.java index cd4d63a8..b57a4b13 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/FrontendGradlePluginTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/FrontendGradlePluginTest.java @@ -1,11 +1,22 @@ package org.siouan.frontendgradleplugin; import static org.assertj.core.api.Assertions.assertThat; +import static org.siouan.frontendgradleplugin.FrontendGradlePlugin.*; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.HTTPS_PROXY_HOST; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.HTTPS_PROXY_PORT; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.HTTP_PROXY_HOST; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.HTTP_PROXY_PORT; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.JVM_ARCH; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.NON_PROXY_HOSTS; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.NON_PROXY_HOSTS_SPLIT_PATTERN; +import static org.siouan.frontendgradleplugin.domain.SystemProperties.OS_NAME; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import org.gradle.api.Project; @@ -17,11 +28,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junitpioneer.jupiter.SetSystemProperty; import org.mockito.junit.jupiter.MockitoExtension; import org.siouan.frontendgradleplugin.infrastructure.gradle.AssembleTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.CheckTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.CleanTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.FrontendExtension; +import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallCorepackTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallFrontendTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallNodeTask; import org.siouan.frontendgradleplugin.infrastructure.gradle.InstallPackageManagerTask; @@ -46,7 +59,7 @@ void setUp() { @Test void should_register_tasks_with_default_extension_values_applied() throws IOException { - Files.createDirectory(project.file(FrontendGradlePlugin.DEFAULT_NODE_INSTALL_DIRECTORY_NAME).toPath()); + Files.createDirectory(project.file(DEFAULT_NODE_INSTALL_DIRECTORY_NAME).toPath()); plugin.apply(project); final FrontendExtension extension = Objects.requireNonNull( @@ -54,61 +67,59 @@ void should_register_tasks_with_default_extension_values_applied() throws IOExce assertThat(extension.getNodeDistributionProvided().get()).isFalse(); assertThat(extension.getNodeVersion().isPresent()).isFalse(); - assertThat(extension.getNodeInstallDirectory().getAsFile().get()).isEqualTo(project - .getLayout() - .getProjectDirectory() - .dir(FrontendGradlePlugin.DEFAULT_NODE_INSTALL_DIRECTORY_NAME) - .getAsFile()); - assertThat(extension.getNodeDistributionUrlRoot().get()).isEqualTo( - FrontendGradlePlugin.DEFAULT_NODE_DISTRIBUTION_URL_ROOT); + assertThat(extension.getNodeInstallDirectory().getAsFile().get()).isEqualTo( + project.getLayout().getProjectDirectory().dir(DEFAULT_NODE_INSTALL_DIRECTORY_NAME).getAsFile()); + assertThat(extension.getNodeDistributionUrlRoot().get()).isEqualTo(DEFAULT_NODE_DISTRIBUTION_URL_ROOT); assertThat(extension.getNodeDistributionUrlPathPattern().get()).isEqualTo( - FrontendGradlePlugin.DEFAULT_NODE_DISTRIBUTION_URL_PATH_PATTERN); + DEFAULT_NODE_DISTRIBUTION_URL_PATH_PATTERN); assertThat(extension.getNodeDistributionServerUsername().isPresent()).isFalse(); assertThat(extension.getNodeDistributionServerPassword().isPresent()).isFalse(); - assertThat(extension.getInstallScript().get()).isEqualTo(FrontendGradlePlugin.DEFAULT_INSTALL_SCRIPT); + assertThat(extension.getCorepackVersion().isPresent()).isFalse(); + assertThat(extension.getInstallScript().get()).isEqualTo(DEFAULT_INSTALL_SCRIPT); assertThat(extension.getCleanScript().isPresent()).isFalse(); assertThat(extension.getAssembleScript().isPresent()).isFalse(); assertThat(extension.getCheckScript().isPresent()).isFalse(); assertThat(extension.getPublishScript().isPresent()).isFalse(); assertThat(extension.getPackageJsonDirectory().getAsFile().get()).isEqualTo(project.getProjectDir()); assertThat(extension.getHttpProxyHost().isPresent()).isFalse(); - assertThat(extension.getHttpProxyPort().get()).isEqualTo(FrontendGradlePlugin.DEFAULT_HTTP_PROXY_PORT); + assertThat(extension.getHttpProxyPort().get()).isEqualTo(DEFAULT_HTTP_PROXY_PORT); assertThat(extension.getHttpProxyUsername().isPresent()).isFalse(); assertThat(extension.getHttpProxyPassword().isPresent()).isFalse(); assertThat(extension.getHttpsProxyHost().isPresent()).isFalse(); - assertThat(extension.getHttpsProxyPort().get()).isEqualTo(FrontendGradlePlugin.DEFAULT_HTTPS_PROXY_PORT); + assertThat(extension.getHttpsProxyPort().get()).isEqualTo(DEFAULT_HTTPS_PROXY_PORT); assertThat(extension.getHttpsProxyUsername().isPresent()).isFalse(); assertThat(extension.getHttpsProxyPassword().isPresent()).isFalse(); - assertThat(extension.getMaxDownloadAttempts().get()).isEqualTo( - FrontendGradlePlugin.DEFAULT_MAX_DOWNLOAD_ATTEMPTS); + assertThat(extension.getMaxDownloadAttempts().get()).isEqualTo(DEFAULT_MAX_DOWNLOAD_ATTEMPTS); assertThat(extension.getRetryHttpStatuses().get()).containsExactlyInAnyOrderElementsOf( - FrontendGradlePlugin.DEFAULT_RETRY_HTTP_STATUSES); - assertThat(extension.getRetryInitialIntervalMs().get()).isEqualTo( - FrontendGradlePlugin.DEFAULT_RETRY_INITIAL_INTERVAL_MS); - assertThat(extension.getRetryIntervalMultiplier().get()).isEqualTo( - FrontendGradlePlugin.DEFAULT_RETRY_INTERVAL_MULTIPLIER); - assertThat(extension.getRetryMaxIntervalMs().get()).isEqualTo( - FrontendGradlePlugin.DEFAULT_RETRY_MAX_INTERVAL_MS); - assertThat(extension.getInternalPackageManagerSpecificationFile().getAsFile().get()).isEqualTo(project - .getProjectDir() - .toPath() - .resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_SPECIFICATION_FILE_NAME)) - .toFile()); - assertThat(extension.getInternalPackageManagerExecutablePathFile().getAsFile().get()).isEqualTo(project - .getProjectDir() - .toPath() - .resolve(Paths.get(FrontendGradlePlugin.DEFAULT_CACHE_DIRECTORY_NAME, - FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, - FrontendGradlePlugin.PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME)) - .toFile()); + DEFAULT_RETRY_HTTP_STATUSES); + assertThat(extension.getRetryInitialIntervalMs().get()).isEqualTo(DEFAULT_RETRY_INITIAL_INTERVAL_MS); + assertThat(extension.getRetryIntervalMultiplier().get()).isEqualTo(DEFAULT_RETRY_INTERVAL_MULTIPLIER); + assertThat(extension.getRetryMaxIntervalMs().get()).isEqualTo(DEFAULT_RETRY_MAX_INTERVAL_MS); + assertThat(extension.getCacheDirectory().getAsFile().get()).isEqualTo( + project.getLayout().getProjectDirectory().dir(DEFAULT_CACHE_DIRECTORY_NAME).getAsFile()); assertThat(extension.getVerboseModeEnabled().get()).isFalse(); - assertThatTasksAreConfigured(project, extension); + final Map expectedSystemProperties = new HashMap<>(); + Set + .of(HTTP_PROXY_HOST, HTTP_PROXY_PORT, HTTPS_PROXY_HOST, HTTPS_PROXY_PORT, NON_PROXY_HOSTS, JVM_ARCH, + OS_NAME) + .forEach(systemPropertyName -> { + final String systemPropertyValue = System.getProperty(systemPropertyName); + if (systemPropertyValue != null) { + expectedSystemProperties.put(systemPropertyName, systemPropertyValue); + } + }); + assertThatTasksAreConfigured(project, extension, expectedSystemProperties); } @Test + @SetSystemProperty(key = HTTP_PROXY_HOST, value = "104.53.49.1") + @SetSystemProperty(key = HTTP_PROXY_PORT, value = "52") + @SetSystemProperty(key = HTTPS_PROXY_HOST, value = "239.19.0.5") + @SetSystemProperty(key = HTTPS_PROXY_PORT, value = "492") + @SetSystemProperty(key = NON_PROXY_HOSTS, value = "localhost|48.8.*|127.0.0.1") + @SetSystemProperty(key = JVM_ARCH, value = "x86 64 bits") + @SetSystemProperty(key = OS_NAME, value = "FreeOS") void should_register_tasks_with_custom_extension_values_applied() throws IOException { final String nodeInstallDirectoryName = "node-dist"; Files.createDirectory(project.file(nodeInstallDirectoryName).toPath()); @@ -121,6 +132,7 @@ void should_register_tasks_with_custom_extension_values_applied() throws IOExcep extension.getNodeDistributionUrlRoot().set("https://node"); extension.getNodeDistributionUrlPathPattern().set("/node.tar.gz"); extension.getNodeInstallDirectory().set(project.file(nodeInstallDirectoryName)); + extension.getCorepackVersion().set("latest"); extension.getInstallScript().set("run ci"); extension.getCleanScript().set("run clean"); extension.getAssembleScript().set("run build"); @@ -140,17 +152,23 @@ void should_register_tasks_with_custom_extension_values_applied() throws IOExcep extension.getRetryInitialIntervalMs().set(539); extension.getRetryIntervalMultiplier().set(7.3); extension.getRetryMaxIntervalMs().set(9623); + extension.getRetryMaxIntervalMs().set(9623); + extension.getCacheDirectory().set(project.file("cache")); extension.getVerboseModeEnabled().set(true); - assertThatTasksAreConfigured(project, extension); + assertThatTasksAreConfigured(project, extension, + Map.of(HTTP_PROXY_HOST, "104.53.49.1", HTTP_PROXY_PORT, "52", HTTPS_PROXY_HOST, "239.19.0.5", + HTTPS_PROXY_PORT, "492", NON_PROXY_HOSTS, "localhost|48.8.*|127.0.0.1", JVM_ARCH, "x86 64 bits", + OS_NAME, "FreeOS")); } - private void assertThatTasksAreConfigured(final Project project, final FrontendExtension extension) { - + private void assertThatTasksAreConfigured(final Project project, final FrontendExtension extension, + final Map expectedSystemProperties) { final InstallNodeTask installNodeTask = project .getTasks() - .named(FrontendGradlePlugin.INSTALL_NODE_TASK_NAME, InstallNodeTask.class) + .named(INSTALL_NODE_TASK_NAME, InstallNodeTask.class) .get(); + assertThat(installNodeTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); assertThat(installNodeTask.getNodeVersion().getOrNull()).isEqualTo(extension.getNodeVersion().getOrNull()); assertThat(installNodeTask.getNodeDistributionUrlRoot().get()).isEqualTo( extension.getNodeDistributionUrlRoot().get()); @@ -184,96 +202,184 @@ private void assertThatTasksAreConfigured(final Project project, final FrontendE extension.getRetryIntervalMultiplier().getOrNull()); assertThat(installNodeTask.getRetryMaxIntervalMs().getOrNull()).isEqualTo( extension.getRetryMaxIntervalMs().getOrNull()); + assertThat(installNodeTask.getVerboseModeEnabled().get()).isEqualTo(extension.getVerboseModeEnabled().get()); + assertThat(installNodeTask.getSystemHttpProxyHost().getOrNull()).isEqualTo( + expectedSystemProperties.get(HTTP_PROXY_HOST)); + assertThat(installNodeTask.getSystemHttpProxyPort().get()).isEqualTo(Optional + .ofNullable(expectedSystemProperties.get(HTTP_PROXY_PORT)) + .map(Integer::parseInt) + .orElse(DEFAULT_HTTP_PROXY_PORT)); + assertThat(installNodeTask.getSystemHttpsProxyHost().getOrNull()).isEqualTo( + expectedSystemProperties.get(HTTPS_PROXY_HOST)); + assertThat(installNodeTask.getSystemHttpsProxyPort().get()).isEqualTo(Optional + .ofNullable(expectedSystemProperties.get(HTTPS_PROXY_PORT)) + .map(Integer::parseInt) + .orElse(DEFAULT_HTTPS_PROXY_PORT)); + assertThat(installNodeTask.getSystemNonProxyHosts().get()).isEqualTo(Optional + .ofNullable(expectedSystemProperties.get(NON_PROXY_HOSTS)) + .map(nonProxyHosts -> Set.of(nonProxyHosts.split(NON_PROXY_HOSTS_SPLIT_PATTERN))) + .orElseGet(Set::of)); + assertThat(installNodeTask.getSystemJvmArch().get()).isEqualTo(expectedSystemProperties.get(JVM_ARCH)); + assertThat(installNodeTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); assertThat(installNodeTask.getDependsOn()).isEmpty(); + final InstallCorepackTask installCorepackTask = project + .getTasks() + .named(INSTALL_COREPACK_TASK_NAME, InstallCorepackTask.class) + .get(); + assertThat(installCorepackTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); + assertThat(installCorepackTask.getPackageJsonDirectory().get()).isEqualTo( + extension.getPackageJsonDirectory().getAsFile().get()); + assertThat(installCorepackTask.getNodeInstallDirectory().get()).isEqualTo( + extension.getNodeInstallDirectory().getAsFile().get()); + assertThat(installCorepackTask.getCorepackVersion().getOrNull()).isEqualTo( + extension.getCorepackVersion().getOrNull()); + assertThat(installCorepackTask.getVerboseModeEnabled().get()).isEqualTo( + extension.getVerboseModeEnabled().get()); + assertThat(installCorepackTask.getSystemJvmArch().get()).isEqualTo(expectedSystemProperties.get(JVM_ARCH)); + assertThat(installCorepackTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); + assertThat(installCorepackTask.getDependsOn()).containsExactlyInAnyOrder(INSTALL_NODE_TASK_NAME); + final ResolvePackageManagerTask resolvePackageManagerTask = project .getTasks() - .named(FrontendGradlePlugin.RESOLVE_PACKAGE_MANAGER_TASK_NAME, ResolvePackageManagerTask.class) + .named(RESOLVE_PACKAGE_MANAGER_TASK_NAME, ResolvePackageManagerTask.class) .get(); - assertThat(resolvePackageManagerTask.getPackageJsonFile().getAsFile().get()).isEqualTo(extension + assertThat(resolvePackageManagerTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); + assertThat(resolvePackageManagerTask.getPackageJsonFile().getAsFile().getOrNull()).isEqualTo(extension .getPackageJsonDirectory() - .file(FrontendGradlePlugin.PACKAGE_JSON_FILE_NAME) + .file(PACKAGE_JSON_FILE_NAME) .map(RegularFile::getAsFile) + .filter(packageJsonFile -> Files.isRegularFile(packageJsonFile.toPath())) + .getOrNull()); + assertThat(resolvePackageManagerTask.getNodeInstallDirectory().get()).isEqualTo( + extension.getNodeInstallDirectory().getAsFile().get()); + assertThat(resolvePackageManagerTask.getPackageManagerSpecificationFile().getAsFile().get()).isEqualTo(extension + .getCacheDirectory() + .dir(RESOLVE_PACKAGE_MANAGER_TASK_NAME) + .map(directory -> directory.file(PACKAGE_MANAGER_SPECIFICATION_FILE_NAME).getAsFile()) .get()); - assertThat(resolvePackageManagerTask.getNodeInstallDirectory().isPresent()).isTrue(); - assertThat(resolvePackageManagerTask.getPackageManagerSpecificationFile().getAsFile().get()).isEqualTo( - extension.getInternalPackageManagerSpecificationFile().getAsFile().get()); assertThat(resolvePackageManagerTask.getPackageManagerExecutablePathFile().getAsFile().get()).isEqualTo( - extension.getInternalPackageManagerExecutablePathFile().getAsFile().get()); - assertThat(installNodeTask.getDependsOn()).isEmpty(); - assertThat(resolvePackageManagerTask.getDependsOn()).containsExactlyInAnyOrder( - FrontendGradlePlugin.INSTALL_NODE_TASK_NAME); + extension + .getCacheDirectory() + .dir(RESOLVE_PACKAGE_MANAGER_TASK_NAME) + .map(directory -> directory.file(PACKAGE_MANAGER_EXECUTABLE_PATH_FILE_NAME).getAsFile()) + .get()); + assertThat(resolvePackageManagerTask.getVerboseModeEnabled().get()).isEqualTo( + extension.getVerboseModeEnabled().get()); + assertThat(resolvePackageManagerTask.getSystemJvmArch().get()).isEqualTo( + expectedSystemProperties.get(JVM_ARCH)); + assertThat(resolvePackageManagerTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); + assertThat(resolvePackageManagerTask.getDependsOn()).containsExactlyInAnyOrder(INSTALL_NODE_TASK_NAME); final InstallPackageManagerTask installPackageManagerTask = project .getTasks() - .named(FrontendGradlePlugin.INSTALL_PACKAGE_MANAGER_TASK_NAME, InstallPackageManagerTask.class) + .named(INSTALL_PACKAGE_MANAGER_TASK_NAME, InstallPackageManagerTask.class) .get(); + assertThat(installPackageManagerTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); assertThat(installPackageManagerTask.getPackageJsonDirectory().get()).isEqualTo( extension.getPackageJsonDirectory().getAsFile().get()); - assertThat(installPackageManagerTask.getNodeInstallDirectory().isPresent()).isTrue(); + assertThat(installPackageManagerTask.getNodeInstallDirectory().get()).isEqualTo( + extension.getNodeInstallDirectory().getAsFile().get()); assertThat(installPackageManagerTask.getPackageManagerSpecificationFile().getAsFile().get()).isEqualTo( - extension.getInternalPackageManagerSpecificationFile().getAsFile().get()); - assertThat(installPackageManagerTask.getDependsOn()).isEmpty(); + resolvePackageManagerTask.getPackageManagerSpecificationFile().getAsFile().get()); + //installPackageManagerTask.getPackageManagerExecutableFile() + assertThat(installPackageManagerTask.getVerboseModeEnabled().get()).isEqualTo( + extension.getVerboseModeEnabled().get()); + assertThat(installPackageManagerTask.getSystemJvmArch().get()).isEqualTo( + expectedSystemProperties.get(JVM_ARCH)); + assertThat(installPackageManagerTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); + assertThat(installPackageManagerTask.getDependsOn()).containsExactlyInAnyOrder(INSTALL_COREPACK_TASK_NAME); final InstallFrontendTask installFrontendTask = project .getTasks() - .named(FrontendGradlePlugin.INSTALL_FRONTEND_TASK_NAME, InstallFrontendTask.class) + .named(INSTALL_FRONTEND_TASK_NAME, InstallFrontendTask.class) .get(); + assertThat(installFrontendTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); assertThat(installFrontendTask.getPackageJsonDirectory().get()).isEqualTo( extension.getPackageJsonDirectory().getAsFile().get()); - assertThat(installFrontendTask.getNodeInstallDirectory().isPresent()).isTrue(); + assertThat(installFrontendTask.getNodeInstallDirectory().get()).isEqualTo( + extension.getNodeInstallDirectory().getAsFile().get()); + //installFrontendTask.getPackageManagerExecutableFile() assertThat(installFrontendTask.getInstallScript().get()).isEqualTo(extension.getInstallScript().get()); + assertThat(installFrontendTask.getVerboseModeEnabled().get()).isEqualTo( + extension.getVerboseModeEnabled().get()); + assertThat(installFrontendTask.getSystemJvmArch().get()).isEqualTo(expectedSystemProperties.get(JVM_ARCH)); + assertThat(installFrontendTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); assertThat(installFrontendTask.getDependsOn()).containsExactlyInAnyOrder(installPackageManagerTask.getName()); - final CleanTask frontendCleanTask = project + final CleanTask cleanFrontendTask = project .getTasks() - .named(FrontendGradlePlugin.CLEAN_TASK_NAME, CleanTask.class) + .named(CLEAN_TASK_NAME, CleanTask.class) .get(); - assertThat(frontendCleanTask.getPackageJsonDirectory().get()).isEqualTo( + assertThat(cleanFrontendTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); + assertThat(cleanFrontendTask.getPackageJsonDirectory().get()).isEqualTo( extension.getPackageJsonDirectory().getAsFile().get()); - assertThat(frontendCleanTask.getNodeInstallDirectory().isPresent()).isTrue(); - assertThat(frontendCleanTask.getCleanScript().getOrNull()).isEqualTo(extension.getCleanScript().getOrNull()); - assertThat(frontendCleanTask.getDependsOn()).containsExactlyInAnyOrder(installFrontendTask.getName()); + assertThat(cleanFrontendTask.getNodeInstallDirectory().get()).isEqualTo( + extension.getNodeInstallDirectory().getAsFile().get()); + //frontendCleanTask.getPackageManagerExecutableFile() + assertThat(cleanFrontendTask.getCleanScript().getOrNull()).isEqualTo(extension.getCleanScript().getOrNull()); + assertThat(cleanFrontendTask.getVerboseModeEnabled().get()).isEqualTo(extension.getVerboseModeEnabled().get()); + assertThat(cleanFrontendTask.getSystemJvmArch().get()).isEqualTo(expectedSystemProperties.get(JVM_ARCH)); + assertThat(cleanFrontendTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); + assertThat(cleanFrontendTask.getDependsOn()).containsExactlyInAnyOrder(installFrontendTask.getName()); assertThat(project.getTasks().named(BasePlugin.CLEAN_TASK_NAME).get().getDependsOn()).contains( - frontendCleanTask.getName()); + cleanFrontendTask.getName()); - final AssembleTask frontendAssembleTask = project + final AssembleTask assembleFrontendTask = project .getTasks() - .named(FrontendGradlePlugin.ASSEMBLE_TASK_NAME, AssembleTask.class) + .named(ASSEMBLE_TASK_NAME, AssembleTask.class) .get(); - assertThat(frontendAssembleTask.getPackageJsonDirectory().get()).isEqualTo( + assertThat(assembleFrontendTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); + assertThat(assembleFrontendTask.getPackageJsonDirectory().get()).isEqualTo( extension.getPackageJsonDirectory().getAsFile().get()); - assertThat(frontendAssembleTask.getNodeInstallDirectory().isPresent()).isTrue(); - assertThat(frontendAssembleTask.getAssembleScript().getOrNull()).isEqualTo( + //frontendAssembleTask.getPackageManagerExecutableFile() + assertThat(assembleFrontendTask.getAssembleScript().getOrNull()).isEqualTo( extension.getAssembleScript().getOrNull()); - assertThat(frontendAssembleTask.getDependsOn()).containsExactlyInAnyOrder(installFrontendTask.getName()); + assertThat(assembleFrontendTask.getVerboseModeEnabled().get()).isEqualTo( + extension.getVerboseModeEnabled().get()); + assertThat(assembleFrontendTask.getSystemJvmArch().get()).isEqualTo(expectedSystemProperties.get(JVM_ARCH)); + assertThat(assembleFrontendTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); + assertThat(assembleFrontendTask.getDependsOn()).containsExactlyInAnyOrder(installFrontendTask.getName()); assertThat(project.getTasks().named(BasePlugin.ASSEMBLE_TASK_NAME).get().getDependsOn()).contains( - frontendAssembleTask.getName()); + assembleFrontendTask.getName()); - final CheckTask frontendCheckTask = project + final CheckTask checkFrontendTask = project .getTasks() - .named(FrontendGradlePlugin.CHECK_TASK_NAME, CheckTask.class) + .named(CHECK_TASK_NAME, CheckTask.class) .get(); - assertThat(frontendCheckTask.getPackageJsonDirectory().get()).isEqualTo( + assertThat(checkFrontendTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); + assertThat(checkFrontendTask.getPackageJsonDirectory().get()).isEqualTo( extension.getPackageJsonDirectory().getAsFile().get()); - assertThat(frontendCheckTask.getNodeInstallDirectory().isPresent()).isTrue(); - assertThat(frontendCheckTask.getCheckScript().getOrNull()).isEqualTo(extension.getCheckScript().getOrNull()); - assertThat(frontendCheckTask.getDependsOn()).containsExactlyInAnyOrder(installFrontendTask.getName()); + assertThat(checkFrontendTask.getNodeInstallDirectory().get()).isEqualTo( + extension.getNodeInstallDirectory().getAsFile().get()); + //frontendCheckTask.getPackageManagerExecutableFile() + assertThat(checkFrontendTask.getCheckScript().getOrNull()).isEqualTo(extension.getCheckScript().getOrNull()); + assertThat(checkFrontendTask.getVerboseModeEnabled().get()).isEqualTo(extension.getVerboseModeEnabled().get()); + assertThat(checkFrontendTask.getSystemJvmArch().get()).isEqualTo(expectedSystemProperties.get(JVM_ARCH)); + assertThat(checkFrontendTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); + assertThat(checkFrontendTask.getDependsOn()).containsExactlyInAnyOrder(installFrontendTask.getName()); assertThat(project.getTasks().named(LifecycleBasePlugin.CHECK_TASK_NAME).get().getDependsOn()).contains( - frontendCheckTask.getName()); + checkFrontendTask.getName()); - final PublishTask frontendPublishTask = project + final PublishTask publishFrontendTask = project .getTasks() - .named(FrontendGradlePlugin.PUBLISH_TASK_NAME, PublishTask.class) + .named(PUBLISH_TASK_NAME, PublishTask.class) .get(); - assertThat(frontendPublishTask.getPackageJsonDirectory().get()).isEqualTo( + assertThat(publishFrontendTask.getBeanRegistryBuildService().get().getBeanRegistry()).isNotNull(); + assertThat(publishFrontendTask.getPackageJsonDirectory().get()).isEqualTo( extension.getPackageJsonDirectory().getAsFile().get()); - assertThat(frontendPublishTask.getNodeInstallDirectory().isPresent()).isTrue(); - assertThat(frontendPublishTask.getPublishScript().getOrNull()).isEqualTo( + assertThat(publishFrontendTask.getNodeInstallDirectory().get()).isEqualTo( + extension.getNodeInstallDirectory().getAsFile().get()); + //frontendPublishTask.getPackageManagerExecutableFile() + assertThat(publishFrontendTask.getPublishScript().getOrNull()).isEqualTo( extension.getPublishScript().getOrNull()); - assertThat(frontendPublishTask.getDependsOn()).containsExactlyInAnyOrder(frontendAssembleTask.getName()); + assertThat(publishFrontendTask.getVerboseModeEnabled().get()).isEqualTo( + extension.getVerboseModeEnabled().get()); + assertThat(publishFrontendTask.getSystemJvmArch().get()).isEqualTo(expectedSystemProperties.get(JVM_ARCH)); + assertThat(publishFrontendTask.getSystemOsName().get()).isEqualTo(expectedSystemProperties.get(OS_NAME)); + assertThat(publishFrontendTask.getDependsOn()).containsExactlyInAnyOrder(assembleFrontendTask.getName()); assertThat( project.getTasks().named(PublishingPlugin.PUBLISH_LIFECYCLE_TASK_NAME).get().getDependsOn()).contains( - frontendPublishTask.getName()); + publishFrontendTask.getName()); } } diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsTest.java index ef7bc483..3aa13166 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolveExecutionSettingsTest.java @@ -3,11 +3,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static org.siouan.frontendgradleplugin.test.PathFixture.ANY_PATH; import static org.siouan.frontendgradleplugin.domain.PlatformFixture.aPlatform; import static org.siouan.frontendgradleplugin.domain.SystemPropertiesFixture.getSystemJvmArch; +import static org.siouan.frontendgradleplugin.test.PathFixture.ANY_PATH; import java.nio.file.Path; +import java.util.Map; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -42,11 +43,13 @@ void should_resolve_exec_settings_with_windows_cmd_when_executable_is_node_in_di .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .build())).thenReturn(nodeExecutablePath); - when(getExecutablePath.execute(GetExecutablePathCommand.builder() - .executableType(ExecutableType.NODE) - .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) - .platform(platform) + when(getExecutablePath.execute(GetExecutablePathCommand + .builder() + .executableType(ExecutableType.NODE) + .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) + .platform(platform) .build())).thenReturn(nodeExecutablePath); + final Map environmentVariables = Map.of("VARIABLE", "value"); final ExecutionSettings executionSettings = usecase.execute(ResolveExecutionSettingsCommand .builder() @@ -55,6 +58,7 @@ void should_resolve_exec_settings_with_windows_cmd_when_executable_is_node_in_di .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .script(SCRIPT) + .environmentVariables(environmentVariables) .build()); assertThat(executionSettings.getWorkingDirectoryPath()).isEqualTo(PACKAGE_JSON_DIRECTORY_PATH); @@ -62,6 +66,7 @@ void should_resolve_exec_settings_with_windows_cmd_when_executable_is_node_in_di assertThat(executionSettings.getExecutablePath()).isEqualTo(ResolveExecutionSettings.WINDOWS_EXECUTABLE_PATH); assertThat(executionSettings.getArguments()).containsExactly( ResolveExecutionSettings.WINDOWS_EXECUTABLE_AUTOEXIT_FLAG, "\"" + nodeExecutablePath + "\" run script"); + assertThat(executionSettings.getEnvironmentVariables()).isEqualTo(environmentVariables); verifyNoMoreInteractions(getNodeExecutablePath, getExecutablePath); } @@ -75,11 +80,13 @@ void should_resolve_exec_settings_with_windows_cmd_when_executable_is_not_node_i .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .build())).thenReturn(nodeExecutablePath); - when(getExecutablePath.execute(GetExecutablePathCommand.builder() + when(getExecutablePath.execute(GetExecutablePathCommand + .builder() .executableType(ExecutableType.NPM) .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .build())).thenReturn(npmExecutablePath); + final Map environmentVariables = Map.of("VARIABLE", "value"); final ExecutionSettings executionSettings = usecase.execute(ResolveExecutionSettingsCommand .builder() @@ -88,6 +95,7 @@ void should_resolve_exec_settings_with_windows_cmd_when_executable_is_not_node_i .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .script(SCRIPT) + .environmentVariables(environmentVariables) .build()); assertThat(executionSettings.getWorkingDirectoryPath()).isEqualTo(PACKAGE_JSON_DIRECTORY_PATH); @@ -95,6 +103,7 @@ void should_resolve_exec_settings_with_windows_cmd_when_executable_is_not_node_i assertThat(executionSettings.getExecutablePath()).isEqualTo(ResolveExecutionSettings.WINDOWS_EXECUTABLE_PATH); assertThat(executionSettings.getArguments()).containsExactly( ResolveExecutionSettings.WINDOWS_EXECUTABLE_AUTOEXIT_FLAG, "\"" + npmExecutablePath + "\" run script"); + assertThat(executionSettings.getEnvironmentVariables()).isEqualTo(environmentVariables); verifyNoMoreInteractions(getNodeExecutablePath, getExecutablePath); } @@ -107,11 +116,13 @@ void should_resolve_exec_settings_with_unix_shell_when_executable_is_node_in_pat .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .build())).thenReturn(nodeExecutablePath); - when(getExecutablePath.execute(GetExecutablePathCommand.builder() + when(getExecutablePath.execute(GetExecutablePathCommand + .builder() .executableType(ExecutableType.NODE) .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .build())).thenReturn(nodeExecutablePath); + final Map environmentVariables = Map.of("VARIABLE", "value"); final ExecutionSettings executionSettings = usecase.execute(ResolveExecutionSettingsCommand .builder() @@ -120,6 +131,7 @@ void should_resolve_exec_settings_with_unix_shell_when_executable_is_node_in_pat .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .script(SCRIPT) + .environmentVariables(environmentVariables) .build()); assertThat(executionSettings.getWorkingDirectoryPath()).isEqualTo(PACKAGE_JSON_DIRECTORY_PATH); @@ -127,6 +139,7 @@ void should_resolve_exec_settings_with_unix_shell_when_executable_is_node_in_pat assertThat(executionSettings.getExecutablePath()).isEqualTo(ResolveExecutionSettings.UNIX_EXECUTABLE_PATH); assertThat(executionSettings.getArguments()).containsExactly( ResolveExecutionSettings.UNIX_EXECUTABLE_AUTOEXIT_FLAG, "\"" + nodeExecutablePath + "\" run script"); + assertThat(executionSettings.getEnvironmentVariables()).isEqualTo(environmentVariables); verifyNoMoreInteractions(getNodeExecutablePath, getExecutablePath); } @@ -140,11 +153,13 @@ void should_resolve_exec_settings_with_unix_shell_when_executable_is_npm_in_path .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .build())).thenReturn(nodeExecutablePath); - when(getExecutablePath.execute(GetExecutablePathCommand.builder() + when(getExecutablePath.execute(GetExecutablePathCommand + .builder() .executableType(ExecutableType.NPM) .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .build())).thenReturn(npmExecutablePath); + final Map environmentVariables = Map.of("VARIABLE", "value"); final ExecutionSettings executionSettings = usecase.execute(ResolveExecutionSettingsCommand .builder() @@ -153,6 +168,7 @@ void should_resolve_exec_settings_with_unix_shell_when_executable_is_npm_in_path .nodeInstallDirectoryPath(NODE_INSTALL_DIRECTORY_PATH) .platform(platform) .script(SCRIPT) + .environmentVariables(environmentVariables) .build()); assertThat(executionSettings.getWorkingDirectoryPath()).isEqualTo(PACKAGE_JSON_DIRECTORY_PATH); @@ -160,6 +176,7 @@ void should_resolve_exec_settings_with_unix_shell_when_executable_is_npm_in_path assertThat(executionSettings.getExecutablePath()).isEqualTo(ResolveExecutionSettings.UNIX_EXECUTABLE_PATH); assertThat(executionSettings.getArguments()).containsExactly( ResolveExecutionSettings.UNIX_EXECUTABLE_AUTOEXIT_FLAG, "\"" + npmExecutablePath + "\" run script"); + assertThat(executionSettings.getEnvironmentVariables()).isEqualTo(environmentVariables); verifyNoMoreInteractions(getNodeExecutablePath, getExecutablePath); } } diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManagerTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManagerTest.java index 938121e0..b32a35a0 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManagerTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/ResolvePackageManagerTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -36,28 +37,46 @@ class ResolvePackageManagerTest { private ResolvePackageManager usecase; @Test - void should_resolve_package_manager_type_and_store_name_and_executable_file_path_in_cache() + void should_delete_output_files_when_package_json_file_does_not_exist() + throws IOException, InvalidJsonFileException, MalformedPackageManagerSpecification, + UnsupportedPackageManagerException { + final Path nodeInstallDirectoryPath = Paths.get("node"); + final Path packageManagerSpecificationFilePath = Paths.get("name.txt"); + final Path packageManagerExecutablePathFilePath = Paths.get("executable-path.txt"); + + usecase.execute(new ResolvePackageManagerCommand(null, nodeInstallDirectoryPath, LOCAL_PLATFORM, + packageManagerSpecificationFilePath, packageManagerExecutablePathFilePath)); + + final ArgumentCaptor pathArgumentCaptor = ArgumentCaptor.forClass(Path.class); + verify(fileManager, times(2)).deleteIfExists(pathArgumentCaptor.capture()); + assertThat(pathArgumentCaptor.getAllValues()).containsExactly(packageManagerSpecificationFilePath, + packageManagerExecutablePathFilePath); + verifyNoMoreInteractions(parsePackageManagerFromPackageJsonFile, getExecutablePath, fileManager); + } + + @Test + void should_resolve_package_manager_and_cache_output_files() throws IOException, InvalidJsonFileException, MalformedPackageManagerSpecification, UnsupportedPackageManagerException { final Path packageJsonFilePath = Paths.get("package.json"); final Path nodeInstallDirectoryPath = Paths.get("node"); final Platform platform = LOCAL_PLATFORM; - final Path packageManagerNameFilePath = Paths.get("name.txt"); + final Path packageManagerSpecificationFilePath = Paths.get("name.txt"); final Path packageManagerExecutablePathFilePath = Paths.get("executable-path.txt"); final PackageManagerType packageManagerType = PackageManagerType.PNPM; final String packageManagerVersion = "5.9.2"; when(parsePackageManagerFromPackageJsonFile.execute(packageJsonFilePath)).thenReturn( PackageManager.builder().type(packageManagerType).version(packageManagerVersion).build()); final Path executablePath = Paths.get("executable"); - when(fileManager.writeString(packageManagerNameFilePath, "pnpm@5.9.2", StandardCharsets.UTF_8, - StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)).thenReturn(packageManagerNameFilePath); + when(fileManager.writeString(packageManagerSpecificationFilePath, "pnpm@5.9.2", StandardCharsets.UTF_8, + StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)).thenReturn(packageManagerSpecificationFilePath); when(getExecutablePath.execute(any(GetExecutablePathCommand.class))).thenReturn(executablePath); when(fileManager.writeString(packageManagerExecutablePathFilePath, executablePath.toString(), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)).thenReturn( packageManagerExecutablePathFilePath); usecase.execute(new ResolvePackageManagerCommand(packageJsonFilePath, nodeInstallDirectoryPath, platform, - packageManagerNameFilePath, packageManagerExecutablePathFilePath)); + packageManagerSpecificationFilePath, packageManagerExecutablePathFilePath)); final ArgumentCaptor getExecutablePathQueryArgumentCaptor = ArgumentCaptor.forClass( GetExecutablePathCommand.class); diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/SystemPropertiesFixture.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/SystemPropertiesFixture.java index 76c8abb1..518f5366 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/SystemPropertiesFixture.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/SystemPropertiesFixture.java @@ -19,7 +19,7 @@ public final class SystemPropertiesFixture { * @return String describing the JVM architecture. */ public static String getSystemJvmArch() { - return getPropertyAndAssertNotNull(SystemProperties.JVM_ARCH_PROPERTY); + return getPropertyAndAssertNotNull(SystemProperties.JVM_ARCH); } /** @@ -28,7 +28,7 @@ public static String getSystemJvmArch() { * @return String describing the O/S. */ public static String getSystemOsName() { - return getPropertyAndAssertNotNull(SystemProperties.OS_NAME_PROPERTY); + return getPropertyAndAssertNotNull(SystemProperties.OS_NAME); } private static String getPropertyAndAssertNotNull(final String property) { diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlTest.java index fce773cc..b621f4d1 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/domain/installer/ResolveProxySettingsByUrlTest.java @@ -16,7 +16,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.siouan.frontendgradleplugin.domain.SystemSettingsProvider; @ExtendWith(MockitoExtension.class) class ResolveProxySettingsByUrlTest { @@ -40,9 +39,6 @@ class ResolveProxySettingsByUrlTest { private static final int SYSTEM_PROXY_PORT = 233; - @Mock - private SystemSettingsProvider systemSettingsProvider; - @Mock private IsNonProxyHost isNonProxyHost; @@ -64,7 +60,7 @@ void should_fail_when_url_uses_unsupported_protocol() throws MalformedURLExcepti assertThatThrownBy(() -> usecase.execute(command)).isInstanceOf(IllegalArgumentException.class); - verifyNoMoreInteractions(systemSettingsProvider, isNonProxyHost, selectProxySettings); + verifyNoMoreInteractions(isNonProxyHost, selectProxySettings); } @Test @@ -78,13 +74,12 @@ void should_return_direct_connection_when_url_uses_file_protocol() throws Malfor .build()) .getProxyType()).isEqualTo(Proxy.Type.DIRECT); - verifyNoMoreInteractions(systemSettingsProvider, isNonProxyHost, selectProxySettings); + verifyNoMoreInteractions(isNonProxyHost, selectProxySettings); } @Test void should_return_direct_connection_when_url_uses_non_proxy_host() throws MalformedURLException { final Set nonProxyHosts = Set.of(PLUGIN_PROXY_HOST); - when(systemSettingsProvider.getNonProxyHosts()).thenReturn(nonProxyHosts); final URL resourceUrl = new URL(HTTP_RESOURCE_URL); when(isNonProxyHost.execute(IsNonProxyHostCommand .builder() @@ -98,16 +93,16 @@ void should_return_direct_connection_when_url_uses_non_proxy_host() throws Malfo .httpProxyPort(80) .httpsProxyPort(443) .resourceUrl(resourceUrl) + .systemNonProxyHosts(nonProxyHosts) .build()) .getProxyType()).isEqualTo(Proxy.Type.DIRECT); - verifyNoMoreInteractions(systemSettingsProvider, isNonProxyHost, selectProxySettings); + verifyNoMoreInteractions(isNonProxyHost, selectProxySettings); } @Test void should_return_http_proxy_settings_when_url_uses_non_secure_http_protocol() throws MalformedURLException { final Set nonProxyHosts = Set.of(); - when(systemSettingsProvider.getNonProxyHosts()).thenReturn(nonProxyHosts); final URL resourceUrl = new URL(HTTP_RESOURCE_URL); when(isNonProxyHost.execute(IsNonProxyHostCommand .builder() @@ -116,8 +111,6 @@ void should_return_http_proxy_settings_when_url_uses_non_secure_http_protocol() .build())).thenReturn(false); final String systemProxyHost = SYSTEM_PROXY_HOST; final int systemProxyPort = SYSTEM_PROXY_PORT; - when(systemSettingsProvider.getHttpProxyHost()).thenReturn(systemProxyHost); - when(systemSettingsProvider.getHttpProxyPort()).thenReturn(systemProxyPort); final String proxyHost = PLUGIN_PROXY_HOST; final int proxyPort = PLUGIN_PROXY_PORT; final ProxySettings proxySettings = someProxySettings(); @@ -137,15 +130,17 @@ void should_return_http_proxy_settings_when_url_uses_non_secure_http_protocol() .httpProxyHost(proxyHost) .httpProxyPort(proxyPort) .httpProxyCredentials(proxyCredentials) + .systemNonProxyHosts(nonProxyHosts) + .systemHttpProxyHost(systemProxyHost) + .systemHttpProxyPort(systemProxyPort) .build())).isEqualTo(proxySettings); - verifyNoMoreInteractions(systemSettingsProvider, isNonProxyHost, selectProxySettings); + verifyNoMoreInteractions(isNonProxyHost, selectProxySettings); } @Test void should_return_https_proxy_settings_when_url_uses_secure_http_protocol() throws MalformedURLException { final Set nonProxyHosts = Set.of(); - when(systemSettingsProvider.getNonProxyHosts()).thenReturn(nonProxyHosts); final URL resourceUrl = new URL(HTTPS_RESOURCE_URL); when(isNonProxyHost.execute(IsNonProxyHostCommand .builder() @@ -154,8 +149,6 @@ void should_return_https_proxy_settings_when_url_uses_secure_http_protocol() thr .build())).thenReturn(false); final String systemProxyHost = SYSTEM_PROXY_HOST; final int systemProxyPort = SYSTEM_PROXY_PORT; - when(systemSettingsProvider.getHttpsProxyHost()).thenReturn(systemProxyHost); - when(systemSettingsProvider.getHttpsProxyPort()).thenReturn(systemProxyPort); final String proxyHost = PLUGIN_PROXY_HOST; final int proxyPort = PLUGIN_PROXY_PORT; final ProxySettings proxySettings = someProxySettings(); @@ -175,8 +168,11 @@ void should_return_https_proxy_settings_when_url_uses_secure_http_protocol() thr .httpsProxyHost(proxyHost) .httpsProxyPort(proxyPort) .httpsProxyCredentials(proxyCredentials) + .systemNonProxyHosts(nonProxyHosts) + .systemHttpsProxyHost(systemProxyHost) + .systemHttpsProxyPort(systemProxyPort) .build())).isEqualTo(proxySettings); - verifyNoMoreInteractions(systemSettingsProvider, isNonProxyHost, selectProxySettings); + verifyNoMoreInteractions(isNonProxyHost, selectProxySettings); } } diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiverTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiverTest.java index 010c6e20..4603f044 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiverTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/archiver/ZipArchiverTest.java @@ -7,8 +7,8 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import static org.siouan.frontendgradleplugin.domain.PlatformFixture.LOCAL_PLATFORM; +import static org.siouan.frontendgradleplugin.test.Resources.getResourcePath; import java.io.IOException; import java.io.InputStream; @@ -55,7 +55,13 @@ void should_fail_initializing_context_when_zip_archive_does_not_exist() { .targetDirectoryPath(temporaryDirectoryPath) .build(); - assertThatThrownBy(() -> archiver.initializeContext(settings)).isInstanceOf(IOException.class); + assertThatThrownBy(() -> { + try (@SuppressWarnings("unused") final ZipArchiverContext zipArchiverContext = archiver.initializeContext( + settings)) { + // The test is expected to fail during context initilization above. This code is necessary in case + // initialization succeeds unexpectedly: the context must be close with the try-with-resources block. + } + }).isInstanceOf(IOException.class); verifyNoMoreInteractions(fileManager); } @@ -70,7 +76,13 @@ void should_fail_initializing_context_when_zip_archive_is_invalid() { .targetDirectoryPath(temporaryDirectoryPath) .build(); - assertThatThrownBy(() -> archiver.initializeContext(settings)).isInstanceOf(IOException.class); + assertThatThrownBy(() -> { + try (@SuppressWarnings("unused") final ZipArchiverContext zipArchiverContext = archiver.initializeContext( + settings)) { + // The test is expected to fail during context initilization above. This code is necessary in case + // initialization succeeds unexpectedly: the context must be close with the try-with-resources block. + } + }).isInstanceOf(IOException.class); verifyNoMoreInteractions(fileManager); } @@ -86,18 +98,18 @@ void should_fail_reading_symbolic_link_target() throws IOException { .build(); final IOException expectedException = new IOException(); - final ZipArchiver archiver = new ZipArchiverWithSymbolicLinkFailure(fileManager, expectedException); + final ZipArchiver zipArchiver = new ZipArchiverWithSymbolicLinkFailure(fileManager, expectedException); boolean failure = false; - try (final ZipArchiverContext context = archiver.initializeContext(settings)) { - Optional option = archiver.getNextEntry(context); + try (final ZipArchiverContext context = zipArchiver.initializeContext(settings)) { + Optional option = zipArchiver.getNextEntry(context); while (option.isPresent()) { final ZipEntry entry = option.get(); if (entry.isSymbolicLink()) { - assertThatThrownBy(() -> archiver.getSymbolicLinkTarget(context, entry)).isEqualTo( + assertThatThrownBy(() -> zipArchiver.getSymbolicLinkTarget(context, entry)).isEqualTo( expectedException); failure = true; } - option = archiver.getNextEntry(context); + option = zipArchiver.getNextEntry(context); } } diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistryTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistryTest.java index 7458f3c0..88b5be9a 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistryTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/bean/BeanRegistryTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import lombok.Getter; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -23,7 +24,7 @@ void should_register_the_registry_itself() @Test void should_not_replace_registry_when_registering_other_registry_class() throws BeanInstanciationException, TooManyCandidateBeansException, ZeroOrMultiplePublicConstructorsException { - beanRegistry.registerBean(BeanRegistry.class); + beanRegistry.registerBeanClass(BeanRegistry.class); assertThat(beanRegistry.getBean(BeanRegistry.class)).isSameAs(beanRegistry); } @@ -134,11 +135,11 @@ void should_get_same_instance_when_registering_bean_class_multiple_times() void should_get_same_instance_when_registering_bean_instance_multiple_times() throws BeanInstanciationException, TooManyCandidateBeansException, ZeroOrMultiplePublicConstructorsException { // First call triggers internally bean registration and instanciation. - beanRegistry.registerBean(DefaultPublicConstructorBean.class); + beanRegistry.registerBeanClass(DefaultPublicConstructorBean.class); // Second call shall return exactly the same bean. final DefaultPublicConstructorBean bean1 = beanRegistry.getBean(DefaultPublicConstructorBean.class); // Third call shall return exactly the same bean, even if we tried to register another instance. - beanRegistry.registerBean(DefaultPublicConstructorBean.class); + beanRegistry.registerBeanClass(DefaultPublicConstructorBean.class); final DefaultPublicConstructorBean bean2 = beanRegistry.getBean(DefaultPublicConstructorBean.class); assertThat(bean1).isNotNull(); @@ -210,6 +211,7 @@ public BeanWithParameterConstructorWithException(final BeanWithConstructorExcept } } + @Getter private static class PublicConstructorWithValidParameterBean { private final DefaultPublicConstructorBean parameter; @@ -217,10 +219,6 @@ private static class PublicConstructorWithValidParameterBean { public PublicConstructorWithValidParameterBean(final DefaultPublicConstructorBean parameter) { this.parameter = parameter; } - - public DefaultPublicConstructorBean getParameter() { - return parameter; - } } private static class Parent {} diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecActionTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecActionTest.java index 65f7de14..00898be7 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecActionTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/ExecSpecActionTest.java @@ -1,17 +1,13 @@ package org.siouan.frontendgradleplugin.infrastructure.gradle; -import static java.util.Arrays.asList; -import static java.util.stream.Collectors.toCollection; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import static org.siouan.frontendgradleplugin.infrastructure.gradle.ExecSpecAction.PATH_VARIABLE_NAME; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -20,7 +16,6 @@ import org.gradle.process.ExecSpec; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.siouan.frontendgradleplugin.domain.ExecutionSettings; @@ -28,15 +23,13 @@ @ExtendWith(MockitoExtension.class) class ExecSpecActionTest { - private static final Path WORKING_DIRECTORY_PATH = Paths.get("/tmp"); + private static final Path WORKING_DIRECTORY_PATH = Paths.get("/home"); - private static final Path EXECUTABLE_DIRECTORY_PATH = WORKING_DIRECTORY_PATH.resolve("bin"); + private static final Path EXECUTABLE_FILE_PATH = Paths.get("/opt/executable"); - private static final Path EXECUTABLE_FILE_PATH = EXECUTABLE_DIRECTORY_PATH.resolve("executable"); + private static final Path ADDITIONAL_EXECUTABLE_PATH = Paths.get("/bin"); - private static final List EXECUTABLE_PATHS = asList("/usr/bin", "/usr/lib"); - - private static final List ARGUMENTS = asList("arg1", "argument 2"); + private static final List ARGUMENTS = List.of("arg1", "argument 2"); @Mock private ExecSpec execSpec; @@ -45,59 +38,190 @@ class ExecSpecActionTest { private Consumer afterConfigured; @Test - void should_configure_exec_spec_with_uppercase_path_variable_and_without_executable_paths() { + void should_configure_exec_spec_with_no_user_environment_and_no_path_override_and_no_additional_executable_paths_and_no_system_path() { + final ExecutionSettings executionSettings = ExecutionSettings + .builder() + .workingDirectoryPath(WORKING_DIRECTORY_PATH) + .additionalExecutablePaths(Set.of()) + .executablePath(EXECUTABLE_FILE_PATH) + .arguments(ARGUMENTS) + .environmentVariables(Map.of()) + .build(); + final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); + when(execSpec.getEnvironment()).thenReturn(Map.of()); + + action.execute(execSpec); + + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(afterConfigured).accept(execSpec); + verifyNoMoreInteractions(execSpec, afterConfigured); + } + + @Test + void should_configure_exec_spec_with_user_environment_and_no_path_override_and_no_additional_executable_paths_and_no_system_path() { + final ExecutionSettings executionSettings = ExecutionSettings + .builder() + .workingDirectoryPath(WORKING_DIRECTORY_PATH) + .additionalExecutablePaths(Set.of()) + .executablePath(EXECUTABLE_FILE_PATH) + .arguments(ARGUMENTS) + .environmentVariables(Map.of("VARIABLE", "value")) + .build(); + final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); + when(execSpec.getEnvironment()).thenReturn(Map.of()); + + action.execute(execSpec); + + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(execSpec).environment(Map.of("VARIABLE", "value")); + verify(afterConfigured).accept(execSpec); + verifyNoMoreInteractions(execSpec, afterConfigured); + } + + @Test + void should_configure_exec_spec_with_user_environment_and_path_override_and_no_additional_executable_paths_and_no_system_path() { + final ExecutionSettings executionSettings = ExecutionSettings + .builder() + .workingDirectoryPath(WORKING_DIRECTORY_PATH) + .additionalExecutablePaths(Set.of()) + .executablePath(EXECUTABLE_FILE_PATH) + .arguments(ARGUMENTS) + .environmentVariables(Map.of("VARIABLE", "value", "PATH", "/usr/bin")) + .build(); + final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); + when(execSpec.getEnvironment()).thenReturn(Map.of()); + + action.execute(execSpec); + + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(execSpec).environment(Map.of("VARIABLE", "value")); + verify(execSpec).environment(PATH_VARIABLE_NAME, "/usr/bin"); + verify(afterConfigured).accept(execSpec); + verifyNoMoreInteractions(execSpec, afterConfigured); + } + + @Test + void should_configure_exec_spec_with_user_environment_and_no_path_override_and_additional_executable_paths_and_no_system_path() { + final ExecutionSettings executionSettings = ExecutionSettings + .builder() + .workingDirectoryPath(WORKING_DIRECTORY_PATH) + .additionalExecutablePaths(Set.of(ADDITIONAL_EXECUTABLE_PATH)) + .executablePath(EXECUTABLE_FILE_PATH) + .arguments(ARGUMENTS) + .environmentVariables(Map.of("VARIABLE", "value")) + .build(); + final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); + when(execSpec.getEnvironment()).thenReturn(Map.of()); + + action.execute(execSpec); + + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(execSpec).environment(Map.of("VARIABLE", "value")); + verify(execSpec).environment(PATH_VARIABLE_NAME, ADDITIONAL_EXECUTABLE_PATH.toString()); + verify(afterConfigured).accept(execSpec); + verifyNoMoreInteractions(execSpec, afterConfigured); + } + + @Test + void should_configure_exec_spec_with_user_environment_and_path_override_and_additional_executable_paths_and_no_system_path() { + final ExecutionSettings executionSettings = ExecutionSettings + .builder() + .workingDirectoryPath(WORKING_DIRECTORY_PATH) + .additionalExecutablePaths(Set.of(ADDITIONAL_EXECUTABLE_PATH)) + .executablePath(EXECUTABLE_FILE_PATH) + .arguments(ARGUMENTS) + .environmentVariables(Map.of("VARIABLE", "value", "PATH", "/usr/bin")) + .build(); + final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); + when(execSpec.getEnvironment()).thenReturn(Map.of()); + + action.execute(execSpec); + + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(execSpec).environment(Map.of("VARIABLE", "value")); + verify(execSpec).environment(PATH_VARIABLE_NAME, ADDITIONAL_EXECUTABLE_PATH + File.pathSeparator + "/usr/bin"); + verify(afterConfigured).accept(execSpec); + verifyNoMoreInteractions(execSpec, afterConfigured); + } + + @Test + void should_configure_exec_spec_with_user_environment_and_no_path_override_and_no_additional_executable_paths_and_system_path() { final ExecutionSettings executionSettings = ExecutionSettings .builder() .workingDirectoryPath(WORKING_DIRECTORY_PATH) .additionalExecutablePaths(Set.of()) .executablePath(EXECUTABLE_FILE_PATH) .arguments(ARGUMENTS) + .environmentVariables(Map.of("VARIABLE", "value")) .build(); final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); - when(execSpec.getEnvironment()).thenReturn(Map.of("PATH", String.join(File.pathSeparator, EXECUTABLE_PATHS))); + when(execSpec.getEnvironment()).thenReturn(Map.of("Path", "/system/bin")); action.execute(execSpec); - assertExecSpecWith(executionSettings); + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(execSpec).environment(Map.of("VARIABLE", "value")); + verify(execSpec).environment(PATH_VARIABLE_NAME, "/system/bin"); + verify(afterConfigured).accept(execSpec); + verifyNoMoreInteractions(execSpec, afterConfigured); } @Test - void should_configure_exec_spec_with_lowercase_path_variable_and_executable_paths() { - final Set executablePaths = new HashSet<>(); - executablePaths.add(Paths.get("\\Program Files\\node\\bin")); - executablePaths.add(Paths.get("/opt/yarn")); + void should_configure_exec_spec_with_user_environment_and_no_path_override_and_additional_executable_paths_and_system_path() { final ExecutionSettings executionSettings = ExecutionSettings .builder() .workingDirectoryPath(WORKING_DIRECTORY_PATH) - .additionalExecutablePaths(executablePaths) + .additionalExecutablePaths(Set.of(EXECUTABLE_FILE_PATH)) .executablePath(EXECUTABLE_FILE_PATH) .arguments(ARGUMENTS) + .environmentVariables(Map.of("VARIABLE", "value")) .build(); final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); - when(execSpec.getEnvironment()).thenReturn(Map.of("Path", String.join(File.pathSeparator, EXECUTABLE_PATHS))); + when(execSpec.getEnvironment()).thenReturn(Map.of("Path", "/system/bin")); action.execute(execSpec); - assertExecSpecWith(executionSettings); + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(execSpec).environment(Map.of("VARIABLE", "value")); + verify(execSpec).environment(PATH_VARIABLE_NAME, EXECUTABLE_FILE_PATH + File.pathSeparator + "/system/bin"); + verify(afterConfigured).accept(execSpec); + verifyNoMoreInteractions(execSpec, afterConfigured); } - private void assertExecSpecWith(final ExecutionSettings executionSettings) { - verify(execSpec).setWorkingDir(executionSettings.getWorkingDirectoryPath().toString()); - verify(execSpec).setExecutable(executionSettings.getExecutablePath()); - verify(execSpec).setArgs(executionSettings.getArguments()); - final ArgumentCaptor pathVariableCaptor = ArgumentCaptor.forClass(String.class); - final ArgumentCaptor pathValueCaptor = ArgumentCaptor.forClass(Object.class); - verify(execSpec).environment(pathVariableCaptor.capture(), pathValueCaptor.capture()); - assertThat(pathVariableCaptor.getValue().toLowerCase()).isEqualTo("path"); - final String pathValue = pathValueCaptor.getValue().toString(); - final List expectedPaths = executionSettings - .getAdditionalExecutablePaths() - .stream() - .map(Path::toString) - .collect(toCollection(ArrayList::new)); - expectedPaths.add("/usr/bin"); - expectedPaths.add("/usr/lib"); - assertThat(pathValue.split(File.pathSeparator)).containsExactlyElementsOf(expectedPaths); + @Test + void should_configure_exec_spec_with_user_environment_and_path_override_and_additional_executable_paths_and_system_path() { + final ExecutionSettings executionSettings = ExecutionSettings + .builder() + .workingDirectoryPath(WORKING_DIRECTORY_PATH) + .additionalExecutablePaths(Set.of(EXECUTABLE_FILE_PATH)) + .executablePath(EXECUTABLE_FILE_PATH) + .arguments(ARGUMENTS) + .environmentVariables(Map.of("VARIABLE", "value", "PATH", "/usr/bin")) + .build(); + final ExecSpecAction action = new ExecSpecAction(executionSettings, afterConfigured); + when(execSpec.getEnvironment()).thenReturn(Map.of("Path", "/system/bin")); + + action.execute(execSpec); + + verify(execSpec).setWorkingDir(WORKING_DIRECTORY_PATH.toString()); + verify(execSpec).setExecutable(EXECUTABLE_FILE_PATH.toString()); + verify(execSpec).setArgs(ARGUMENTS); + verify(execSpec).environment(Map.of("VARIABLE", "value")); + verify(execSpec).environment(PATH_VARIABLE_NAME, EXECUTABLE_FILE_PATH + File.pathSeparator + "/usr/bin"); verify(afterConfigured).accept(execSpec); verifyNoMoreInteractions(execSpec, afterConfigured); } diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapterTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapterTest.java index 67686835..3862a64f 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapterTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/GradleScriptRunnerAdapterTest.java @@ -11,6 +11,7 @@ import java.nio.file.Path; import java.util.List; +import java.util.Map; import java.util.Set; import org.gradle.process.ExecOperations; @@ -50,8 +51,9 @@ void setUp() { @Test void should_run_script_when_settings_are_resolved() { final Path nodeInstallationDirectory = ANY_PATH.resolve("node"); + final Map environmentVariables = Map.of("VARIABLE", "value"); final ScriptProperties scriptProperties = new ScriptProperties(execOperations, ANY_PATH.resolve("frontend"), - ExecutableType.NPM, nodeInstallationDirectory, SCRIPT, LOCAL_PLATFORM); + ExecutableType.NPM, nodeInstallationDirectory, SCRIPT, LOCAL_PLATFORM, environmentVariables); final Set executablePaths = Set.of(); final List arguments = List.of(); final ExecutionSettings executionSettings = ExecutionSettings @@ -60,6 +62,7 @@ void should_run_script_when_settings_are_resolved() { .additionalExecutablePaths(executablePaths) .executablePath(nodeInstallationDirectory.resolve("npm")) .arguments(arguments) + .environmentVariables(environmentVariables) .build(); when(resolveExecutionSettings.execute(ResolveExecutionSettingsCommand .builder() @@ -68,6 +71,7 @@ void should_run_script_when_settings_are_resolved() { .nodeInstallDirectoryPath(scriptProperties.getNodeInstallDirectoryPath()) .platform(scriptProperties.getPlatform()) .script(scriptProperties.getScript()) + .environmentVariables(environmentVariables) .build())).thenReturn(executionSettings); final ExecResult execResult = mock(ExecResult.class); when(execOperations.exec(any(ExecSpecAction.class))).thenReturn(execResult); @@ -84,6 +88,7 @@ void should_run_script_when_settings_are_resolved() { assertThat(eS.getAdditionalExecutablePaths()).isEqualTo( executionSettings.getAdditionalExecutablePaths()); assertThat(eS.getExecutablePath()).isEqualTo(executionSettings.getExecutablePath()); + assertThat(eS.getEnvironmentVariables()).isEqualTo(environmentVariables); }); assertThat(execSpecAction.getAfterConfiguredConsumer()).isNotNull(); }); diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemProvidersTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemProvidersTest.java new file mode 100644 index 00000000..aef6a5a7 --- /dev/null +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemProvidersTest.java @@ -0,0 +1,70 @@ +package org.siouan.frontendgradleplugin.infrastructure.gradle; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import org.gradle.api.internal.provider.DefaultProviderFactory; +import org.gradle.api.provider.Provider; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.siouan.frontendgradleplugin.domain.SystemProperties; + +@ExtendWith(MockitoExtension.class) +class SystemProvidersTest { + + @Mock + private Provider httpProxyHostProvider; + + @Mock + private Provider httpProxyPortProvider; + + @Mock + private Provider httpsProxyHostProvider; + + @Mock + private Provider httpsProxyPortProvider; + + @Mock + private Provider nonProxyHosts; + + @Mock + private Provider jvmArchProvider; + + @Mock + private Provider osNameProvider; + + @Mock + private DefaultProviderFactory providerFactory; + + private SystemProviders systemProviders; + + @BeforeEach + void setUp() { + when(providerFactory.systemProperty(SystemProperties.HTTP_PROXY_HOST)).thenReturn(httpProxyHostProvider); + when(providerFactory.systemProperty(SystemProperties.HTTP_PROXY_PORT)).thenReturn(httpProxyPortProvider); + when(providerFactory.systemProperty(SystemProperties.HTTPS_PROXY_HOST)).thenReturn(httpsProxyHostProvider); + when(providerFactory.systemProperty(SystemProperties.HTTPS_PROXY_PORT)).thenReturn(httpsProxyPortProvider); + when(providerFactory.systemProperty(SystemProperties.NON_PROXY_HOSTS)).thenReturn(nonProxyHosts); + when(providerFactory.systemProperty(SystemProperties.JVM_ARCH)).thenReturn(jvmArchProvider); + when(providerFactory.systemProperty(SystemProperties.OS_NAME)).thenReturn(osNameProvider); + systemProviders = new SystemProviders(providerFactory); + } + + @Test + void should_return_system_properties() { + assertThat(systemProviders.getHttpProxyHost()).isEqualTo(httpProxyHostProvider); + assertThat(systemProviders.getHttpProxyPort()).isEqualTo(httpProxyPortProvider); + assertThat(systemProviders.getHttpsProxyHost()).isEqualTo(httpsProxyHostProvider); + assertThat(systemProviders.getHttpsProxyPort()).isEqualTo(httpsProxyPortProvider); + assertThat(systemProviders.getNonProxyHosts()).isEqualTo(nonProxyHosts); + assertThat(systemProviders.getJvmArch()).isEqualTo(jvmArchProvider); + assertThat(systemProviders.getOsName()).isEqualTo(osNameProvider); + + verifyNoMoreInteractions(httpProxyHostProvider, httpProxyPortProvider, httpsProxyHostProvider, + httpsProxyPortProvider, nonProxyHosts, jvmArchProvider, osNameProvider); + } +} diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemSettingsProviderImplTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemSettingsProviderImplTest.java deleted file mode 100644 index fd473acd..00000000 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/SystemSettingsProviderImplTest.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.siouan.frontendgradleplugin.infrastructure.gradle; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static org.siouan.frontendgradleplugin.domain.SystemPropertiesFixture.getSystemJvmArch; -import static org.siouan.frontendgradleplugin.domain.SystemPropertiesFixture.getSystemOsName; - -import org.gradle.api.provider.Provider; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junitpioneer.jupiter.ClearSystemProperty; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.siouan.frontendgradleplugin.domain.SystemProperties; - -@ExtendWith(MockitoExtension.class) -class SystemSettingsProviderImplTest { - - private static final int DEFAULT_HTTP_PROXY_PORT = 80; - - private static final int DEFAULT_HTTPS_PROXY_PORT = 443; - - @Mock - private Provider stringProvider; - - @Mock - private SystemExtension systemExtension; - - private SystemSettingsProviderImpl systemSettingsProvider; - - @BeforeEach - void setUp() { - when(systemExtension.getJvmArch()).thenReturn(stringProvider); - when(systemExtension.getOsName()).thenReturn(stringProvider); - when(systemExtension.getHttpProxyHost()).thenReturn(stringProvider); - when(systemExtension.getHttpProxyPort()).thenReturn(stringProvider); - when(systemExtension.getHttpsProxyHost()).thenReturn(stringProvider); - when(systemExtension.getHttpsProxyPort()).thenReturn(stringProvider); - when(systemExtension.getNonProxyHosts()).thenReturn(stringProvider); - systemSettingsProvider = new SystemSettingsProviderImpl(systemExtension, DEFAULT_HTTP_PROXY_PORT, - DEFAULT_HTTPS_PROXY_PORT); - } - - @Test - void should_return_jvm_arch_from_extension() { - final String jvmArch = getSystemJvmArch(); - when(stringProvider.get()).thenReturn(jvmArch); - - assertThat(systemSettingsProvider.getSystemJvmArch()).isEqualTo(jvmArch); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - void should_return_os_name_from_extension() { - final String osName = getSystemOsName(); - when(stringProvider.get()).thenReturn(osName); - - assertThat(systemSettingsProvider.getSystemOsName()).isEqualTo(osName); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.HTTP_PROXY_HOST) - void should_return_http_proxy_host_from_extension() { - final String httpProxyHost = "http-proxy"; - when(stringProvider.getOrNull()).thenReturn(httpProxyHost); - - assertThat(systemSettingsProvider.getHttpProxyHost()).isEqualTo(httpProxyHost); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.HTTP_PROXY_HOST) - void should_return_no_http_proxy_port_from_extension() { - when(stringProvider.getOrNull()).thenReturn(null); - - assertThat(systemSettingsProvider.getHttpProxyPort()).isEqualTo(DEFAULT_HTTP_PROXY_PORT); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.HTTP_PROXY_PORT) - void should_return_http_proxy_port_when_non_blank() { - final String httpProxyPort = "743"; - when(stringProvider.getOrNull()).thenReturn(httpProxyPort); - - assertThat(systemSettingsProvider.getHttpProxyPort()).hasToString(httpProxyPort); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.HTTP_PROXY_PORT) - void should_return_no_http_non_proxy_hosts_when_system_property_is_null_or_blank() { - when(stringProvider.getOrNull()).thenReturn(null); - - assertThat(systemSettingsProvider.getNonProxyHosts()).isEmpty(); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.NON_PROXY_HOSTS) - void should_return_http_non_proxy_hosts_when_system_property_is_defined() { - when(stringProvider.getOrNull()).thenReturn("localhost|127.*|[::1]"); - - assertThat(systemSettingsProvider.getNonProxyHosts()).containsExactlyInAnyOrder("localhost", "127.*", "[::1]"); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.HTTPS_PROXY_HOST) - void should_return_https_proxy_host_from_extension() { - final String httpsProxyHost = "https-proxy"; - when(stringProvider.getOrNull()).thenReturn(httpsProxyHost); - - assertThat(systemSettingsProvider.getHttpsProxyHost()).isEqualTo(httpsProxyHost); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.HTTPS_PROXY_PORT) - void should_return_no_https_proxy_port_from_extension() { - when(stringProvider.getOrNull()).thenReturn(null); - - assertThat(systemSettingsProvider.getHttpsProxyPort()).isEqualTo(DEFAULT_HTTPS_PROXY_PORT); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } - - @Test - @ClearSystemProperty(key = SystemProperties.HTTPS_PROXY_PORT) - void should_return_https_proxy_port_when_non_blank() { - final String httpsProxyPort = "1988"; - when(stringProvider.getOrNull()).thenReturn(httpsProxyPort); - - assertThat(systemSettingsProvider.getHttpsProxyPort()).hasToString(httpsProxyPort); - - verifyNoMoreInteractions(systemExtension, stringProvider); - } -} diff --git a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerConfigurerTest.java b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerInitializerTest.java similarity index 60% rename from plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerConfigurerTest.java rename to plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerInitializerTest.java index cee640b7..2c6dafa0 100644 --- a/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerConfigurerTest.java +++ b/plugin/src/test/java/org/siouan/frontendgradleplugin/infrastructure/gradle/TaskLoggerInitializerTest.java @@ -10,23 +10,18 @@ import org.gradle.api.logging.LogLevel; import org.gradle.api.logging.Logger; import org.gradle.api.logging.LoggingManager; -import org.gradle.api.provider.Property; 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; @ExtendWith(MockitoExtension.class) -class TaskLoggerConfigurerTest { +class TaskLoggerInitializerTest { private static final String TASK_NAME = "task"; private static final LogLevel LOGGING_LEVEL = LogLevel.WARN; - @Mock - private Property verboseModeEnabled; - @Mock private Logger gradleLogger; @@ -37,30 +32,22 @@ class TaskLoggerConfigurerTest { private LoggingManager taskLoggingManager; @Mock - private GradleLoggerAdapter adapter; - - @Mock - private FrontendExtension extension; + private GradleLoggerAdapter gradleLoggerAdapter; @Mock private GradleSettings gradleSettings; - @InjectMocks - private TaskLoggerConfigurer taskLoggerConfigurer; - @Test void should_init_logger_before_task_execution_with_task_level() { when(task.getName()).thenReturn(TASK_NAME); when(task.getLogger()).thenReturn(gradleLogger); when(task.getLogging()).thenReturn(taskLoggingManager); when(taskLoggingManager.getLevel()).thenReturn(LOGGING_LEVEL); - when(extension.getVerboseModeEnabled()).thenReturn(verboseModeEnabled); - when(verboseModeEnabled.get()).thenReturn(true); - taskLoggerConfigurer.initLoggerAdapter(task); + TaskLoggerInitializer.initAdapter(task, true, gradleLoggerAdapter, gradleSettings); - verify(adapter).init(eq(gradleLogger), eq(LOGGING_LEVEL), eq(true), anyString()); - verifyNoMoreInteractions(task, taskLoggingManager, adapter, gradleSettings); + verify(gradleLoggerAdapter).init(eq(gradleLogger), eq(LOGGING_LEVEL), eq(true), anyString()); + verifyNoMoreInteractions(task, taskLoggingManager, gradleLoggerAdapter, gradleSettings); } @Test @@ -69,14 +56,12 @@ void should_init_logger_before_task_execution_with_project_level() { when(task.getLogger()).thenReturn(gradleLogger); when(task.getLogging()).thenReturn(taskLoggingManager); when(gradleSettings.getProjectLogLevel()).thenReturn(LOGGING_LEVEL); - when(extension.getVerboseModeEnabled()).thenReturn(verboseModeEnabled); - when(verboseModeEnabled.get()).thenReturn(true); - taskLoggerConfigurer.initLoggerAdapter(task); + TaskLoggerInitializer.initAdapter(task, true, gradleLoggerAdapter, gradleSettings); - verify(adapter).init(eq(gradleLogger), eq(LOGGING_LEVEL), eq(true), anyString()); + verify(gradleLoggerAdapter).init(eq(gradleLogger), eq(LOGGING_LEVEL), eq(true), anyString()); verify(taskLoggingManager).getLevel(); - verifyNoMoreInteractions(task, taskLoggingManager, adapter, gradleSettings); + verifyNoMoreInteractions(task, taskLoggingManager, gradleLoggerAdapter, gradleSettings); } @Test @@ -86,13 +71,11 @@ void should_init_logger_before_task_execution_with_gradle_start_level() { when(task.getLogging()).thenReturn(taskLoggingManager); when(gradleSettings.getProjectLogLevel()).thenReturn(null); when(gradleSettings.getCommandLineLogLevel()).thenReturn(LOGGING_LEVEL); - when(extension.getVerboseModeEnabled()).thenReturn(verboseModeEnabled); - when(verboseModeEnabled.get()).thenReturn(true); - taskLoggerConfigurer.initLoggerAdapter(task); + TaskLoggerInitializer.initAdapter(task, true, gradleLoggerAdapter, gradleSettings); - verify(adapter).init(eq(gradleLogger), eq(LOGGING_LEVEL), eq(true), anyString()); + verify(gradleLoggerAdapter).init(eq(gradleLogger), eq(LOGGING_LEVEL), eq(true), anyString()); verify(taskLoggingManager).getLevel(); - verifyNoMoreInteractions(task, taskLoggingManager, adapter, gradleSettings); + verifyNoMoreInteractions(task, taskLoggingManager, gradleLoggerAdapter, gradleSettings); } } diff --git a/site/build.gradle.kts b/site/build.gradle.kts index ed9c9bc3..17688c4f 100644 --- a/site/build.gradle.kts +++ b/site/build.gradle.kts @@ -13,7 +13,7 @@ plugins { } frontend { - nodeVersion.set("20.12.2") + nodeVersion.set("20.14.0") assembleScript.set("run generate") cleanScript.set("run clean") publishScript.set("run deploy") diff --git a/site/src/components/faq/custom-environment-variables-faq.vue b/site/src/components/faq/custom-environment-variables-faq.vue new file mode 100644 index 00000000..0cd10713 --- /dev/null +++ b/site/src/components/faq/custom-environment-variables-faq.vue @@ -0,0 +1,14 @@ + diff --git a/site/src/components/gradle-scripts.vue b/site/src/components/gradle-scripts.vue index 597ed0d5..158bbd72 100644 --- a/site/src/components/gradle-scripts.vue +++ b/site/src/components/gradle-scripts.vue @@ -3,7 +3,7 @@