diff --git a/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/BaseSortDependenciesTask.kt b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/BaseSortDependenciesTask.kt new file mode 100644 index 0000000..3f761ce --- /dev/null +++ b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/BaseSortDependenciesTask.kt @@ -0,0 +1,30 @@ +package com.squareup.sort + +import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Classpath +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.options.Option + +abstract class BaseSortDependenciesTask : DefaultTask() { + + @get:Classpath + @get:InputFiles + abstract val sortProgram: ConfigurableFileCollection + + /** The app version limits what options we can pass it. */ + @get:Input + abstract val version: Property + + @get:Optional + @get:Option(option = "verbose", description = "Enables verbose logging.") + @get:Input + abstract val verbose: Property + + @get:Optional + @get:Input + abstract val insertBlankLines: Property +} diff --git a/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/CheckSortDependenciesTask.kt b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/CheckSortDependenciesTask.kt new file mode 100644 index 0000000..b7f5581 --- /dev/null +++ b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/CheckSortDependenciesTask.kt @@ -0,0 +1,83 @@ +package com.squareup.sort + +import com.squareup.sort.internal.VersionNumber +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.tasks.* +import org.gradle.process.ExecOperations +import java.io.File +import java.nio.file.Path +import java.nio.file.Paths +import javax.inject.Inject + +@CacheableTask +abstract class CheckSortDependenciesTask @Inject constructor( + private val execOps: ExecOperations +) : BaseSortDependenciesTask() { + + init { + group = JavaBasePlugin.VERIFICATION_GROUP + description = "Checks if the dependencies block in a Gradle build script is sorted" + } + + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val buildScript: RegularFileProperty + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @TaskAction + fun action() { + val buildScript = buildScript.get().asFile.absolutePath + val verbose = verbose.getOrElse(false) + + logger.info("Checking if '$buildScript' is sorted.") + + val version = VersionNumber.parse(version.get().removeSuffix("-SNAPSHOT")) + + val result = execOps.exec { execSpec -> + execSpec.setIgnoreExitValue(true) + execSpec.commandLine = listOf( + "java", + "-cp", sortProgram.asPath, + "com.squareup.sort.MainKt", + buildScript, + "--mode", "check" + ) + + // Not really intended to be user-specified + if (version > VersionNumber.parse("0.8")) { + execSpec.args("--context", "gradle") + } + + if (verbose) { + if (version < VersionNumber.parse("0.3")) { + logger.warn("--verbose specified by version < 0.3. Ignoring flag.") + } else { + execSpec.args("--verbose") + } + } + } + + val resultText = when (result.exitValue) { + 0 -> "Dependencies are correctly sorted." + 2 -> "Dependencies are not correctly sorted." + 3 -> "There were parse errors." + else -> "The exit code ${result.exitValue} is not known." + } + + outputDirectory.asFile.get().mkdirs() + val outputPath : Path = Paths.get(outputDirectory.asFile.get().absolutePath, "result.txt") + File(outputPath.toUri()).writeText(resultText) + + if (result.exitValue == 2) { + throw VerificationException("Dependencies are not correctly sorted.") + } else if (result.exitValue == 3) { + throw RuntimeException("There were parse errors.") + } else if (result.exitValue > 0) { + throw RuntimeException("The command failed with exit code ${result.exitValue}.") + } + } +} diff --git a/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesPlugin.kt b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesPlugin.kt index bf38888..1874098 100644 --- a/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesPlugin.kt +++ b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesPlugin.kt @@ -3,6 +3,7 @@ package com.squareup.sort import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.ProjectLayout import org.gradle.language.base.plugins.LifecycleBasePlugin @Suppress("unused") @@ -27,10 +28,10 @@ class SortDependenciesPlugin : Plugin { } tasks.register("sortDependencies", SortDependenciesTask::class.java) { t -> - t.configure("sort", target, sortApp, extension) + t.configure(target, sortApp, extension) } - val checkTask = tasks.register("checkSortDependencies", SortDependenciesTask::class.java) { t -> - t.configure("check", target, sortApp, extension) + val checkTask = tasks.register("checkSortDependencies", CheckSortDependenciesTask::class.java) { t -> + t.configure(target, sortApp, layout, extension) } afterEvaluate { @@ -46,7 +47,6 @@ class SortDependenciesPlugin : Plugin { } private fun SortDependenciesTask.configure( - mode: String, project: Project, sortApp: Configuration, extension: SortDependenciesExtension, @@ -54,7 +54,19 @@ class SortDependenciesPlugin : Plugin { buildScript.set(project.buildFile) sortProgram.setFrom(sortApp) version.set(extension.version) - this.mode.set(mode) + insertBlankLines.set(extension.insertBlankLines) + } + + private fun CheckSortDependenciesTask.configure( + project: Project, + sortApp: Configuration, + layout: ProjectLayout, + extension: SortDependenciesExtension, + ) { + buildScript.set(project.buildFile) + sortProgram.setFrom(sortApp) + version.set(extension.version) + outputDirectory.set(layout.buildDirectory.dir("generated/sort-dependencies")) insertBlankLines.set(extension.insertBlankLines) } } diff --git a/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesTask.kt b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesTask.kt index bb7e651..660b863 100644 --- a/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesTask.kt +++ b/sort-dependencies-gradle-plugin/src/main/kotlin/com/squareup/sort/SortDependenciesTask.kt @@ -1,25 +1,15 @@ package com.squareup.sort import com.squareup.sort.internal.VersionNumber -import org.gradle.api.DefaultTask -import org.gradle.api.InvalidUserDataException -import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.RegularFileProperty import org.gradle.api.plugins.JavaBasePlugin -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Classpath -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.options.Option +import org.gradle.api.tasks.* import org.gradle.process.ExecOperations import javax.inject.Inject abstract class SortDependenciesTask @Inject constructor( private val execOps: ExecOperations -) : DefaultTask() { +) : BaseSortDependenciesTask() { init { group = JavaBasePlugin.VERIFICATION_GROUP @@ -34,37 +24,12 @@ abstract class SortDependenciesTask @Inject constructor( @get:Internal abstract val buildScript: RegularFileProperty - @get:Classpath - @get:InputFiles - abstract val sortProgram: ConfigurableFileCollection - - /** The app version limits what options we can pass it. */ - @get:Input - abstract val version: Property - - @get:Input - abstract val mode: Property - - @get:Optional - @get:Option(option = "verbose", description = "Enables verbose logging.") - @get:Input - abstract val verbose: Property - - @get:Optional - @get:Input - abstract val insertBlankLines: Property - @TaskAction fun action() { val buildScript = buildScript.get().asFile.absolutePath - val mode = mode.getOrElse("sort") val verbose = verbose.getOrElse(false) val insertBlankLines = insertBlankLines.getOrElse(true) - if (mode != "check" && mode != "sort") { - throw InvalidUserDataException("Mode must be 'sort' or 'check'. Was '$mode'.") - } - - logger.info("Sorting '$buildScript' using mode '$mode'.") + logger.info("Sorting '$buildScript'.") val version = VersionNumber.parse(version.get().removeSuffix("-SNAPSHOT")) @@ -74,7 +39,8 @@ abstract class SortDependenciesTask @Inject constructor( classpath = sortProgram args = buildList { add(buildScript) - option("--mode", mode) + add("--mode") + add("sort") // Not really intended to be user-specified if (version > VersionNumber.parse("0.8")) {