Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix plugin not working if module has a lot of dependencies #50

Merged
merged 5 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions focus-gradle-plugin/api/focus-gradle-plugin.api
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public abstract class com/dropbox/focus/CreateFocusSettingsTask : org/gradle/api
public static final field Companion Lcom/dropbox/focus/CreateFocusSettingsTask$Companion;
public fun <init> ()V
public final fun createFocusSettings ()V
public abstract fun getModulesToDirMapFile ()Lorg/gradle/api/file/RegularFileProperty;
public abstract fun getSettingsFile ()Lorg/gradle/api/file/RegularFileProperty;
}

Expand Down Expand Up @@ -45,6 +46,7 @@ public final class com/dropbox/focus/FocusPlugin$apply$1$1$1$inlined$sam$i$org_g
public abstract class com/dropbox/focus/FocusSubExtension {
public fun <init> (Lorg/gradle/api/file/ProjectLayout;Lorg/gradle/api/model/ObjectFactory;)V
public final fun getFocusSettingsFile ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getModuleToDirMapFile ()Lorg/gradle/api/file/RegularFileProperty;
}

public abstract class com/dropbox/focus/FocusTask : org/gradle/api/DefaultTask {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.dropbox.focus
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.SelfResolvingDependency
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
Expand All @@ -15,6 +14,9 @@ public abstract class CreateFocusSettingsTask : DefaultTask() {
@get:OutputFile
public abstract val settingsFile: RegularFileProperty

@get:OutputFile
public abstract val modulesToDirMapFile: RegularFileProperty

init {
outputs.upToDateWhen { false }
}
Expand All @@ -23,29 +25,38 @@ public abstract class CreateFocusSettingsTask : DefaultTask() {
public fun createFocusSettings() {
val dependencies = project.collectDependencies().sortedBy { it.path }

// generate CSV mapping from module name to its absolute path
modulesToDirMapFile.get().asFile.writer().use { writer ->

dependencies
.forEach { dep ->
val projectPath = dep.path
val projectDir = dep.projectDir
writer.appendLine("$projectPath,$projectDir")
}
}

settingsFile.get().asFile.writer().use { writer ->
writer.write("// ${project.path} specific settings\n")
writer.appendLine("//")
writer.appendLine("// This file is autogenerated by the focus task. Changes will be overwritten.")
writer.appendLine()

// Add the includes statements
dependencies.forEach { dep ->
writer.appendLine("include(\"${dep.path}\")")
}

writer.appendLine()

// Add overrides for projects with a root that's different from the gradle path
dependencies
.forEach { dep ->
val gradleProjectPath = dep.path.substring(1).replace(":", "/")
if (project.rootDir.resolve(gradleProjectPath) != dep.projectDir) {
val gradleProjectDir = dep.projectDir.path.replace("\\", "\\\\")
// language=groovy
writer.appendLine("""project("${dep.path}").projectDir = new File('$gradleProjectDir')""")
// language=groovy
writer.append(
"""
File f = new File('${modulesToDirMapFile.get().asFile.absolutePath}')
if (f.exists()) {
f.eachLine { line ->
var values = line.split(",")
var module = values[0]
var path = values[1]
include(module)
project(module).projectDir = new File(path)
}
}
""".trimIndent()
)
}
}

Expand All @@ -71,6 +82,7 @@ public abstract class CreateFocusSettingsTask : DefaultTask() {
public operator fun invoke(subExtension: FocusSubExtension): CreateFocusSettingsTask.() -> Unit = {
group = FOCUS_TASK_GROUP
settingsFile.set(subExtension.focusSettingsFile)
modulesToDirMapFile.set(subExtension.moduleToDirMapFile)
notCompatibleWithConfigurationCache("This reads configurations from the project at action-time.")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ public abstract class FocusSubExtension @Inject constructor(
layout.buildDirectory.file("focus.settings.gradle")
)

public val moduleToDirMapFile: RegularFileProperty = objects.fileProperty().convention(
layout.buildDirectory.file("moduleToDirMap.csv")
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.dropbox.focus

import com.google.common.truth.Truth.assertThat
import java.io.File
import java.time.temporal.Temporal
import java.util.regex.Pattern
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import org.junit.Before
Expand Down Expand Up @@ -51,17 +51,46 @@ class FocusPluginTest {
}

@Test
fun singleQuotePath() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of replacing this test, can you add a new one? The single-quote test was intentionally introduced as part of resolving #25.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I restored the original test with some changes, take a look

val fixtureRoot = File("src/test/projects/single-quote-path")
fun allPathLiteralsAreSingleQuote() {
val fixtureRoot = File("src/test/projects/happy-path")
gradleRunner
.withArguments(":module:focus")
.runFixture(fixtureRoot) { build() }

val focusFileContent =
File("src/test/projects/happy-path/build/notnowhere/build/focus.settings.gradle").readText()
// has at least one single-quote path literal
assertThat(focusFileContent).matches(Pattern.compile(""".*new File\('.*'\).*""", Pattern.DOTALL))
// no double-quote path literals
assertThat(focusFileContent).doesNotMatch(Pattern.compile(""".*new File\(".*"\).*""", Pattern.DOTALL))
}

@Test
fun happyPath_CsvCreated() {
val fixtureRoot = File("src/test/projects/happy-path")

gradleRunner
.withArguments(":module:focus")
.runFixture(fixtureRoot) { build() }

val focusFileContent = File("src/test/projects/single-quote-path/build/notnowhere/build/focus.settings.gradle").readText()
val csvFileContents = File("src/test/projects/happy-path/build/notnowhere/build/moduleToDirMap.csv").readText()
val absoluteFilePath = fixtureRoot.resolve("build/notnowhere").absolutePath.replace("\\", "\\\\")
// language=csv
assertThat(csvFileContents).contains(""":module,$absoluteFilePath""")
}

@Test
fun happyPath_CsvRead() {
val fixtureRoot = File("src/test/projects/happy-path")

gradleRunner
.withArguments(":module:focus")
.runFixture(fixtureRoot) { build() }

val csvFilePath = File("src/test/projects/happy-path/build/notnowhere/build/moduleToDirMap.csv").absolutePath
val focusFileContent = File("src/test/projects/happy-path/build/notnowhere/build/focus.settings.gradle").readText()
// language=groovy
assertThat(focusFileContent).contains("""project(":module").projectDir = new File('$absoluteFilePath')""")
assertThat(focusFileContent).contains("""File f = new File('$csvFilePath')""")
}

private fun GradleRunner.runFixture(
Expand Down
Loading