Skip to content

Commit 2ab760b

Browse files
style: prepare semmantic commits for different configurations (#4275)
* style: prepare semmantic commits for different configurations * refactor: remove semantic commit hotfix as it is not a part of it * style: fix styling issues * style: remove unused methods * style: refactor to make it easier to understand * refactor: cleed up functions that are only used in tests * docs: add new hotfix commits to docs and changelog --------- Co-authored-by: Christian Hühn <christian.huehn@maibornwolff.de>
1 parent b45fd34 commit 2ab760b

36 files changed

+1068
-1195
lines changed

analysis/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/)
1212
- Add new '--base-file' flag to unifiedparser and rawtextparser [#4270](https://github.com/MaibornWolff/codecharta/pull/4270)
1313
- UnifiedParser now automatically uses `.gitignore` files for file exclusion [#4254](https://github.com/MaibornWolff/codecharta/issues/4254)
1414
- RawTextParser now automatically uses `.gitignore` files for file exclusion [#4273](https://github.com/MaibornWolff/codecharta/issues/4273)
15+
- GitLogParser is now able to find commits that contain the word hotfixes
1516

1617
### Removed
1718

analysis/analysers/parsers/GitLogParser/src/main/kotlin/de/maibornwolff/codecharta/analysers/parsers/gitlog/GitLogParser.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class GitLogParser(
9292
"docs_commits",
9393
"style_commits",
9494
"refactor_commits",
95+
"hotfix_commits",
9596
"test_commits",
9697
"semantic_commit_ratio",
9798
"hotfix_commit_ratio"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package de.maibornwolff.codecharta.analysers.parsers.gitlog.input.metrics
2+
3+
object DefaultSemanticCommitStyle {
4+
private val defaultCommitTypes = listOf(
5+
SemanticCommitType(
6+
name = "feat",
7+
metricName = "feat_commits",
8+
description = "Feat Commits: Number of feature commits (starting with 'feat') for this file.",
9+
matchPattern = MatchPattern.StartsWith("feat")
10+
),
11+
SemanticCommitType(
12+
name = "fix",
13+
metricName = "fix_commits",
14+
description = "Fix Commits: Number of bug fix commits (starting with 'fix') for this file.",
15+
matchPattern = MatchPattern.StartsWith("fix")
16+
),
17+
SemanticCommitType(
18+
name = "docs",
19+
metricName = "docs_commits",
20+
description = "Docs Commits: Number of documentation commits (starting with 'docs') for this file.",
21+
matchPattern = MatchPattern.StartsWith("docs")
22+
),
23+
SemanticCommitType(
24+
name = "style",
25+
metricName = "style_commits",
26+
description = "Style Commits: Number of style commits (starting with 'style') for this file.",
27+
matchPattern = MatchPattern.StartsWith("style")
28+
),
29+
SemanticCommitType(
30+
name = "refactor",
31+
metricName = "refactor_commits",
32+
description = "Refactor Commits: Number of refactoring commits (starting with 'refactor') for this file.",
33+
matchPattern = MatchPattern.StartsWith("refactor")
34+
),
35+
SemanticCommitType(
36+
name = "test",
37+
metricName = "test_commits",
38+
description = "Test Commits: Number of test commits (starting with 'test') for this file.",
39+
matchPattern = MatchPattern.StartsWith("test")
40+
)
41+
)
42+
43+
fun getAllTypes(): List<SemanticCommitType> {
44+
return defaultCommitTypes
45+
}
46+
}

analysis/analysers/parsers/GitLogParser/src/main/kotlin/de/maibornwolff/codecharta/analysers/parsers/gitlog/input/metrics/DocsCommits.kt

Lines changed: 0 additions & 25 deletions
This file was deleted.

analysis/analysers/parsers/GitLogParser/src/main/kotlin/de/maibornwolff/codecharta/analysers/parsers/gitlog/input/metrics/FeatCommits.kt

Lines changed: 0 additions & 25 deletions
This file was deleted.

analysis/analysers/parsers/GitLogParser/src/main/kotlin/de/maibornwolff/codecharta/analysers/parsers/gitlog/input/metrics/HotfixCommitRatio.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class HotfixCommitRatio : Metric {
99
private var hotfixCommitsCount: Long = 0
1010

1111
override fun description(): String {
12-
return "Hotfix Commit Ratio: Ratio of hotfix commits to total commits for this file."
12+
return "Hotfix Commit Ratio: Ratio of hotfix commits (containing 'hotfix') to total commits for this file."
1313
}
1414

1515
override fun metricName(): String {
@@ -23,7 +23,7 @@ class HotfixCommitRatio : Metric {
2323
override fun registerCommit(commit: Commit) {
2424
totalCommitsCount++
2525

26-
if (SemanticCommitDetector.isHotfixCommit(commit.message)) {
26+
if (commit.message.contains("hotfix", ignoreCase = true)) {
2727
hotfixCommitsCount++
2828
}
2929
}

analysis/analysers/parsers/GitLogParser/src/main/kotlin/de/maibornwolff/codecharta/analysers/parsers/gitlog/input/metrics/HotfixCommits.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ package de.maibornwolff.codecharta.analysers.parsers.gitlog.input.metrics
33
import de.maibornwolff.codecharta.analysers.parsers.gitlog.input.Commit
44

55
class HotfixCommits : Metric {
6-
private var hotfixCommitsCount: Long = 0
6+
private var count: Long = 0
77

88
override fun description(): String {
9-
return "Hotfix Commits: Number of hotfix commits (containing 'hotfix' keyword) for this file."
9+
return "Hotfix Commits: Number of hotfix commits (containing 'hotfix') for this file."
1010
}
1111

1212
override fun metricName(): String {
1313
return "hotfix_commits"
1414
}
1515

1616
override fun registerCommit(commit: Commit) {
17-
if (SemanticCommitDetector.isHotfixCommit(commit.message)) {
18-
hotfixCommitsCount++
17+
if (commit.message.contains("hotfix", ignoreCase = true)) {
18+
count++
1919
}
2020
}
2121

2222
override fun value(): Number {
23-
return hotfixCommitsCount
23+
return count
2424
}
2525
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package de.maibornwolff.codecharta.analysers.parsers.gitlog.input.metrics
2+
3+
sealed class MatchPattern {
4+
abstract fun matches(message: String): Boolean
5+
6+
data class StartsWith(val prefix: String) : MatchPattern() {
7+
override fun matches(message: String): Boolean {
8+
return message.trim().startsWith(prefix, ignoreCase = true)
9+
}
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,50 @@
11
package de.maibornwolff.codecharta.analysers.parsers.gitlog.input.metrics
22

3-
class MetricsFactory {
4-
private val metricClasses: List<Class<out Metric>>
3+
data class MetricDefinition(
4+
val metricName: String,
5+
val factory: () -> Metric
6+
)
57

6-
constructor() {
7-
this.metricClasses = createAllMetrics().map { it.javaClass }
8-
}
8+
class MetricsFactory(requestedMetrics: List<String> = emptyList()) {
9+
private val metricDefinitions = createAllDefinitions().selectMetrics(requestedMetrics)
910

10-
constructor(metricNames: List<String>) {
11-
this.metricClasses =
12-
createAllMetrics().filter { m -> metricNames.contains(m.metricName()) }.map { it.javaClass }
13-
}
11+
fun createMetrics(): List<Metric> = metricDefinitions.map { it.factory() }
1412

15-
private fun createMetric(clazz: Class<out Metric>): Metric {
16-
try {
17-
return clazz.getDeclaredConstructor().newInstance()
18-
} catch (e: InstantiationException) {
19-
throw IllegalArgumentException("metric $clazz not found.")
20-
} catch (e: IllegalAccessException) {
21-
throw IllegalArgumentException("metric $clazz not found.")
22-
}
13+
private fun createAllDefinitions(): List<MetricDefinition> {
14+
val commitTypes = DefaultSemanticCommitStyle.getAllTypes()
15+
val standard = createStandardDefinitions(commitTypes)
16+
val dynamic = createCommitTypeDefinitions(commitTypes)
17+
return standard + dynamic
2318
}
2419

25-
private fun createAllMetrics(): List<Metric> {
26-
return listOf(
27-
AbsoluteCodeChurn(),
28-
AddedLines(),
29-
DeletedLines(),
30-
NumberOfAuthors(),
31-
NumberOfOccurencesInCommits(),
32-
RangeOfWeeksWithCommits(),
33-
SuccessiveWeeksWithCommits(),
34-
WeeksWithCommits(),
35-
HighlyCoupledFiles(),
36-
MedianCoupledFiles(),
37-
AbsoluteCoupledChurn(),
38-
AverageCodeChurnPerCommit(),
39-
NumberOfRenames(),
40-
AgeInWeeks(),
41-
FeatCommits(),
42-
FixCommits(),
43-
DocsCommits(),
44-
StyleCommits(),
45-
RefactorCommits(),
46-
TestCommits(),
47-
HotfixCommits(),
48-
SemanticCommitRatio(),
49-
HotfixCommitRatio()
50-
)
20+
private fun createStandardDefinitions(commitTypes: List<SemanticCommitType>): List<MetricDefinition> = listOf(
21+
MetricDefinition("abs_code_churn", { AbsoluteCodeChurn() }),
22+
MetricDefinition("added_lines", { AddedLines() }),
23+
MetricDefinition("deleted_lines", { DeletedLines() }),
24+
MetricDefinition("number_of_authors", { NumberOfAuthors() }),
25+
MetricDefinition("number_of_commits", { NumberOfOccurencesInCommits() }),
26+
MetricDefinition("range_of_weeks_with_commits", { RangeOfWeeksWithCommits() }),
27+
MetricDefinition("successive_weeks_with_commits", { SuccessiveWeeksWithCommits() }),
28+
MetricDefinition("weeks_with_commits", { WeeksWithCommits() }),
29+
MetricDefinition("highly_coupled_files", { HighlyCoupledFiles() }),
30+
MetricDefinition("median_coupled_files", { MedianCoupledFiles() }),
31+
MetricDefinition("abs_coupled_churn", { AbsoluteCoupledChurn() }),
32+
MetricDefinition("avg_code_churn", { AverageCodeChurnPerCommit() }),
33+
MetricDefinition("number_of_renames", { NumberOfRenames() }),
34+
MetricDefinition("age_in_weeks", { AgeInWeeks() }),
35+
MetricDefinition("semantic_commit_ratio", { SemanticCommitRatio(commitTypes) }),
36+
MetricDefinition("hotfix_commits", { HotfixCommits() }),
37+
MetricDefinition("hotfix_commit_ratio", { HotfixCommitRatio() })
38+
)
39+
40+
private fun createCommitTypeDefinitions(commitTypes: List<SemanticCommitType>): List<MetricDefinition> = commitTypes.map { type ->
41+
MetricDefinition(type.metricName, { SemanticCommitMetric(type) })
5142
}
5243

53-
fun createMetrics(): List<Metric> {
54-
return metricClasses.map { createMetric(it) }
44+
private fun List<MetricDefinition>.selectMetrics(names: List<String>): List<MetricDefinition> {
45+
if (names.isEmpty()) {
46+
return this
47+
}
48+
return filter { it.metricName in names }
5549
}
5650
}

analysis/analysers/parsers/GitLogParser/src/main/kotlin/de/maibornwolff/codecharta/analysers/parsers/gitlog/input/metrics/RefactorCommits.kt

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)