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

Make Gradle task to check if dependencies are sorted cacheable #115

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -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<String>

@get:Optional
@get:Option(option = "verbose", description = "Enables verbose logging.")
@get:Input
abstract val verbose: Property<Boolean>

@get:Optional
@get:Input
abstract val insertBlankLines: Property<Boolean>
}
Original file line number Diff line number Diff line change
@@ -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}.")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -27,10 +28,10 @@ class SortDependenciesPlugin : Plugin<Project> {
}

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 {
Expand All @@ -46,15 +47,26 @@ class SortDependenciesPlugin : Plugin<Project> {
}

private fun SortDependenciesTask.configure(
mode: String,
project: Project,
sortApp: Configuration,
extension: SortDependenciesExtension,
) {
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)
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<String>

@get:Input
abstract val mode: Property<String>

@get:Optional
@get:Option(option = "verbose", description = "Enables verbose logging.")
@get:Input
abstract val verbose: Property<Boolean>

@get:Optional
@get:Input
abstract val insertBlankLines: Property<Boolean>

@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"))

Expand All @@ -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")) {
Expand Down
Loading