Skip to content

Commit

Permalink
Merge pull request #47 from appKODE/add-logic-to-configure-version-pa…
Browse files Browse the repository at this point in the history
…ttern

Add experimental logic to configure build tag pattern. But now it has…
  • Loading branch information
rinekri authored Mar 11, 2024
2 parents cba405e + bf612b1 commit 2b8c485
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 35 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 1.3.0-alpha01
* Add experimental logic to configure build tag pattern (buildTagPattern). But now it has restrictions: for example, in tag name should be only one - delimiter

## 1.2.0
* Hide firebase app distribution plugin inside, and add logic to apply it only if required
* Add `useVersionsFromTag` property inside OutputConfig to disable logic when versions and file names is applied from tag
Expand Down
5 changes: 5 additions & 0 deletions example/dimensions/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ buildPublish {
register("default") {
baseFileName.set("example-base-project-android")
}

register("x86MinApi21AlphaDebug") {
baseFileName.set("example-base-project-android")
buildTagPattern.set("cabinet\\+.+\\.(\\d+)-x86MinApi21AlphaDebug")
}
}
changelog {
register("default") {
Expand Down
2 changes: 1 addition & 1 deletion plugin-build/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {

allprojects {
group = "ru.kode.android"
version = "1.2.0"
version = "1.3.0-alpha01"
}

val dependsOnRecursivelyByName = { task: Task, name: String ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,12 @@ abstract class BuildPublishPlugin : Plugin<Project> {
with(buildPublishExtension.output) {
findByName(buildVariant.name) ?: getByName(DEFAULT_CONTAINER_NAME)
}
val tagBuildProvider = registerGetLastTagTask(buildVariant, grgitService)
val tagBuildProvider =
registerGetLastTagTask(
buildVariant,
outputConfig.buildTagPattern,
grgitService,
)
val useVersionsFromTagProvider = outputConfig.useVersionsFromTag.orElse(true)
val versionCodeProvider =
useVersionsFromTagProvider.flatMap { useVersionsFromTag ->
Expand Down Expand Up @@ -183,6 +188,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
val generateChangelogFileProvider =
tasks.registerGenerateChangelogTask(
changelogConfig.commitMessageKey,
outputConfig.buildTagPattern,
buildVariant,
changelogFile,
tagBuildProvider,
Expand Down Expand Up @@ -333,6 +339,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {

private fun Project.registerGetLastTagTask(
buildVariant: BuildVariant,
buildTagPattern: Provider<String>,
grgitService: Provider<GrgitService>,
): Provider<RegularFile> {
val tagBuildFile =
Expand All @@ -344,6 +351,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
) { task ->
task.tagBuildFile.set(tagBuildFile)
task.buildVariant.set(buildVariant.name)
task.buildTagPattern.set(buildTagPattern)
task.getGrgitService().set(grgitService)
}.flatMap { it.tagBuildFile }
}
Expand All @@ -362,6 +370,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {

private fun TaskContainer.registerGenerateChangelogTask(
commitMessageKey: Provider<String>,
buildTagPattern: Provider<String>,
buildVariant: BuildVariant,
changelogFile: Provider<RegularFile>,
tagBuildProvider: Provider<RegularFile>,
Expand All @@ -372,7 +381,7 @@ abstract class BuildPublishPlugin : Plugin<Project> {
GenerateChangelogTask::class.java,
) {
it.commitMessageKey.set(commitMessageKey)
it.buildVariant.set(buildVariant.name)
it.buildTagPattern.set(buildTagPattern)
it.changelogFile.set(changelogFile)
it.tagBuildFile.set(tagBuildProvider)
it.getGrgitService().set(grgitService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ internal class GitCommandExecutor(
private val grgitService: GrgitService,
) {
/**
* Extracts lines which contain [tag] from all commit messages in commit range (inclusive).
* Extracts lines which contain [key] from all commit messages in commit range (inclusive).
* For example calling this function with arguments `"CHANGELOG", CommitRange("someSHA1", "someSHA2")`
* will run `git log` command and extract lines containing "CHANGELOG" from each commit in that range.
*/
fun extractTagFromCommitMessages(
tag: String,
fun extractMarkedCommitMessages(
key: String,
range: CommitRange?,
): List<String> {
return getCommitsByRange(range)
.flatMap { commit ->
commit.fullMessage
.split('\n')
.filter { message -> message.contains(tag) }
.filter { message -> message.contains(key) }
}
}

Expand All @@ -30,10 +30,9 @@ internal class GitCommandExecutor(
* Resulting set will be limited to [limitResultCount] tags or `null` if no tags found
*/
fun findBuildTags(
buildVariant: String,
buildTagRegex: Regex,
limitResultCount: Int,
): List<Tag>? {
val buildTagRegex = Regex(".+\\.(\\d+)-$buildVariant")
return grgitService.grgit.tag.list()
.filter { tag -> tag.name.matches(buildTagRegex) }
.sortedBy { tag ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ private fun Tag.toBuildVariant(buildVariant: String): String {
}
}

// TODO: Add logic to configure logic to extract build version outside
private fun Tag.toBuildVersion(): String {
val tagFirstPart = name.split("-").first()
val numbers = Regex("\\d+").findAll(tagFirstPart).toList()
return numbers.dropLast(1).joinToString(separator = ".") { it.value }
}

// TODO: Add logic to configure logic to extract build number outside
private fun Tag.toBuildNumber(): Int {
val tagFirstPart = name.split("-").first()
return Regex("\\d+").findAll(tagFirstPart).last().value.toInt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ru.kode.android.build.publish.plugin.extension.config

import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional

interface OutputConfig {
val name: String
Expand All @@ -25,4 +26,8 @@ interface OutputConfig {
*/
@get:Input
val useVersionsFromTag: Property<Boolean>

@get:Input
@get:Optional
val buildTagPattern: Property<String>
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.options.Option
Expand Down Expand Up @@ -43,17 +44,21 @@ abstract class GenerateChangelogTask
@get:Option(option = "tagBuildFile", description = "Json contains info about tag build")
abstract val tagBuildFile: RegularFileProperty

@get:Input
@get:Option(option = "buildVariant", description = "Current build variant")
abstract val buildVariant: Property<String>

@get:Input
@get:Option(
option = "commitMessageKey",
description = "Message key to collect interested commits",
)
abstract val commitMessageKey: Property<String>

@get:Input
@get:Option(
option = "buildTagPattern",
description = "Tag pattern to correctly search related tags",
)
@get:Optional
abstract val buildTagPattern: Property<String>

@get:OutputFile
@get:Option(
option = "changelogFile",
Expand All @@ -66,7 +71,7 @@ abstract class GenerateChangelogTask
val workQueue: WorkQueue = workerExecutor.noIsolation()
workQueue.submit(GenerateChangelogWork::class.java) { parameters ->
parameters.commitMessageKey.set(commitMessageKey)
parameters.buildVariant.set(buildVariant)
parameters.buildTagPattern.set(buildTagPattern)
parameters.tagBuildFile.set(tagBuildFile)
parameters.changelogFile.set(changelogFile)
parameters.grgitService.set(grgitService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@ internal class ChangelogBuilder(
@Suppress("ReturnCount")
fun buildForBuildTag(
buildTag: Tag.Build,
buildTagPattern: String?,
defaultValueSupplier: ((TagRange) -> String?)? = null,
): String? {
val buildVariant = buildTag.buildVariant
return buildForBuildVariant(buildVariant, defaultValueSupplier)
return buildForBuildVariant(buildVariant, buildTagPattern, defaultValueSupplier)
}

private fun buildForBuildVariant(
buildVariant: String,
buildTagPattern: String?,
defaultValueSupplier: ((TagRange) -> String?)? = null,
): String? {
val tagRange =
gitRepository.findTagRange(buildVariant)
gitRepository.findTagRange(buildVariant, buildTagPattern)
.also { if (it == null) logger?.warn("failed to build a changelog: no build tags") }
?: return null
return tagRange.buildChangelog() ?: defaultValueSupplier?.invoke(tagRange)
Expand All @@ -44,7 +46,7 @@ internal class ChangelogBuilder(
// (but remember, tags can be annotated - which is taken care of above)
if (this.currentBuildTag.commitSha != this.previousBuildTag?.commitSha) {
gitCommandExecutor
.extractTagFromCommitMessages(messageKey, this.asCommitRange())
.extractMarkedCommitMessages(messageKey, this.asCommitRange())
.map { it.replace(Regex("\\s*$messageKey:?\\s*"), "") }
.forEach {
messageBuilder.appendLine(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,34 @@ import ru.kode.android.build.publish.plugin.enity.TagRange

internal class GitRepository(
private val gitCommandExecutor: GitCommandExecutor,
private val buildVariant: String,
) {
/**
* Finds a range of build tags, returning `null` if no build tags are present (happens on a new projects)
*/
fun findTagRange(buildVariant: String): TagRange? {
val tags = gitCommandExecutor.findBuildTags(buildVariant, limitResultCount = 2)
return tags?.let {
val currentBuildTag = it.first()
val previousBuildTag = it.getOrNull(1)
TagRange(
// todo add Build types
currentBuildTag = Tag.Build(currentBuildTag, buildVariant),
previousBuildTag = previousBuildTag?.let { Tag.Build(it, buildVariant) },
)
}
fun findTagRange(
buildVariant: String,
buildTagPattern: String?,
): TagRange? {
val buildTagRegex = Regex(buildTagPattern ?: DEFAULT_TAG_PATTERN.format(buildVariant))
return gitCommandExecutor.findBuildTags(buildTagRegex, limitResultCount = 2)
?.let { tags ->
val currentBuildTag = tags.first()
val previousBuildTag = tags.getOrNull(1)
TagRange(
currentBuildTag = Tag.Build(currentBuildTag, buildVariant),
previousBuildTag = previousBuildTag?.let { Tag.Build(it, buildVariant) },
)
}
}

fun findRecentBuildTag(): Tag.Build? {
val tags = gitCommandExecutor.findBuildTags(buildVariant, limitResultCount = 1)
fun findRecentBuildTag(
buildVariant: String,
buildTagPattern: String?,
): Tag.Build? {
val buildTagRegex = Regex(buildTagPattern ?: DEFAULT_TAG_PATTERN.format(buildVariant))
val tags = gitCommandExecutor.findBuildTags(buildTagRegex, limitResultCount = 1)
return tags?.first()?.let { Tag.Build(it, buildVariant) }
}
}

private const val DEFAULT_TAG_PATTERN = ".+\\.(\\d+)-%s"
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import javax.inject.Inject

interface GenerateChangelogParameters : WorkParameters {
val commitMessageKey: Property<String>
val buildVariant: Property<String>
val buildTagPattern: Property<String>
val tagBuildFile: RegularFileProperty
val changelogFile: RegularFileProperty
val grgitService: Property<GrgitService>
Expand All @@ -27,14 +27,15 @@ abstract class GenerateChangelogWork

override fun execute() {
val messageKey = parameters.commitMessageKey.get()
val buildTagPattern = parameters.buildTagPattern.orNull
val currentBuildTag = fromJson(parameters.tagBuildFile.asFile.get())
val buildVariant = parameters.buildVariant.get()
val gitCommandExecutor = GitCommandExecutor(parameters.grgitService.get())
val gitRepository = GitRepository(gitCommandExecutor, buildVariant)
val gitRepository = GitRepository(gitCommandExecutor)
val changelog =
ChangelogBuilder(gitRepository, gitCommandExecutor, logger, messageKey)
.buildForBuildTag(
currentBuildTag,
buildTagPattern,
defaultValueSupplier = { tagRange ->
val previousBuildName = tagRange.previousBuildTag?.name?.let { "($it)" }
"No changes compared to the previous build $previousBuildName"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.gradle.api.plugins.BasePlugin
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.options.Option
Expand Down Expand Up @@ -37,6 +38,11 @@ abstract class GetLastTagTask
@get:Option(option = "buildVariant", description = "Current build variant")
abstract val buildVariant: Property<String>

@get:Input
@get:Option(option = "buildTagPattern", description = "Tag pattern to correctly search related tags")
@get:Optional
abstract val buildTagPattern: Property<String>

@get:OutputFile
@get:Option(option = "tagBuildFile", description = "Json contains info about tag build")
abstract val tagBuildFile: RegularFileProperty
Expand All @@ -47,6 +53,7 @@ abstract class GetLastTagTask
workQueue.submit(GenerateTagWork::class.java) { parameters ->
parameters.tagBuildFile.set(tagBuildFile)
parameters.buildVariant.set(buildVariant)
parameters.buildTagPattern.set(buildTagPattern)
parameters.grgitService.set(grgitService)
}
workQueue.await()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import javax.inject.Inject

interface GenerateTagParameters : WorkParameters {
val buildVariant: Property<String>
val buildTagPattern: Property<String>
val tagBuildFile: RegularFileProperty
val grgitService: Property<GrgitService>
}
Expand All @@ -24,8 +25,9 @@ abstract class GenerateTagWork

override fun execute() {
val buildVariant = parameters.buildVariant.get()
val buildTagPattern = parameters.buildTagPattern.orNull
val gitCommandExecutor = GitCommandExecutor(parameters.grgitService.get())
val buildTag = GitRepository(gitCommandExecutor, buildVariant).findRecentBuildTag()
val buildTag = GitRepository(gitCommandExecutor).findRecentBuildTag(buildVariant, buildTagPattern)
val tagBuildOutput = parameters.tagBuildFile.asFile.get()

if (buildTag != null) {
Expand Down

0 comments on commit 2b8c485

Please sign in to comment.