-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add api linter gradle plugin * Optimized code * Optimize code * Optimize code Co-authored-by: Kanro <[email protected]>
- Loading branch information
Showing
11 changed files
with
204 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
tools | ||
|
||
plugins { | ||
`java-library` | ||
`java-gradle-plugin` | ||
id("com.gradle.plugin-publish") | ||
} | ||
|
||
description = "Runner and executable manager for Google API Linter on java" |
70 changes: 70 additions & 0 deletions
70
...phus-api-linter-runner/src/main/kotlin/com/bybutter/sisyphus/apilinter/ApiLinterRunner.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.bybutter.sisyphus.apilinter | ||
|
||
import java.io.BufferedReader | ||
import java.nio.file.Files | ||
import java.nio.file.Path | ||
import java.nio.file.Paths | ||
import java.nio.file.attribute.PosixFilePermission | ||
|
||
class ApiLinterRunner { | ||
|
||
fun runApiLinter(args: List<String>, version: String): String? { | ||
val apiLinterTemp = extractApiLinter(version) | ||
return executeCmd(apiLinterTemp.toString(), args) | ||
} | ||
|
||
private fun executeCmd(cmd: String, args: List<String>): String { | ||
val apiLinterCmd = mutableListOf(cmd) | ||
for (arg in args) { | ||
apiLinterCmd.add(arg) | ||
} | ||
println("api-linter executing: $apiLinterCmd") | ||
val process = ProcessBuilder(apiLinterCmd).start() | ||
val result = process.text() | ||
process.waitFor() | ||
return result | ||
} | ||
|
||
private fun extractApiLinter(version: String): Path { | ||
val osName = System.getProperties().getProperty("os.name").normalize() | ||
val platform = detectPlatform(osName) | ||
val srcFilePath = Paths.get(version, "api-linter-$version-$platform.exe").toString() | ||
val srcFile = this.javaClass.classLoader.getResource(srcFilePath) | ||
?: throw UnsupportedOperationException("Unsupported api linter version $version or platform $osName.") | ||
val executable = createTempBinDir().resolve("apilinter.exe") | ||
srcFile.openStream().use { | ||
Files.copy(it, executable) | ||
} | ||
Files.setPosixFilePermissions(executable, setOf(PosixFilePermission.OWNER_EXECUTE)) | ||
return executable.also { | ||
it.toFile().deleteOnExit() | ||
} | ||
} | ||
|
||
private fun detectPlatform(osName: String): String { | ||
return when { | ||
(osName.startsWith("macosx") || osName.startsWith("osx")) -> "darwin" | ||
osName.startsWith("linux") -> "linux" | ||
osName.startsWith("windows") -> "windows" | ||
else -> "unknown" | ||
} | ||
} | ||
|
||
private fun String.normalize(): String { | ||
return this.toLowerCase().replace("[^a-z0-9]+".toRegex(), "") | ||
} | ||
|
||
private fun createTempBinDir(): Path { | ||
return Files.createTempDirectory("apilinterrun").also { | ||
it.toFile().deleteOnExit() | ||
} | ||
} | ||
|
||
private fun Process.text(): String { | ||
return this.inputStream.bufferedReader().use(BufferedReader::readText) | ||
} | ||
|
||
companion object { | ||
const val API_LINTER_DEFAULT_VERSION = "1.1.0" | ||
} | ||
} |
Binary file added
BIN
+18.4 MB
tools/sisyphus-api-linter-runner/src/main/resources/1.1.0/api-linter-1.1.0-darwin.exe
Binary file not shown.
Binary file added
BIN
+18.6 MB
tools/sisyphus-api-linter-runner/src/main/resources/1.1.0/api-linter-1.1.0-linux.exe
Binary file not shown.
Binary file added
BIN
+18.2 MB
tools/sisyphus-api-linter-runner/src/main/resources/1.1.0/api-linter-1.1.0-windows.exe
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 85 additions & 1 deletion
86
...radle-plugin/src/main/kotlin/com/bybutter/sisyphus/protobuf/gradle/ProtobufApiLintTask.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,89 @@ | ||
package com.bybutter.sisyphus.protobuf.gradle | ||
|
||
import com.bybutter.sisyphus.apilinter.ApiLinterRunner | ||
import com.bybutter.sisyphus.jackson.parseJson | ||
import com.fasterxml.jackson.annotation.JsonProperty | ||
import java.io.File | ||
import java.nio.file.Files | ||
import java.nio.file.Paths | ||
import org.gradle.api.tasks.InputDirectory | ||
import org.gradle.api.tasks.Internal | ||
import org.gradle.api.tasks.SourceTask | ||
import org.gradle.api.tasks.TaskAction | ||
|
||
open class ProtobufApiLintTask : SourceTask() | ||
open class ProtobufApiLintTask : SourceTask() { | ||
|
||
@get:InputDirectory | ||
lateinit var protoPath: File | ||
|
||
@get:Internal | ||
lateinit var protobuf: ProtobufExtension | ||
|
||
@TaskAction | ||
fun apiLinter() { | ||
val cmd = mutableListOf<String>() | ||
val apiLinterConfig = protobuf.linter | ||
ruleHandle(cmd, apiLinterConfig) | ||
val path = protoPath.toPath().toString() | ||
cmd.addAll(listOf(OUTPUT_FORMAT, "json", PROTO_PATH, path)) | ||
val excludeFiles = apiLinterConfig.excludeFiles | ||
Paths.get(path, "protosrc").toFile().bufferedReader().forEachLine { | ||
if (excludeFiles.isEmpty() || !excludeFiles.contains(it)) { | ||
cmd.add(it) | ||
} | ||
} | ||
val protoPathMapping = mutableMapOf<String, String>() | ||
Paths.get(path, "protofile").toFile().bufferedReader().forEachLine { | ||
val mapping = it.split("=", limit = 2) | ||
protoPathMapping[mapping[0]] = mapping[1] | ||
} | ||
val version = apiLinterConfig.version ?: ApiLinterRunner.API_LINTER_DEFAULT_VERSION | ||
val message = ApiLinterRunner().runApiLinter(cmd, version) ?: return | ||
printMessage(message.parseJson(), protoPathMapping) | ||
outputMessageToFile(message) | ||
} | ||
|
||
private fun outputMessageToFile(message: String) { | ||
val outPutDirectory = project.layout.buildDirectory.file(project.provider { | ||
"reports/apilinter" | ||
}).get().asFile | ||
if (!outPutDirectory.exists()) Files.createDirectories(outPutDirectory.toPath()) | ||
Files.write(Paths.get(outPutDirectory.toPath().toString(), "apilinter.json"), message.toByteArray()) | ||
} | ||
|
||
private fun ruleHandle(cmd: MutableList<String>, apiLinterConfig: ApiLinterConfig) { | ||
val enableRules = apiLinterConfig.enableRules | ||
if (enableRules.isNotEmpty()) { | ||
cmd.add(ENABLE_RULE) | ||
enableRules.forEach { cmd.add(it) } | ||
} | ||
val disableRules = apiLinterConfig.disableRules | ||
if (disableRules.isNotEmpty()) { | ||
cmd.add(DISABLE_RULE) | ||
disableRules.forEach { cmd.add(it) } | ||
} | ||
} | ||
|
||
private fun printMessage(linterResponseList: List<LinterResponse>, protoPathMapping: Map<String, String>) { | ||
for (linterResponse in linterResponseList) { | ||
linterResponse.problems.forEach { | ||
println("api-linter: ${protoPathMapping[linterResponse.filePath]}:${it.location.startPosition.lineNumber}:${it.location.startPosition.columnNumber} ${it.message} rule detail in ${it.ruleDocUri}") | ||
} | ||
} | ||
} | ||
|
||
companion object { | ||
private const val DISABLE_RULE = "--disable-rule" | ||
private const val ENABLE_RULE = "--enable-rule" | ||
private const val PROTO_PATH = "--proto-path" | ||
private const val OUTPUT_FORMAT = "--output-format" | ||
} | ||
} | ||
|
||
data class LinterResponse(@JsonProperty("file_path") var filePath: String, @JsonProperty("problems") var problems: List<Problem>) | ||
|
||
data class Problem(var message: String, var location: Location, @JsonProperty("rule_id") var ruleId: String, @JsonProperty("rule_doc_uri") var ruleDocUri: String) | ||
|
||
data class Location(@JsonProperty("start_position") val startPosition: FilePosition, @JsonProperty("end_position") val endPosition: FilePosition) | ||
|
||
data class FilePosition(@JsonProperty("line_number") var lineNumber: Int, @JsonProperty("column_number") var columnNumber: Int) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters