Skip to content

Commit

Permalink
Diktat CLI runner (#1653)
Browse files Browse the repository at this point in the history
  • Loading branch information
nulls authored Apr 6, 2023
1 parent 0d528ce commit 0fd74b5
Show file tree
Hide file tree
Showing 19 changed files with 681 additions and 76 deletions.
48 changes: 37 additions & 11 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,20 @@ jobs:
name: gradle-reports
path: '**/build/reports/'
retention-days: 1
- name: Upload diktat jar
- name: Upload diktat-ruleset jar
uses: actions/upload-artifact@v3
with:
name: diktat-ruleset
path: diktat-ruleset/build/libs/diktat-*.jar
# no need to store artifact longer, it is used only by dependant jobs
retention-days: 1
- name: Upload diktat-cli jar
uses: actions/upload-artifact@v3
with:
name: diktat-cli
path: diktat-cli/build/libs/diktat-cli-*.jar
# no need to store artifact longer, it is used only by dependant jobs
retention-days: 1
- name: Code coverage report
uses: codecov/codecov-action@v3
with:
Expand All @@ -77,37 +84,55 @@ jobs:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
java-version: [8, 11]
type: [ ktlint, cli ]

steps:
- uses: actions/checkout@v3

- name: Retrieve Ktlint version
if: matrix.type == 'ktlint'
run: |
ktlint_version=$(cat gradle/libs.versions.toml | grep '^ktlint =' | awk -F'[=]' '{print $2}' | tr -d '" ')
echo KTLINT_VERSION=$ktlint_version >> $GITHUB_ENV
shell: bash

- name: Setup environment
if: matrix.type == 'ktlint'
run: |
curl -o ktlint -sSL https://github.com/pinterest/ktlint/releases/download/${{ env.KTLINT_VERSION }}/ktlint && chmod a+x ktlint
java -version
shell: bash

- name: Download diktat jar
if: matrix.type == 'ktlint'
uses: actions/download-artifact@v3
with:
name: diktat-ruleset

- name: Retrieve diktat jar file name
- name: Generate run command using ktlint
if: matrix.type == 'ktlint'
run: |
filename=$(ls -1 diktat-*.jar | head -n1)
echo DIKTAT_RUN="java -jar ktlint -R \"$filename\" --disabled_rules=standard,experimental,test,custom" >> $GITHUB_ENV
shell: bash

- name: Download diktat cli jar
if: matrix.type == 'cli'
uses: actions/download-artifact@v3
with:
name: diktat-cli

- name: Generate run command using cli
if: matrix.type == 'cli'
run: |
filename=$(ls diktat-*.jar)
echo DIKTAT_JAR=$filename >> $GITHUB_ENV
filename=$(ls -1 diktat-cli-*.jar | head -n1)
echo DIKTAT_RUN="java -jar \"$filename\"" >> $GITHUB_ENV
shell: bash

- name: Run diKTat from cli
continue-on-error: true
run: |
java -jar ktlint -R ${{ env.DIKTAT_JAR }} --disabled_rules=standard,experimental,test,custom 'examples/maven/src/main/kotlin/Test.kt' &>out.txt
${{ env.DIKTAT_RUN }} 'examples/maven/src/main/kotlin/Test.kt' &>out.txt
shell: bash

- name: Check output
Expand All @@ -121,14 +146,15 @@ jobs:
continue-on-error: true
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
run: |
java -jar ktlint -R ${{ env.DIKTAT_JAR }} --disabled_rules=standard,experimental,test,custom "$PWD/examples/maven/src/main/kotlin/Test.kt" &>out.txt
${{ env.DIKTAT_RUN }} "$PWD/examples/maven/src/main/kotlin/Test.kt" &>out.txt
shell: bash

- name: Run diKTat from cli on windows (absolute paths)
continue-on-error: true
if: runner.os == 'Windows'
# cannot use '&>out.txt' since it's Windows
run: |
java -jar ktlint -R ${{ env.DIKTAT_JAR }} --disabled_rules=standard,experimental,test,custom "%cd%/examples/maven/src/main/kotlin/Test.kt" > out.txt 2>&1
${{ env.DIKTAT_RUN }} "%cd%/examples/maven/src/main/kotlin/Test.kt" > out.txt 2>&1
shell: cmd

- name: Check output (absolute paths)
Expand All @@ -141,7 +167,7 @@ jobs:
- name: Run diKTat from cli (glob paths, 1 of 4)
continue-on-error: true
run: |
java -jar ktlint -R ${{ env.DIKTAT_JAR }} --disabled_rules=standard,experimental,test,custom 'examples/maven/src/main/kotlin/*.kt' &>out.txt
${{ env.DIKTAT_RUN }} 'examples/maven/src/main/kotlin/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 1 of 4)
Expand All @@ -154,7 +180,7 @@ jobs:
- name: Run diKTat from cli (glob paths, 2 of 4)
continue-on-error: true
run: |
java -jar ktlint -R ${{ env.DIKTAT_JAR }} --disabled_rules=standard,experimental,test,custom 'examples/**/main/kotlin/*.kt' &>out.txt
${{ env.DIKTAT_RUN }} 'examples/**/main/kotlin/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 2 of 4)
Expand All @@ -167,7 +193,7 @@ jobs:
- name: Run diKTat from cli (glob paths, 3 of 4)
continue-on-error: true
run: |
java -jar ktlint -R ${{ env.DIKTAT_JAR }} --disabled_rules=standard,experimental,test,custom 'examples/**/*.kt' &>out.txt
${{ env.DIKTAT_RUN }} 'examples/**/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 3 of 4)
Expand All @@ -180,7 +206,7 @@ jobs:
- name: Run diKTat from cli (glob paths, 4 of 4)
continue-on-error: true
run: |
java -jar ktlint -R ${{ env.DIKTAT_JAR }} --disabled_rules=standard,experimental,test,custom '**/*.kt' &>out.txt
${{ env.DIKTAT_RUN }} '**/*.kt' &>out.txt
shell: bash

- name: Check output (glob paths, 4 of 4)
Expand Down
30 changes: 30 additions & 0 deletions diktat-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,33 @@ project.description = "This module builds diktat-api"
dependencies {
implementation(libs.kotlin.compiler.embeddable)
}

val generateDiktatVersionFile by tasks.registering {
val outputDir = File("$buildDir/generated/src")
val versionsFile = outputDir.resolve("generated/DiktatVersion.kt")

val diktatVersion = version.toString()

inputs.property("diktat version", diktatVersion)
outputs.dir(outputDir)

doFirst {
versionsFile.parentFile.mkdirs()
versionsFile.writeText(
"""
package generated
const val DIKTAT_VERSION = "$diktatVersion"
""".trimIndent()
)
}
}

kotlin.sourceSets.getByName("main") {
kotlin.srcDir(
generateDiktatVersionFile.map {
it.outputs.files.singleFile
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import kotlin.io.path.absolutePathString
* @property baselineFile an optional path to file with baseline
* @property reporterType type of reporter to report the detected errors
* @property reporterOutput output for reporter
* @property loggingListener listener to log diktat runner phases
* @property groupByFileInPlain a flag `groupByFile` which is applicable for plain reporter only, **null** by default
* @property colorNameInPlain a color name which is applicable for plain reporter only, **null** by default
* @property loggingListener listener to log diktat runner phases, [DiktatProcessorListener.empty] by default
*/
data class DiktatRunnerArguments(
val configFileName: String,
Expand All @@ -23,6 +25,8 @@ data class DiktatRunnerArguments(
val baselineFile: Path?,
val reporterType: String,
val reporterOutput: OutputStream?,
val groupByFileInPlain: Boolean? = null,
val colorNameInPlain: String? = null,
val loggingListener: DiktatProcessorListener = DiktatProcessorListener.empty,
) {
constructor(
Expand All @@ -32,14 +36,18 @@ data class DiktatRunnerArguments(
baselineFile: Path?,
reporterType: String,
reporterOutput: OutputStream?,
loggingListener: DiktatProcessorListener,
groupByFileInPlain: Boolean? = null,
colorNameInPlain: String? = null,
loggingListener: DiktatProcessorListener = DiktatProcessorListener.empty,
) : this(
configFile.absolutePathString(),
sourceRootDir,
files,
baselineFile,
reporterType,
reporterOutput,
groupByFileInPlain,
colorNameInPlain,
loggingListener,
)
}
24 changes: 21 additions & 3 deletions diktat-api/src/main/kotlin/org/cqfn/diktat/DiktatRunnerFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import java.nio.file.Path

/**
* A factory to create [DiktatRunner]
*
* @property diktatReporterFactory a factory for [DiktatReporter]
*/
class DiktatRunnerFactory(
private val diktatRuleSetFactory: DiktatRuleSetFactory,
private val diktatProcessorFactory: DiktatProcessorFactory,
private val diktatBaselineFactory: DiktatBaselineFactory,
private val diktatReporterFactory: DiktatReporterFactory,
val diktatReporterFactory: DiktatReporterFactory,
) : Function1<DiktatRunnerArguments, DiktatRunner> {
/**
* @param args
Expand All @@ -27,7 +29,11 @@ class DiktatRunnerFactory(
val diktatRuleSet = diktatRuleSetFactory.create(args.configFileName)
val processor = diktatProcessorFactory(diktatRuleSet)
val (baseline, baselineGenerator) = resolveBaseline(args.baselineFile, args.sourceRootDir)
val (reporter, closer) = resolveReporter(args.reporterType, args.reporterOutput, args.sourceRootDir)
val (reporter, closer) = resolveReporter(
args.reporterType, args.reporterOutput,
args.colorNameInPlain, args.groupByFileInPlain,
args.sourceRootDir
)
return DiktatRunner(
diktatProcessor = processor,
diktatBaseline = baseline,
Expand All @@ -53,14 +59,26 @@ class DiktatRunnerFactory(
private fun resolveReporter(
reporterType: String,
reporterOutput: OutputStream?,
colorNameInPlain: String?,
groupByFileInPlain: Boolean?,
sourceRootDir: Path,
): Pair<DiktatReporter, DiktatProcessorListener> {
val (outputStream, closeListener) = reporterOutput
?.let { it to it.closeAfterAllAsProcessorListener() }
?: run {
System.`out` to DiktatProcessorListener.empty
}
val actualReporter = diktatReporterFactory(reporterType, outputStream, sourceRootDir)
val actualReporter = if (reporterType == diktatReporterFactory.plainId) {
diktatReporterFactory.createPlain(outputStream, sourceRootDir, colorNameInPlain, groupByFileInPlain)
} else {
require(colorNameInPlain == null) {
"colorization is applicable only for plain reporter"
}
require(groupByFileInPlain == null) {
"groupByFile is applicable only for plain reporter"
}
diktatReporterFactory(reporterType, outputStream, sourceRootDir)
}
return actualReporter to closeListener
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ interface DiktatReporterFactory : Function3<String, OutputStream, Path, DiktatRe
outputStream: OutputStream,
sourceRootDir: Path,
colorName: String? = null,
groupByFile: Boolean = false,
groupByFile: Boolean? = null,
): DiktatReporter
}
72 changes: 72 additions & 0 deletions diktat-cli/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.incremental.createDirectory

@Suppress("DSL_SCOPE_VIOLATION", "RUN_IN_SCRIPT") // https://github.com/gradle/gradle/issues/22797
plugins {
id("org.cqfn.diktat.buildutils.kotlin-jvm-configuration")
id("org.cqfn.diktat.buildutils.code-quality-convention")
id("org.cqfn.diktat.buildutils.publishing-signing-default-configuration")
alias(libs.plugins.kotlin.plugin.serialization)
alias(libs.plugins.shadow)
}

project.description = "This module builds diktat-cli to run diktat as CLI using ktlint"

dependencies {
implementation(projects.diktatApi)
implementation(projects.diktatKtlintEngine)
implementation(projects.diktatRules)
implementation(libs.kotlinx.cli)
implementation(libs.log4j2.core)
implementation(libs.log4j2.slf4j)

testImplementation(libs.junit.jupiter)
testImplementation(libs.junit.platform.suite)
testImplementation(libs.assertj.core)
testImplementation(libs.mockito)
}

val addLicenseTask = tasks.register("addLicense") {
val licenseFile = rootProject.file("LICENSE")
val outputDir = File("$buildDir/generated/src")

inputs.file(licenseFile)
outputs.dir(outputDir)

doLast {
licenseFile.copyTo(
outputDir.resolve("META-INF").resolve("diktat")
.also { it.createDirectory() }
.resolve(licenseFile.name),
overwrite = true
)
}
}

sourceSets.getByName("main") {
resources.srcDir(
addLicenseTask.map {
it.outputs.files.singleFile
}
)
}

tasks.named<ShadowJar>("shadowJar") {
archiveClassifier.set("")
manifest {
attributes["Main-Class"] = "org.cqfn.diktat.DiktatMainKt"
}
duplicatesStrategy = DuplicatesStrategy.FAIL
}

// disable default jar
tasks.named("jar") {
enabled = false
}

// it triggers shadowJar with default build
tasks {
build {
dependsOn(shadowJar)
}
}
Loading

0 comments on commit 0fd74b5

Please sign in to comment.