Skip to content

Instantly share code, notes, and snippets.

@helpermethod
Last active November 9, 2022 08:24
Show Gist options
  • Save helpermethod/984c0854806868779db48746a306c763 to your computer and use it in GitHub Desktop.
Save helpermethod/984c0854806868779db48746a306c763 to your computer and use it in GitHub Desktop.
Silencer
#!/usr/bin/env kotlin
@file:DependsOn("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0")
@file:DependsOn("com.github.ajalt.clikt:clikt-jvm:3.5.0")
@file:DependsOn("eu.jrie.jetbrains:kotlin-shell-core:0.2.1")
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.util.DefaultIndenter
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
import com.fasterxml.jackson.databind.node.ArrayNode
import com.fasterxml.jackson.module.kotlin.jsonMapper
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.NoOpCliktCommand
import com.github.ajalt.clikt.core.subcommands
import com.github.ajalt.clikt.parameters.groups.OptionGroup
import com.github.ajalt.clikt.parameters.groups.provideDelegate
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.multiple
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
import eu.jrie.jetbrains.kotlinshell.shell.shell
import kotlinx.coroutines.ExperimentalCoroutinesApi
import java.io.File
class CustomPrettyPrinter : DefaultPrettyPrinter() {
init {
_arrayIndenter = DefaultIndenter.SYSTEM_LINEFEED_INSTANCE
_objectIndenter = DefaultIndenter(" ", "\n")
}
override fun createInstance() =
CustomPrettyPrinter()
override fun writeObjectFieldValueSeparator(g: JsonGenerator) {
g.writeRaw(": ")
}
override fun writeEndArray(g: JsonGenerator, nrOfValues: Int) {
if (!_arrayIndenter.isInline) {
--_nesting
}
if (nrOfValues > 0) {
_arrayIndenter.writeIndentation(g, _nesting)
}
g.writeRaw(']')
}
}
class CommonOptions : OptionGroup() {
val group by option("-g", "--group", help = "The group name.").required()
val packagePatterns by option(
"-p",
"--package-pattern",
help = "The package pattern to exclude. Repeatable."
).multiple(required = true)
val dryRun by option("-d", "--dry-run", help = "Performs a dry run.").flag()
}
class Silencer : NoOpCliktCommand()
class Exclude : CliktCommand() {
private val commonOptions by CommonOptions()
override fun run() {
addExcludePattern()
if (!commonOptions.dryRun) createMergeRequest()
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun createMergeRequest() =
shell {
"git checkout -b silencer/exclude-package-patterns-from-${commonOptions.group}"()
"git add renovate.json"()
systemProcess {
cmd {
"git" withArgs listOf(
"-c",
"user.name=silencerbot",
"-c",
"user.email=",
"commit",
"-m",
"chore(deps): Exclude packages from ${commonOptions.group}",
"-m",
commonOptions.packagePatterns.joinToString("\n") { "- $it" }
)
}
}()
"git push -o merge_request.create"()
}
private fun addExcludePattern() {
val objectMapper = jsonMapper {
configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
}
val renovate = File("renovate.json")
val tree = objectMapper.readTree(renovate)
val packageRules = tree.get("packageRules")
val excludePackagePatterns =
packageRules
.first { it.get("groupName").textValue() == commonOptions.group }
.withArray<ArrayNode>("excludePackagePatterns")
commonOptions
.packagePatterns
.forEach(excludePackagePatterns::add)
val output = if (commonOptions.dryRun) System.out.bufferedWriter() else renovate.bufferedWriter()
output.use {
objectMapper.writer(CustomPrettyPrinter()).writeValue(it, tree)
it.appendLine("\n")
}
}
}
class Unexclude : CliktCommand() {
private val commonOptions by CommonOptions()
override fun run() {
removeExcludePattern()
if (!commonOptions.dryRun) createMergeRequest()
}
private fun removeExcludePattern() {
val objectMapper = jsonMapper {
configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
}
val renovate = File("renovate.json")
val tree = objectMapper.readTree(renovate)
val packageRules = tree.get("packageRules")
val excludePackagePatterns =
packageRules
.first { it.get("groupName").textValue() == commonOptions.group }
?.get("excludePackagePatterns")
?: return
excludePackagePatterns
.removeAll { it.textValue() in commonOptions.packagePatterns }
val output = if (commonOptions.dryRun) System.out.bufferedWriter() else renovate.bufferedWriter()
output.use {
objectMapper.writer(CustomPrettyPrinter()).writeValue(it, tree)
it.appendLine("\n")
}
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun createMergeRequest() {
shell {
"git checkout -b silencer/unexclude-packages-patterns-from-${commonOptions.group}"()
"git add renovate.json"()
systemProcess {
cmd {
"git" withArgs listOf(
"-c",
"user.name=silencerbot",
"-c",
"user.email=",
"commit",
"-m",
"chore(deps): Unexclude package patterns from ${commonOptions.group}",
"-m",
commonOptions.packagePatterns.joinToString("\n") { "- $it" }
)
}
}()
"git push -o merge_request.create"()
}
}
}
Silencer()
.subcommands(Exclude(), Unexclude())
.main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment