fix(gradle): add build-ci target even if atomized=false (#31537)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> when atomized=false, it does not generate build-ci and check-ci targets ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> - when atomized=false, it should still generate build-ci and check-ci targets - upgrade dev.nx.gradle.project-graph version to 0.1.2 ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
b89ca32a01
commit
3aa546ffe3
@ -2076,6 +2076,16 @@
|
||||
}
|
||||
},
|
||||
"migrations": {
|
||||
"/technologies/java/api/migrations/change-plugin-version-0-1-2": {
|
||||
"description": "Change dev.nx.gradle.project-graph to version 0.1.2 in build file",
|
||||
"file": "generated/packages/gradle/migrations/change-plugin-version-0-1-2.json",
|
||||
"hidden": false,
|
||||
"name": "change-plugin-version-0-1-2",
|
||||
"version": "21.3.0-beta.0",
|
||||
"originalFilePath": "/packages/gradle",
|
||||
"path": "/technologies/java/api/migrations/change-plugin-version-0-1-2",
|
||||
"type": "migration"
|
||||
},
|
||||
"/technologies/java/api/migrations/change-plugin-version-0-1-0": {
|
||||
"description": "Change dev.nx.gradle.project-graph to version 0.1.0 in build file",
|
||||
"file": "generated/packages/gradle/migrations/change-plugin-version-0-1-0.json",
|
||||
|
||||
@ -2249,6 +2249,16 @@
|
||||
}
|
||||
],
|
||||
"migrations": [
|
||||
{
|
||||
"description": "Change dev.nx.gradle.project-graph to version 0.1.2 in build file",
|
||||
"file": "generated/packages/gradle/migrations/change-plugin-version-0-1-2.json",
|
||||
"hidden": false,
|
||||
"name": "change-plugin-version-0-1-2",
|
||||
"version": "21.3.0-beta.0",
|
||||
"originalFilePath": "/packages/gradle",
|
||||
"path": "gradle/migrations/change-plugin-version-0-1-2",
|
||||
"type": "migration"
|
||||
},
|
||||
{
|
||||
"description": "Change dev.nx.gradle.project-graph to version 0.1.0 in build file",
|
||||
"file": "generated/packages/gradle/migrations/change-plugin-version-0-1-0.json",
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "change-plugin-version-0-1-2",
|
||||
"version": "21.3.0-beta.0",
|
||||
"cli": "nx",
|
||||
"description": "Change dev.nx.gradle.project-graph to version 0.1.2 in build file",
|
||||
"factory": "./src/migrations/21-3-0/change-plugin-version-0-1-2",
|
||||
"implementation": "/packages/gradle/src/migrations/21-3-0/change-plugin-version-0-1-2.ts",
|
||||
"aliases": [],
|
||||
"hidden": false,
|
||||
"path": "/packages/gradle",
|
||||
"schema": null,
|
||||
"type": "migration",
|
||||
"examplesFile": "#### Change dev.nx.gradle.project-graph to version 0.1.2\n\nChange dev.nx.gradle.project-graph to version 0.1.2 in build file\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```{% fileName=\"build.gradle\" %}\nplugins {\n\tid \"dev.nx.gradle.project-graph\" version \"0.1.0\"\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```{% fileName=\"build.gradle\" %}\nplugins {\n id \"dev.nx.gradle.project-graph\" version \"0.1.2\"\n}\n```\n\n{% /tab %}\n{% /tabs %}\n"
|
||||
}
|
||||
@ -35,6 +35,12 @@
|
||||
"cli": "nx",
|
||||
"description": "Change dev.nx.gradle.project-graph to version 0.1.0 in build file",
|
||||
"factory": "./src/migrations/21-1-2/change-plugin-version-0-1-0"
|
||||
},
|
||||
"change-plugin-version-0-1-2": {
|
||||
"version": "21.3.0-beta.0",
|
||||
"cli": "nx",
|
||||
"description": "Change dev.nx.gradle.project-graph to version 0.1.2 in build file",
|
||||
"factory": "./src/migrations/21-3-0/change-plugin-version-0-1-2"
|
||||
}
|
||||
},
|
||||
"packageJsonUpdates": {}
|
||||
|
||||
@ -10,7 +10,7 @@ plugins {
|
||||
|
||||
group = "dev.nx.gradle"
|
||||
|
||||
version = "0.0.1-alpha.6"
|
||||
version = "0.1.2"
|
||||
|
||||
repositories { mavenCentral() }
|
||||
|
||||
|
||||
@ -12,10 +12,13 @@ private val testFileNameRegex =
|
||||
Regex("^(?!(abstract|fake)).*?(Test)(s)?\\d*", RegexOption.IGNORE_CASE)
|
||||
|
||||
private val packageDeclarationRegex =
|
||||
Regex("""package\s+([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)""")
|
||||
Regex(
|
||||
"""^\s*package\s+([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)""",
|
||||
RegexOption.MULTILINE)
|
||||
private val classDeclarationRegex =
|
||||
Regex("""^\s*(?:@[\w]+)?\s*(class|object)\s+([A-Za-z_][A-Za-z0-9_]*)""")
|
||||
private val privateClassRegex = Regex("""\bprivate\s+(class|object)\s+([A-Za-z_][A-Za-z0-9_]*)""")
|
||||
Regex(
|
||||
"""^\s*(?:@[\w]+\s*)*(?:public|protected|internal|open|sealed|final|data|enum|annotation)?\s*(class)\s+([A-Za-z_][A-Za-z0-9_]*)""")
|
||||
private val privateClassRegex = Regex("""\bprivate\s+class\s+([A-Za-z_][A-Za-z0-9_]*)""")
|
||||
|
||||
// Essential annotations (most common subset)
|
||||
private val essentialTestAnnotations =
|
||||
|
||||
@ -84,8 +84,8 @@ fun processTargetsForProject(
|
||||
|
||||
val testTasks = project.getTasksByName("test", false)
|
||||
val intTestTasks = project.getTasksByName("intTest", false)
|
||||
val hasCiTestTarget = ciTestTargetName != null && testTasks.isNotEmpty()
|
||||
val hasCiIntTestTarget = ciIntTestTargetName != null && intTestTasks.isNotEmpty()
|
||||
val hasCiTestTarget = ciTestTargetName != null && testTasks.isNotEmpty() && atomized
|
||||
val hasCiIntTestTarget = ciIntTestTargetName != null && intTestTasks.isNotEmpty() && atomized
|
||||
|
||||
project.tasks.forEach { task ->
|
||||
try {
|
||||
@ -111,7 +111,7 @@ fun processTargetsForProject(
|
||||
|
||||
targets[taskName] = target
|
||||
|
||||
if (hasCiTestTarget && task.name.startsWith("compileTest") && atomized) {
|
||||
if (hasCiTestTarget && task.name.startsWith("compileTest")) {
|
||||
addTestCiTargets(
|
||||
task.inputs.sourceFiles,
|
||||
projectBuildPath,
|
||||
@ -124,7 +124,7 @@ fun processTargetsForProject(
|
||||
ciTestTargetName!!)
|
||||
}
|
||||
|
||||
if (hasCiIntTestTarget && task.name.startsWith("compileIntTest") && atomized) {
|
||||
if (hasCiIntTestTarget && task.name.startsWith("compileIntTest")) {
|
||||
addTestCiTargets(
|
||||
task.inputs.sourceFiles,
|
||||
projectBuildPath,
|
||||
@ -137,23 +137,22 @@ fun processTargetsForProject(
|
||||
ciIntTestTargetName!!)
|
||||
}
|
||||
|
||||
val ciCheckTargetName = targetNameOverrides.getOrDefault("ciCheckTargetName", "check-ci")
|
||||
if (task.name == "check") {
|
||||
val replacedDependencies =
|
||||
(target["dependsOn"] as? List<*>)?.map { dep ->
|
||||
val dependsOn = dep.toString()
|
||||
if (hasCiTestTarget && dependsOn == "${project.name}:$testTargetName" && atomized) {
|
||||
"${project.name}:$ciTestTargetName"
|
||||
} else if (hasCiIntTestTarget &&
|
||||
dependsOn == "${project.name}:$intTestTargetName" &&
|
||||
atomized) {
|
||||
"${project.name}:$ciIntTestTargetName"
|
||||
} else {
|
||||
dep
|
||||
}
|
||||
} ?: emptyList()
|
||||
if (ciTestTargetName != null || ciIntTestTargetName != null) {
|
||||
val ciCheckTargetName = targetNameOverrides.getOrDefault("ciCheckTargetName", "check-ci")
|
||||
if (task.name == "check") {
|
||||
val replacedDependencies =
|
||||
(target["dependsOn"] as? List<*>)?.map { dep ->
|
||||
val dependsOn = dep.toString()
|
||||
if (hasCiTestTarget && dependsOn == "${project.name}:$testTargetName") {
|
||||
"${project.name}:$ciTestTargetName"
|
||||
} else if (hasCiIntTestTarget &&
|
||||
dependsOn == "${project.name}:$intTestTargetName") {
|
||||
"${project.name}:$ciIntTestTargetName"
|
||||
} else {
|
||||
dep
|
||||
}
|
||||
} ?: emptyList()
|
||||
|
||||
if (atomized) {
|
||||
val newTarget: MutableMap<String, Any?> =
|
||||
mutableMapOf(
|
||||
"dependsOn" to replacedDependencies,
|
||||
@ -165,21 +164,19 @@ fun processTargetsForProject(
|
||||
ensureTargetGroupExists(targetGroups, testCiTargetGroup)
|
||||
targetGroups[testCiTargetGroup]?.add(ciCheckTargetName)
|
||||
}
|
||||
}
|
||||
|
||||
if (task.name == "build") {
|
||||
val ciBuildTargetName = targetNameOverrides.getOrDefault("ciBuildTargetName", "build-ci")
|
||||
val replacedDependencies =
|
||||
(target["dependsOn"] as? List<*>)?.map { dep ->
|
||||
val dependsOn = dep.toString()
|
||||
if (dependsOn == "${project.name}:check" && atomized) {
|
||||
"${project.name}:$ciCheckTargetName"
|
||||
} else {
|
||||
dep
|
||||
}
|
||||
} ?: emptyList()
|
||||
if (task.name == "build") {
|
||||
val ciBuildTargetName = targetNameOverrides.getOrDefault("ciBuildTargetName", "build-ci")
|
||||
val replacedDependencies =
|
||||
(target["dependsOn"] as? List<*>)?.map { dep ->
|
||||
val dependsOn = dep.toString()
|
||||
if (dependsOn == "${project.name}:check") {
|
||||
"${project.name}:$ciCheckTargetName"
|
||||
} else {
|
||||
dep
|
||||
}
|
||||
} ?: emptyList()
|
||||
|
||||
if (atomized) {
|
||||
val newTarget: MutableMap<String, Any?> =
|
||||
mutableMapOf(
|
||||
"dependsOn" to replacedDependencies,
|
||||
@ -199,5 +196,6 @@ fun processTargetsForProject(
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Final targets in processTargetsForProject: $targets")
|
||||
return GradleTargets(targets, targetGroups, externalNodes)
|
||||
}
|
||||
|
||||
@ -9,6 +9,10 @@ class ClassDetectionTest {
|
||||
fun `detects top-level and annotated nested classes only`() {
|
||||
val kotlinSource =
|
||||
"""
|
||||
import some.package
|
||||
|
||||
package real.package
|
||||
|
||||
class ClassA {
|
||||
@Nested
|
||||
class ClassB
|
||||
@ -18,6 +22,10 @@ class ClassDetectionTest {
|
||||
private class ClassD
|
||||
}
|
||||
|
||||
internal class ClassU
|
||||
|
||||
public abstract class ClassV
|
||||
|
||||
@Nested
|
||||
class ClassX // not nested — should be ignored
|
||||
|
||||
@ -36,7 +44,11 @@ class ClassDetectionTest {
|
||||
val result = getAllVisibleClassesWithNestedAnnotation(tempFile)
|
||||
|
||||
// Expected output
|
||||
val expected = mapOf("ClassAClassB" to "ClassA\$ClassB", "ClassZ" to "ClassZ")
|
||||
val expected =
|
||||
mapOf(
|
||||
"ClassAClassB" to "real.package.ClassA\$ClassB",
|
||||
"ClassU" to "real.package.ClassU",
|
||||
"ClassZ" to "real.package.ClassZ")
|
||||
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package dev.nx.gradle.utils
|
||||
|
||||
import dev.nx.gradle.data.*
|
||||
import java.io.File
|
||||
import kotlin.test.*
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
@ -11,7 +10,7 @@ class CreateNodeForProjectTest {
|
||||
fun `should return GradleNodeReport with targets and metadata`() {
|
||||
// Arrange
|
||||
val workspaceRoot = createTempDir("workspace").absolutePath
|
||||
val projectDir = createTempDir("project")
|
||||
val projectDir = File(workspaceRoot, "project-a").apply { mkdirs() }
|
||||
val project = ProjectBuilder.builder().withProjectDir(projectDir).build()
|
||||
|
||||
// Create a couple of dummy tasks
|
||||
@ -51,104 +50,4 @@ class CreateNodeForProjectTest {
|
||||
assertTrue(result.dependencies.isEmpty(), "Expected no dependencies")
|
||||
assertTrue(result.externalNodes.isEmpty(), "Expected no external nodes")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should not generate atomized targets when atomized is false`() {
|
||||
// Arrange
|
||||
val workspaceRoot = createTempDir("workspace").absolutePath
|
||||
val projectDir = createTempDir("project")
|
||||
val project = ProjectBuilder.builder().withProjectDir(projectDir).build()
|
||||
|
||||
// Create tasks that would normally trigger atomized targets
|
||||
val testFile1 =
|
||||
File(projectDir, "src/test/kotlin/MyFirstTest.kt").apply {
|
||||
parentFile.mkdirs()
|
||||
writeText("@Test class MyFirstTest")
|
||||
}
|
||||
|
||||
val testTask =
|
||||
project.task("test").apply {
|
||||
group = "verification"
|
||||
description = "Runs the tests"
|
||||
inputs.files(project.files(testFile1))
|
||||
}
|
||||
project
|
||||
.task("compileTestKotlin")
|
||||
.dependsOn(testTask) // This task name triggers ci test target logic
|
||||
|
||||
val checkTask =
|
||||
project.task("check").apply {
|
||||
group = "verification"
|
||||
description = "Runs all checks"
|
||||
dependsOn(testTask)
|
||||
}
|
||||
project.task("build").apply {
|
||||
group = "build"
|
||||
description = "Assembles and tests"
|
||||
dependsOn(checkTask)
|
||||
}
|
||||
|
||||
val targetNameOverrides =
|
||||
mapOf(
|
||||
"ciTestTargetName" to "ci-test",
|
||||
"ciCheckTargetName" to "ci-check",
|
||||
"ciBuildTargetName" to "ci-build")
|
||||
|
||||
// Act
|
||||
val result =
|
||||
createNodeForProject(
|
||||
project = project,
|
||||
targetNameOverrides = targetNameOverrides,
|
||||
workspaceRoot = workspaceRoot,
|
||||
atomized = false) // Test with atomized = false
|
||||
|
||||
// Assert
|
||||
val projectRoot = project.projectDir.absolutePath
|
||||
val projectNode = result.nodes[projectRoot]
|
||||
assertNotNull(projectNode, "ProjectNode should not be null")
|
||||
|
||||
// Verify that individual atomized targets are NOT created
|
||||
assertFalse(
|
||||
projectNode.targets.containsKey("ci--MyFirstTest"),
|
||||
"Expected ci--MyFirstTest target NOT to be present")
|
||||
|
||||
// Verify 'test' and 'check' targets are present but not their 'ci' counterparts if atomized is
|
||||
// false
|
||||
assertNotNull(projectNode.targets["test"], "Expected 'test' target to be present")
|
||||
assertNotNull(projectNode.targets["check"], "Expected 'check' target to be present")
|
||||
assertNotNull(projectNode.targets["build"], "Expected 'build' target to be present")
|
||||
|
||||
// Verify that 'ci-test', 'ci-check', 'ci-build' are not created as main targets if atomized is
|
||||
// false
|
||||
assertFalse(
|
||||
projectNode.targets.containsKey("ci-test"),
|
||||
"Expected ci-test target NOT to be present as a main target")
|
||||
assertFalse(
|
||||
projectNode.targets.containsKey("ci-check"),
|
||||
"Expected ci-check target NOT to be present as a main target")
|
||||
assertFalse(
|
||||
projectNode.targets.containsKey("ci-build"),
|
||||
"Expected ci-build target NOT to be present as a main target")
|
||||
|
||||
// Verify dependencies are NOT rewritten for 'check' and 'build' tasks
|
||||
val checkTarget = projectNode.targets["check"]
|
||||
assertNotNull(checkTarget, "Check target should exist")
|
||||
val checkDependsOn = checkTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(checkDependsOn, "Check dependsOn should not be null")
|
||||
assertTrue(
|
||||
checkDependsOn.contains("${project.name}:test"), "Expected 'check' to depend on 'test'")
|
||||
assertFalse(
|
||||
checkDependsOn.contains("${project.name}:ci-test"),
|
||||
"Expected 'check' NOT to depend on 'ci-test'")
|
||||
|
||||
val buildTarget = projectNode.targets["build"]
|
||||
assertNotNull(buildTarget, "Build target should exist")
|
||||
val buildDependsOn = buildTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(buildDependsOn, "Build dependsOn should not be null")
|
||||
assertTrue(
|
||||
buildDependsOn.contains("${project.name}:check"), "Expected 'build' to depend on 'check'")
|
||||
assertFalse(
|
||||
buildDependsOn.contains("${project.name}:ci-check"),
|
||||
"Expected 'build' NOT to depend on 'ci-check'")
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,226 @@
|
||||
package dev.nx.gradle.utils
|
||||
|
||||
import dev.nx.gradle.data.*
|
||||
import java.io.File
|
||||
import kotlin.test.*
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
|
||||
class ProcessTargetsForProjectTest {
|
||||
|
||||
@Test
|
||||
fun `should process targets correctly when atomized is true`() {
|
||||
// Arrange
|
||||
val workspaceRoot = createTempDir("workspace").absolutePath
|
||||
val projectDir = File(workspaceRoot, "project-a").apply { mkdirs() }
|
||||
val project = ProjectBuilder.builder().withProjectDir(projectDir).build()
|
||||
|
||||
// Create tasks that would normally trigger atomized targets
|
||||
val testFile1 =
|
||||
File(projectDir, "src/test/kotlin/MyFirstTest.kt").apply {
|
||||
parentFile.mkdirs()
|
||||
writeText("@Test class MyFirstTest")
|
||||
}
|
||||
|
||||
val testTask =
|
||||
project.task("test").apply {
|
||||
group = "verification"
|
||||
description = "Runs the tests"
|
||||
inputs.files(project.files(testFile1))
|
||||
}
|
||||
project.task("compileTestKotlin").apply { inputs.files(project.files(testFile1)) }
|
||||
|
||||
val checkTask =
|
||||
project.task("check").apply {
|
||||
group = "verification"
|
||||
description = "Runs all checks"
|
||||
dependsOn(testTask)
|
||||
}
|
||||
project.task("build").apply {
|
||||
group = "build"
|
||||
description = "Assembles and tests"
|
||||
dependsOn(checkTask)
|
||||
}
|
||||
|
||||
val targetNameOverrides =
|
||||
mapOf(
|
||||
"ciTestTargetName" to "ci-test",
|
||||
"ciCheckTargetName" to "ci-check",
|
||||
"ciBuildTargetName" to "ci-build")
|
||||
|
||||
val dependencies = mutableSetOf<Dependency>() // Empty for this test's scope
|
||||
|
||||
// Act
|
||||
val gradleTargets =
|
||||
processTargetsForProject(
|
||||
project = project,
|
||||
dependencies = dependencies,
|
||||
targetNameOverrides = targetNameOverrides,
|
||||
workspaceRoot = workspaceRoot,
|
||||
atomized = true)
|
||||
|
||||
// Assert
|
||||
// Verify 'ci-test' should not be presented
|
||||
// But 'ci-check' and 'ci-build' targets should be present in the returned targets
|
||||
assertNull(
|
||||
gradleTargets.targets["ci-test"],
|
||||
"Expected ci-test target to NOT be present in processed targets")
|
||||
assertNotNull(
|
||||
gradleTargets.targets["ci-check"],
|
||||
"Expected ci-check target to be present in processed targets")
|
||||
assertNotNull(
|
||||
gradleTargets.targets["ci-build"],
|
||||
"Expected ci-build target to be present in processed targets")
|
||||
|
||||
// Verify dependencies are rewritten for 'check' and 'build' tasks in the returned targets
|
||||
val checkTarget = gradleTargets.targets["check"]
|
||||
assertNotNull(checkTarget, "Check target should exist in processed targets")
|
||||
val checkDependsOn = checkTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(checkDependsOn, "Check dependsOn should not be null in processed targets")
|
||||
assertTrue(
|
||||
checkDependsOn.contains("${project.name}:test"),
|
||||
"Expected 'check' to depend on 'test' in processed targets")
|
||||
|
||||
val checkCiTarget = gradleTargets.targets["ci-check"]
|
||||
assertNotNull(checkCiTarget, "Check CI target should exist in processed targets")
|
||||
val checkCiDependsOn = checkCiTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(checkCiDependsOn, "Check CI dependsOn should not be null in processed targets")
|
||||
assertTrue(
|
||||
checkCiDependsOn.contains("${project.name}:ci-test"),
|
||||
"Expected 'ci-check' to depend on 'ci-test' in processed targets")
|
||||
|
||||
val buildTarget = gradleTargets.targets["build"]
|
||||
assertNotNull(buildTarget, "Build target should exist in processed targets")
|
||||
val buildDependsOn = buildTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(buildDependsOn, "Build dependsOn should not be null in processed targets")
|
||||
assertTrue(
|
||||
buildDependsOn.contains("${project.name}:check"),
|
||||
"Expected 'build' to depend on 'check' in processed targets")
|
||||
|
||||
val buildCiTarget = gradleTargets.targets["ci-build"]
|
||||
assertNotNull(buildCiTarget, "Build CI target should exist in processed targets")
|
||||
val buildCiDependsOn = buildCiTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(buildCiDependsOn, "Build CI dependsOn should not be null in processed targets")
|
||||
assertTrue(
|
||||
buildCiDependsOn.contains("${project.name}:ci-check"),
|
||||
"Expected 'ci-build' to depend on 'ci-check' in processed targets")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should process targets correctly when atomized is false`() {
|
||||
// Arrange
|
||||
val workspaceRoot = createTempDir("workspace").absolutePath
|
||||
val projectDir = File(workspaceRoot, "project-a").apply { mkdirs() }
|
||||
val project = ProjectBuilder.builder().withProjectDir(projectDir).build()
|
||||
|
||||
// Create tasks that would normally trigger atomized targets
|
||||
val testFile1 =
|
||||
File(projectDir, "src/test/kotlin/MyFirstTest.kt").apply {
|
||||
parentFile.mkdirs()
|
||||
writeText("@Test class MyFirstTest")
|
||||
}
|
||||
|
||||
val testTask =
|
||||
project.task("test").apply {
|
||||
group = "verification"
|
||||
description = "Runs the tests"
|
||||
inputs.files(project.files(testFile1))
|
||||
}
|
||||
project
|
||||
.task("compileTestKotlin")
|
||||
.dependsOn(testTask) // This task name triggers ci test target logic
|
||||
|
||||
val checkTask =
|
||||
project.task("check").apply {
|
||||
group = "verification"
|
||||
description = "Runs all checks"
|
||||
dependsOn(testTask)
|
||||
}
|
||||
project.task("build").apply {
|
||||
group = "build"
|
||||
description = "Assembles and tests"
|
||||
dependsOn(checkTask)
|
||||
}
|
||||
|
||||
val targetNameOverrides =
|
||||
mapOf(
|
||||
"ciTestTargetName" to "ci-test",
|
||||
"ciCheckTargetName" to "ci-check",
|
||||
"ciBuildTargetName" to "ci-build")
|
||||
|
||||
val dependencies = mutableSetOf<Dependency>() // Empty for this test's scope
|
||||
|
||||
// Act
|
||||
val gradleTargets =
|
||||
processTargetsForProject(
|
||||
project = project,
|
||||
dependencies = dependencies,
|
||||
targetNameOverrides = targetNameOverrides,
|
||||
workspaceRoot = workspaceRoot,
|
||||
atomized = false) // Test with atomized = false
|
||||
|
||||
// Assert
|
||||
// Verify that individual atomized targets are NOT created
|
||||
assertFalse(
|
||||
gradleTargets.targets.containsKey("ci--MyFirstTest"),
|
||||
"Expected ci--MyFirstTest target NOT to be present in processed targets")
|
||||
|
||||
// Verify 'test' and 'check' targets are present but not their 'ci' counterparts if atomized is
|
||||
// false
|
||||
assertNotNull(gradleTargets.targets["test"], "Expected 'test' target to be present")
|
||||
assertNotNull(gradleTargets.targets["check"], "Expected 'check' target to be present")
|
||||
assertNotNull(gradleTargets.targets["build"], "Expected 'build' target to be present")
|
||||
|
||||
// Verify that 'ci-test' is not created as main targets if atomized is false
|
||||
// 'ci-check' and 'ci-build should still be presented if ciTestTargetName is presented
|
||||
// regardless of atomized value
|
||||
assertFalse(
|
||||
gradleTargets.targets.containsKey("ci-test"),
|
||||
"Expected ci-test target NOT to be present as a main target")
|
||||
assertTrue(
|
||||
gradleTargets.targets.containsKey("ci-check"),
|
||||
"Expected ci-check target to be present as a main target")
|
||||
assertTrue(
|
||||
gradleTargets.targets.containsKey("ci-build"),
|
||||
"Expected ci-build target to be present as a main target")
|
||||
|
||||
// Verify dependencies are NOT rewritten for 'check' and 'build' tasks
|
||||
val checkTarget = gradleTargets.targets["check"]
|
||||
assertNotNull(checkTarget, "Check target should exist")
|
||||
val checkDependsOn = checkTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(checkDependsOn, "Check dependsOn should not be null")
|
||||
assertTrue(
|
||||
checkDependsOn.contains("${project.name}:test"), "Expected 'check' to depend on 'test'")
|
||||
assertFalse(
|
||||
checkDependsOn.contains("${project.name}:ci-test"),
|
||||
"Expected 'check' NOT to depend on 'ci-test'")
|
||||
|
||||
val checkCiTarget = gradleTargets.targets["ci-check"]
|
||||
assertNotNull(checkCiTarget, "Check CI target should exist in processed targets")
|
||||
val checkCiDependsOn = checkCiTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(checkCiDependsOn, "Check CI dependsOn should not be null in processed targets")
|
||||
assertFalse(
|
||||
checkCiDependsOn.contains("${project.name}:ci-test"),
|
||||
"Expected 'ci-check' to NOT depend on 'ci-test' in processed targets")
|
||||
assertTrue(
|
||||
checkCiDependsOn.contains("${project.name}:test"),
|
||||
"Expected 'ci-check' to depend on 'test' in processed targets")
|
||||
|
||||
val buildTarget = gradleTargets.targets["build"]
|
||||
assertNotNull(buildTarget, "Build target should exist")
|
||||
val buildDependsOn = buildTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(buildDependsOn, "Build dependsOn should not be null")
|
||||
assertTrue(
|
||||
buildDependsOn.contains("${project.name}:check"), "Expected 'build' to depend on 'check'")
|
||||
assertFalse(
|
||||
buildDependsOn.contains("${project.name}:ci-check"),
|
||||
"Expected 'build' NOT to depend on 'ci-check'")
|
||||
|
||||
val buildCiTarget = gradleTargets.targets["ci-build"]
|
||||
assertNotNull(buildCiTarget, "Build CI target should exist in processed targets")
|
||||
val buildCiDependsOn = buildCiTarget["dependsOn"] as? List<*>
|
||||
assertNotNull(buildCiDependsOn, "Build CI dependsOn should not be null in processed targets")
|
||||
assertTrue(
|
||||
buildCiDependsOn.contains("${project.name}:ci-check"),
|
||||
"Expected 'ci-build' to depend on 'ci-check' in processed targets")
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
#### Change dev.nx.gradle.project-graph to version 0.1.2
|
||||
|
||||
Change dev.nx.gradle.project-graph to version 0.1.2 in build file
|
||||
|
||||
#### Sample Code Changes
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Before" %}
|
||||
|
||||
```{% fileName="build.gradle" %}
|
||||
plugins {
|
||||
id "dev.nx.gradle.project-graph" version "0.1.0"
|
||||
}
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% tab label="After" %}
|
||||
|
||||
```{% fileName="build.gradle" %}
|
||||
plugins {
|
||||
id "dev.nx.gradle.project-graph" version "0.1.2"
|
||||
}
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
@ -0,0 +1,128 @@
|
||||
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
|
||||
import { Tree } from '@nx/devkit';
|
||||
import { FsTree } from 'nx/src/generators/tree';
|
||||
import update from './change-plugin-version-0-1-2';
|
||||
import { gradleProjectGraphPluginName } from '../../utils/versions';
|
||||
|
||||
describe('change-plugin-version-0-1-2 migration', () => {
|
||||
let tempFs: TempFs;
|
||||
let cwd: string;
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempFs = new TempFs('test');
|
||||
cwd = process.cwd();
|
||||
process.chdir(tempFs.tempDir);
|
||||
tree = new FsTree(tempFs.tempDir, false);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetModules();
|
||||
process.chdir(cwd);
|
||||
});
|
||||
|
||||
it('should update plugin version to 0.1.2 in Groovy DSL', async () => {
|
||||
await tempFs.createFiles({
|
||||
'nx.json': JSON.stringify({
|
||||
plugins: ['@nx/gradle'],
|
||||
}),
|
||||
'proj/settings.gradle': '',
|
||||
'proj/build.gradle': `plugins {
|
||||
id 'java'
|
||||
id "${gradleProjectGraphPluginName}" version "0.0.1"
|
||||
}`,
|
||||
});
|
||||
|
||||
await update(tree);
|
||||
|
||||
const content = tree.read('proj/build.gradle', 'utf-8');
|
||||
expect(content).toContain(
|
||||
`id "${gradleProjectGraphPluginName}" version "0.1.2"`
|
||||
);
|
||||
expect(content).not.toContain('version "0.0.1"');
|
||||
});
|
||||
|
||||
it('should update plugin version to 0.1.2 in Kotlin DSL', async () => {
|
||||
await tempFs.createFiles({
|
||||
'nx.json': JSON.stringify({
|
||||
plugins: ['@nx/gradle'],
|
||||
}),
|
||||
'proj/settings.gradle.kts': '',
|
||||
'proj/build.gradle.kts': `plugins {
|
||||
id("java")
|
||||
id("${gradleProjectGraphPluginName}") version("0.0.1")
|
||||
}`,
|
||||
});
|
||||
|
||||
await update(tree);
|
||||
|
||||
const content = tree.read('proj/build.gradle.kts', 'utf-8');
|
||||
expect(content).toContain(
|
||||
`id("${gradleProjectGraphPluginName}") version("0.1.2")`
|
||||
);
|
||||
expect(content).not.toContain('version("0.0.1")');
|
||||
});
|
||||
|
||||
it('should not update if nx.json is missing', async () => {
|
||||
await tempFs.createFiles({
|
||||
'proj/settings.gradle': '',
|
||||
'proj/build.gradle': `plugins {
|
||||
id 'java'
|
||||
id "${gradleProjectGraphPluginName}" version "0.0.1"
|
||||
}`,
|
||||
});
|
||||
|
||||
await update(tree);
|
||||
|
||||
const content = tree.read('proj/build.gradle', 'utf-8');
|
||||
expect(content).toContain('version "0.0.1"');
|
||||
expect(content).not.toContain('version "0.1.2"');
|
||||
});
|
||||
|
||||
it('should not update if Gradle plugin is not present', async () => {
|
||||
await tempFs.createFiles({
|
||||
'nx.json': JSON.stringify({}),
|
||||
'proj/settings.gradle': '',
|
||||
'proj/build.gradle': `plugins {
|
||||
id 'java'
|
||||
}`,
|
||||
});
|
||||
|
||||
await update(tree);
|
||||
|
||||
const content = tree.read('proj/build.gradle', 'utf-8');
|
||||
expect(content).not.toContain(gradleProjectGraphPluginName);
|
||||
});
|
||||
|
||||
it('should handle multiple build.gradle files', async () => {
|
||||
await tempFs.createFiles({
|
||||
'nx.json': JSON.stringify({
|
||||
plugins: ['@nx/gradle'],
|
||||
}),
|
||||
'proj1/settings.gradle': '',
|
||||
'proj1/build.gradle': `plugins {
|
||||
id 'java'
|
||||
id "${gradleProjectGraphPluginName}" version "0.0.1"
|
||||
}`,
|
||||
'proj2/settings.gradle': '',
|
||||
'proj2/build.gradle': `plugins {
|
||||
id 'java'
|
||||
id "${gradleProjectGraphPluginName}" version "0.0.1"
|
||||
}`,
|
||||
});
|
||||
|
||||
await update(tree);
|
||||
|
||||
const proj1Content = tree.read('proj1/build.gradle', 'utf-8');
|
||||
const proj2Content = tree.read('proj2/build.gradle', 'utf-8');
|
||||
|
||||
expect(proj1Content).toContain(
|
||||
`id "${gradleProjectGraphPluginName}" version "0.1.2"`
|
||||
);
|
||||
expect(proj2Content).toContain(
|
||||
`id "${gradleProjectGraphPluginName}" version "0.1.2"`
|
||||
);
|
||||
expect(proj1Content).not.toContain('version "0.0.1"');
|
||||
expect(proj2Content).not.toContain('version "0.0.1"');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,16 @@
|
||||
import { Tree, readNxJson } from '@nx/devkit';
|
||||
import { hasGradlePlugin } from '../../utils/has-gradle-plugin';
|
||||
import { addNxProjectGraphPlugin } from '../../generators/init/gradle-project-graph-plugin-utils';
|
||||
|
||||
/* Change the plugin version to 0.1.2
|
||||
*/
|
||||
export default async function update(tree: Tree) {
|
||||
const nxJson = readNxJson(tree);
|
||||
if (!nxJson) {
|
||||
return;
|
||||
}
|
||||
if (!hasGradlePlugin(tree)) {
|
||||
return;
|
||||
}
|
||||
await addNxProjectGraphPlugin(tree, '0.1.2');
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user