churn_vs_complexity 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/CLAUDE.md +60 -0
- data/lib/churn_vs_complexity/churn.rb +1 -1
- data/lib/churn_vs_complexity/cli/main.rb +8 -0
- data/lib/churn_vs_complexity/cli/parser.rb +68 -11
- data/lib/churn_vs_complexity/cli.rb +3 -1
- data/lib/churn_vs_complexity/complexity/go_calculator.rb +48 -0
- data/lib/churn_vs_complexity/complexity/python_calculator.rb +50 -0
- data/lib/churn_vs_complexity/complexity.rb +2 -0
- data/lib/churn_vs_complexity/complexity_validator.rb +4 -0
- data/lib/churn_vs_complexity/delta/config.rb +2 -2
- data/lib/churn_vs_complexity/delta.rb +8 -0
- data/lib/churn_vs_complexity/diff/checker.rb +46 -0
- data/lib/churn_vs_complexity/diff/config.rb +53 -0
- data/lib/churn_vs_complexity/diff/serializer.rb +78 -0
- data/lib/churn_vs_complexity/diff.rb +10 -0
- data/lib/churn_vs_complexity/file_selector.rb +26 -0
- data/lib/churn_vs_complexity/focus/checker.rb +59 -0
- data/lib/churn_vs_complexity/focus/config.rb +66 -0
- data/lib/churn_vs_complexity/focus/serializer.rb +98 -0
- data/lib/churn_vs_complexity/focus.rb +10 -0
- data/lib/churn_vs_complexity/gamma_score.rb +13 -0
- data/lib/churn_vs_complexity/gate/checker.rb +36 -0
- data/lib/churn_vs_complexity/gate/config.rb +53 -0
- data/lib/churn_vs_complexity/gate/serializer.rb +35 -0
- data/lib/churn_vs_complexity/gate.rb +10 -0
- data/lib/churn_vs_complexity/git_strategy.rb +13 -5
- data/lib/churn_vs_complexity/hotspots/checker.rb +17 -0
- data/lib/churn_vs_complexity/hotspots/config.rb +50 -0
- data/lib/churn_vs_complexity/hotspots/serializer.rb +49 -0
- data/lib/churn_vs_complexity/hotspots.rb +10 -0
- data/lib/churn_vs_complexity/language_validator.rb +3 -1
- data/lib/churn_vs_complexity/normal/config.rb +18 -0
- data/lib/churn_vs_complexity/normal/serializer/json.rb +36 -0
- data/lib/churn_vs_complexity/normal/serializer/summary_hash.rb +25 -32
- data/lib/churn_vs_complexity/normal/serializer.rb +1 -0
- data/lib/churn_vs_complexity/normal.rb +1 -1
- data/lib/churn_vs_complexity/risk_annotator.rb +26 -0
- data/lib/churn_vs_complexity/risk_classifier.rb +35 -0
- data/lib/churn_vs_complexity/triage/checker.rb +64 -0
- data/lib/churn_vs_complexity/triage/config.rb +52 -0
- data/lib/churn_vs_complexity/triage/serializer.rb +16 -0
- data/lib/churn_vs_complexity/triage.rb +10 -0
- data/lib/churn_vs_complexity/version.rb +1 -1
- data/lib/churn_vs_complexity.rb +8 -0
- data/tmp/test-support/delta/ruby-summary.txt +10 -5
- data/tmp/test-support/delta/ruby.csv +5 -5
- data/tmp/test-support/go/main.go +11 -0
- data/tmp/test-support/go/utils.go +13 -0
- data/tmp/test-support/python/example.py +6 -0
- data/tmp/test-support/python/utils.py +9 -0
- metadata +34 -3
|
@@ -7,45 +7,38 @@ module ChurnVsComplexity
|
|
|
7
7
|
class << self
|
|
8
8
|
def serialize(result)
|
|
9
9
|
values_by_file = result[:values_by_file]
|
|
10
|
-
|
|
11
|
-
complexity_values = values_by_file.map { |_, values| values[1].to_f }
|
|
12
|
-
|
|
13
|
-
mean_churn = churn_values.sum / churn_values.size
|
|
14
|
-
median_churn = churn_values.sort[churn_values.size / 2]
|
|
15
|
-
mean_complexity = complexity_values.sum / complexity_values.size
|
|
16
|
-
median_complexity = complexity_values.sort[complexity_values.size / 2]
|
|
10
|
+
end_date = result[:git_period].end_date
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
min_churn = churn_values.min
|
|
20
|
-
max_complexity = complexity_values.max
|
|
21
|
-
min_complexity = complexity_values.min
|
|
12
|
+
return empty_summary(end_date) if values_by_file.empty?
|
|
22
13
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# since the summary needs to be comparable over time
|
|
27
|
-
churn = values[0].to_f + epsilon
|
|
28
|
-
complexity = values[1].to_f + epsilon
|
|
14
|
+
churn_values = values_by_file.map { |_, values| values[0].to_f }
|
|
15
|
+
complexity_values = values_by_file.map { |_, values| values[1].to_f }
|
|
16
|
+
gamma_scores = values_by_file.map { |_, values| GammaScore.calculate(values[0], values[1]) }
|
|
29
17
|
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
stats(churn_values).transform_keys { |k| :"#{k}_churn" }
|
|
19
|
+
.merge(stats(complexity_values).transform_keys { |k| :"#{k}_complexity" })
|
|
20
|
+
.merge(stats(gamma_scores).slice(:mean, :median).transform_keys { |k| :"#{k}_gamma_score" })
|
|
21
|
+
.merge(end_date:)
|
|
22
|
+
end
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
median_gamma_score = gamma_score.sort[gamma_score.size / 2]
|
|
24
|
+
private
|
|
35
25
|
|
|
36
|
-
|
|
26
|
+
def stats(values)
|
|
27
|
+
{ mean: values.sum / values.size, median: values.sort[values.size / 2], max: values.max, min: values.min }
|
|
28
|
+
end
|
|
37
29
|
|
|
30
|
+
def empty_summary(end_date)
|
|
38
31
|
{
|
|
39
|
-
mean_churn
|
|
40
|
-
median_churn
|
|
41
|
-
max_churn
|
|
42
|
-
min_churn
|
|
43
|
-
mean_complexity
|
|
44
|
-
median_complexity
|
|
45
|
-
max_complexity
|
|
46
|
-
min_complexity
|
|
47
|
-
mean_gamma_score
|
|
48
|
-
median_gamma_score
|
|
32
|
+
mean_churn: 0.0,
|
|
33
|
+
median_churn: 0.0,
|
|
34
|
+
max_churn: 0.0,
|
|
35
|
+
min_churn: 0.0,
|
|
36
|
+
mean_complexity: 0.0,
|
|
37
|
+
median_complexity: 0.0,
|
|
38
|
+
max_complexity: 0.0,
|
|
39
|
+
min_complexity: 0.0,
|
|
40
|
+
mean_gamma_score: 0.0,
|
|
41
|
+
median_gamma_score: 0.0,
|
|
49
42
|
end_date:,
|
|
50
43
|
}
|
|
51
44
|
end
|
|
@@ -9,7 +9,7 @@ module ChurnVsComplexity
|
|
|
9
9
|
module SerializerValidator
|
|
10
10
|
def self.validate!(serializer:)
|
|
11
11
|
raise ValidationError, "Unsupported serializer: #{serializer}" \
|
|
12
|
-
unless %i[none csv graph summary].include?(serializer)
|
|
12
|
+
unless %i[none csv graph summary json].include?(serializer)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChurnVsComplexity
|
|
4
|
+
module RiskAnnotator
|
|
5
|
+
def self.annotate(values_by_file, classifier: RiskClassifier.new)
|
|
6
|
+
values_by_file.map { |file, values| build_entry(file, values, classifier) }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.risk_summary(entries)
|
|
10
|
+
counts = entries.each_with_object(Hash.new(0)) { |e, acc| acc["#{e[:risk]}_risk"] += 1 }
|
|
11
|
+
{ high_risk: counts['high_risk'], medium_risk: counts['medium_risk'], low_risk: counts['low_risk'] }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.build_entry(file, values, classifier)
|
|
15
|
+
gamma = GammaScore.calculate(values[0], values[1])
|
|
16
|
+
classification = classifier.classify(gamma_score: gamma)
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
file:, churn: values[0], complexity: values[1].to_f, gamma_score: gamma.round(2),
|
|
20
|
+
risk: classification[:risk], recommendation: classification[:recommendation],
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private_class_method :build_entry
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChurnVsComplexity
|
|
4
|
+
class RiskClassifier
|
|
5
|
+
DEFAULT_LOW = 10
|
|
6
|
+
DEFAULT_HIGH = 25
|
|
7
|
+
|
|
8
|
+
RECOMMENDATIONS = {
|
|
9
|
+
'low' => 'Safe for quick changes.',
|
|
10
|
+
'medium' => 'Exercise judgement; consider tests for non-trivial changes.',
|
|
11
|
+
'high' => 'Write tests before modifying. Consider multi-agent review.',
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
def initialize(low: DEFAULT_LOW, high: DEFAULT_HIGH)
|
|
15
|
+
@low = low
|
|
16
|
+
@high = high
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def classify(gamma_score:)
|
|
20
|
+
risk = if gamma_score < @low
|
|
21
|
+
'low'
|
|
22
|
+
elsif gamma_score > @high
|
|
23
|
+
'high'
|
|
24
|
+
else
|
|
25
|
+
'medium'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
{ risk:, recommendation: RECOMMENDATIONS[risk] }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.classify(gamma_score:)
|
|
32
|
+
new.classify(gamma_score:)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChurnVsComplexity
|
|
4
|
+
module Triage
|
|
5
|
+
class Checker
|
|
6
|
+
def initialize(language:, serializer:, targets:, since:, excluded:)
|
|
7
|
+
@language = language
|
|
8
|
+
@serializer = serializer
|
|
9
|
+
@targets = targets
|
|
10
|
+
@since = since
|
|
11
|
+
@excluded = excluded
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def check(folder: nil)
|
|
15
|
+
files, dirs = partition_targets
|
|
16
|
+
folder = folder || dirs.first || '.'
|
|
17
|
+
engine = build_engine(files, folder)
|
|
18
|
+
raw_result = engine.check(folder:)
|
|
19
|
+
@serializer.serialize(raw_result)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def partition_targets
|
|
25
|
+
@targets.partition { |t| File.file?(t) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def build_engine(files, _folder)
|
|
29
|
+
Engine.concurrent(
|
|
30
|
+
complexity: complexity_for(@language),
|
|
31
|
+
churn: Churn::GitCalculator,
|
|
32
|
+
file_selector: select_files(files),
|
|
33
|
+
serializer: Normal::Serializer::None,
|
|
34
|
+
since: @since,
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def select_files(files)
|
|
39
|
+
selector = file_selector_for(@language)
|
|
40
|
+
files.any? ? selector.predefined(included: files, excluded: @excluded) : selector.excluding(@excluded)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def file_selector_for(language)
|
|
44
|
+
case language
|
|
45
|
+
when :ruby then FileSelector::Ruby
|
|
46
|
+
when :java then FileSelector::Java
|
|
47
|
+
when :javascript then FileSelector::JavaScript
|
|
48
|
+
when :python then FileSelector::Python
|
|
49
|
+
when :go then FileSelector::Go
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def complexity_for(language)
|
|
54
|
+
case language
|
|
55
|
+
when :ruby then Complexity::FlogCalculator
|
|
56
|
+
when :java then Complexity::PMD::FolderCalculator
|
|
57
|
+
when :javascript then Complexity::ESLintCalculator
|
|
58
|
+
when :python then Complexity::PythonCalculator
|
|
59
|
+
when :go then Complexity::GoCalculator
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChurnVsComplexity
|
|
4
|
+
module Triage
|
|
5
|
+
class Config
|
|
6
|
+
def initialize(
|
|
7
|
+
language:,
|
|
8
|
+
serializer: :json,
|
|
9
|
+
targets: [],
|
|
10
|
+
since: nil,
|
|
11
|
+
excluded: [],
|
|
12
|
+
complexity_validator: ComplexityValidator,
|
|
13
|
+
since_validator: Normal::SinceValidator,
|
|
14
|
+
**options
|
|
15
|
+
)
|
|
16
|
+
@language = language
|
|
17
|
+
@serializer = serializer
|
|
18
|
+
@targets = targets
|
|
19
|
+
@since = since
|
|
20
|
+
@excluded = excluded
|
|
21
|
+
@complexity_validator = complexity_validator
|
|
22
|
+
@since_validator = since_validator
|
|
23
|
+
@options = options
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def validate!
|
|
27
|
+
LanguageValidator.validate!(@language)
|
|
28
|
+
@since_validator.validate!(since: @since, relative_period: nil)
|
|
29
|
+
@complexity_validator.validate!(@language)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def checker
|
|
33
|
+
Checker.new(
|
|
34
|
+
language: @language,
|
|
35
|
+
serializer: triage_serializer,
|
|
36
|
+
targets: @targets,
|
|
37
|
+
since: @since,
|
|
38
|
+
excluded: @excluded,
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def triage_serializer
|
|
45
|
+
case @serializer
|
|
46
|
+
when :json
|
|
47
|
+
Serializer::Json
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module ChurnVsComplexity
|
|
6
|
+
module Triage
|
|
7
|
+
module Serializer
|
|
8
|
+
module Json
|
|
9
|
+
def self.serialize(result)
|
|
10
|
+
entries = RiskAnnotator.annotate(result[:values_by_file])
|
|
11
|
+
JSON.generate({ files: entries, summary: RiskAnnotator.risk_summary(entries) })
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/churn_vs_complexity.rb
CHANGED
|
@@ -32,6 +32,14 @@ require_relative 'churn_vs_complexity/git_date'
|
|
|
32
32
|
require_relative 'churn_vs_complexity/complexity_validator'
|
|
33
33
|
require_relative 'churn_vs_complexity/language_validator'
|
|
34
34
|
require_relative 'churn_vs_complexity/git_strategy'
|
|
35
|
+
require_relative 'churn_vs_complexity/gamma_score'
|
|
36
|
+
require_relative 'churn_vs_complexity/risk_classifier'
|
|
37
|
+
require_relative 'churn_vs_complexity/risk_annotator'
|
|
35
38
|
require_relative 'churn_vs_complexity/normal'
|
|
36
39
|
require_relative 'churn_vs_complexity/timetravel'
|
|
37
40
|
require_relative 'churn_vs_complexity/delta'
|
|
41
|
+
require_relative 'churn_vs_complexity/triage'
|
|
42
|
+
require_relative 'churn_vs_complexity/hotspots'
|
|
43
|
+
require_relative 'churn_vs_complexity/gate'
|
|
44
|
+
require_relative 'churn_vs_complexity/focus'
|
|
45
|
+
require_relative 'churn_vs_complexity/diff'
|
|
@@ -8,14 +8,16 @@ Type of change: modified
|
|
|
8
8
|
Complexity: 58.34326171010786
|
|
9
9
|
|
|
10
10
|
File, relative path: lib/churn_vs_complexity/serializer/timetravel/stats_calculator.rb
|
|
11
|
-
Type of change:
|
|
11
|
+
Type of change: new
|
|
12
|
+
Complexity: 80.35549194682164
|
|
12
13
|
|
|
13
14
|
File, relative path: test/churn_vs_complexity/serializer/timetravel/quality_calculator_test.rb
|
|
14
15
|
Type of change: modified
|
|
15
16
|
Complexity: 13.054183368177016
|
|
16
17
|
|
|
17
18
|
File, relative path: test/churn_vs_complexity/serializer/timetravel/stats_calculator_test.rb
|
|
18
|
-
Type of change:
|
|
19
|
+
Type of change: new
|
|
20
|
+
Complexity: 12.2198021565134
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
|
|
@@ -29,7 +31,8 @@ Type of change: modified
|
|
|
29
31
|
Complexity: 70.26655854867414
|
|
30
32
|
|
|
31
33
|
File, relative path: lib/churn_vs_complexity/serializer/pass_through.rb
|
|
32
|
-
Type of change:
|
|
34
|
+
Type of change: new
|
|
35
|
+
Complexity: 19.309088021254183
|
|
33
36
|
|
|
34
37
|
File, relative path: lib/churn_vs_complexity/serializer/summary_hash.rb
|
|
35
38
|
Type of change: modified
|
|
@@ -40,11 +43,13 @@ Type of change: modified
|
|
|
40
43
|
Complexity: 131.0989019732436
|
|
41
44
|
|
|
42
45
|
File, relative path: lib/churn_vs_complexity/serializer/timetravel/quality_calculator.rb
|
|
43
|
-
Type of change:
|
|
46
|
+
Type of change: new
|
|
47
|
+
Complexity: 23.324498016752965
|
|
44
48
|
|
|
45
49
|
File, relative path: test/churn_vs_complexity/serializer/summary_hash_test.rb
|
|
46
50
|
Type of change: modified
|
|
47
51
|
Complexity: 14.396336540125482
|
|
48
52
|
|
|
49
53
|
File, relative path: test/churn_vs_complexity/serializer/timetravel/quality_calculator_test.rb
|
|
50
|
-
Type of change:
|
|
54
|
+
Type of change: new
|
|
55
|
+
Complexity: 13.054183368177016
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Commit, Relative Path, Type of Change, Complexity
|
|
2
2
|
b20a9bddd04afb9c7a736cf4530fd3188b5f785e, lib/churn_vs_complexity/serializer/timetravel.rb, modified, 58.34326171010786
|
|
3
|
-
b20a9bddd04afb9c7a736cf4530fd3188b5f785e, lib/churn_vs_complexity/serializer/timetravel/stats_calculator.rb,
|
|
3
|
+
b20a9bddd04afb9c7a736cf4530fd3188b5f785e, lib/churn_vs_complexity/serializer/timetravel/stats_calculator.rb, new, 80.35549194682164
|
|
4
4
|
b20a9bddd04afb9c7a736cf4530fd3188b5f785e, test/churn_vs_complexity/serializer/timetravel/quality_calculator_test.rb, modified, 13.054183368177016
|
|
5
|
-
b20a9bddd04afb9c7a736cf4530fd3188b5f785e, test/churn_vs_complexity/serializer/timetravel/stats_calculator_test.rb,
|
|
5
|
+
b20a9bddd04afb9c7a736cf4530fd3188b5f785e, test/churn_vs_complexity/serializer/timetravel/stats_calculator_test.rb, new, 12.2198021565134
|
|
6
6
|
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/config.rb, modified, 70.26655854867414
|
|
7
|
-
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/pass_through.rb,
|
|
7
|
+
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/pass_through.rb, new, 19.309088021254183
|
|
8
8
|
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/summary_hash.rb, modified, 89.25682464940157
|
|
9
9
|
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/timetravel.rb, modified, 131.0989019732436
|
|
10
|
-
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/timetravel/quality_calculator.rb,
|
|
10
|
+
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/timetravel/quality_calculator.rb, new, 23.324498016752965
|
|
11
11
|
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, test/churn_vs_complexity/serializer/summary_hash_test.rb, modified, 14.396336540125482
|
|
12
|
-
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, test/churn_vs_complexity/serializer/timetravel/quality_calculator_test.rb,
|
|
12
|
+
4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, test/churn_vs_complexity/serializer/timetravel/quality_calculator_test.rb, new, 13.054183368177016
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: churn_vs_complexity
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Erik T. Madsen
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: flog
|
|
@@ -52,6 +52,7 @@ files:
|
|
|
52
52
|
- ".devcontainer/devcontainer.json"
|
|
53
53
|
- ".rubocop.yml"
|
|
54
54
|
- CHANGELOG.md
|
|
55
|
+
- CLAUDE.md
|
|
55
56
|
- Dockerfile
|
|
56
57
|
- Dockerfile.dev
|
|
57
58
|
- LICENSE.txt
|
|
@@ -67,9 +68,11 @@ files:
|
|
|
67
68
|
- lib/churn_vs_complexity/complexity.rb
|
|
68
69
|
- lib/churn_vs_complexity/complexity/eslint_calculator.rb
|
|
69
70
|
- lib/churn_vs_complexity/complexity/flog_calculator.rb
|
|
71
|
+
- lib/churn_vs_complexity/complexity/go_calculator.rb
|
|
70
72
|
- lib/churn_vs_complexity/complexity/pmd.rb
|
|
71
73
|
- lib/churn_vs_complexity/complexity/pmd/files_calculator.rb
|
|
72
74
|
- lib/churn_vs_complexity/complexity/pmd/folder_calculator.rb
|
|
75
|
+
- lib/churn_vs_complexity/complexity/python_calculator.rb
|
|
73
76
|
- lib/churn_vs_complexity/complexity_validator.rb
|
|
74
77
|
- lib/churn_vs_complexity/concurrent_calculator.rb
|
|
75
78
|
- lib/churn_vs_complexity/delta.rb
|
|
@@ -80,19 +83,39 @@ files:
|
|
|
80
83
|
- lib/churn_vs_complexity/delta/factory.rb
|
|
81
84
|
- lib/churn_vs_complexity/delta/multi_checker.rb
|
|
82
85
|
- lib/churn_vs_complexity/delta/serializer.rb
|
|
86
|
+
- lib/churn_vs_complexity/diff.rb
|
|
87
|
+
- lib/churn_vs_complexity/diff/checker.rb
|
|
88
|
+
- lib/churn_vs_complexity/diff/config.rb
|
|
89
|
+
- lib/churn_vs_complexity/diff/serializer.rb
|
|
83
90
|
- lib/churn_vs_complexity/engine.rb
|
|
84
91
|
- lib/churn_vs_complexity/file_selector.rb
|
|
92
|
+
- lib/churn_vs_complexity/focus.rb
|
|
93
|
+
- lib/churn_vs_complexity/focus/checker.rb
|
|
94
|
+
- lib/churn_vs_complexity/focus/config.rb
|
|
95
|
+
- lib/churn_vs_complexity/focus/serializer.rb
|
|
96
|
+
- lib/churn_vs_complexity/gamma_score.rb
|
|
97
|
+
- lib/churn_vs_complexity/gate.rb
|
|
98
|
+
- lib/churn_vs_complexity/gate/checker.rb
|
|
99
|
+
- lib/churn_vs_complexity/gate/config.rb
|
|
100
|
+
- lib/churn_vs_complexity/gate/serializer.rb
|
|
85
101
|
- lib/churn_vs_complexity/git_date.rb
|
|
86
102
|
- lib/churn_vs_complexity/git_strategy.rb
|
|
103
|
+
- lib/churn_vs_complexity/hotspots.rb
|
|
104
|
+
- lib/churn_vs_complexity/hotspots/checker.rb
|
|
105
|
+
- lib/churn_vs_complexity/hotspots/config.rb
|
|
106
|
+
- lib/churn_vs_complexity/hotspots/serializer.rb
|
|
87
107
|
- lib/churn_vs_complexity/language_validator.rb
|
|
88
108
|
- lib/churn_vs_complexity/normal.rb
|
|
89
109
|
- lib/churn_vs_complexity/normal/config.rb
|
|
90
110
|
- lib/churn_vs_complexity/normal/serializer.rb
|
|
91
111
|
- lib/churn_vs_complexity/normal/serializer/csv.rb
|
|
92
112
|
- lib/churn_vs_complexity/normal/serializer/graph.rb
|
|
113
|
+
- lib/churn_vs_complexity/normal/serializer/json.rb
|
|
93
114
|
- lib/churn_vs_complexity/normal/serializer/pass_through.rb
|
|
94
115
|
- lib/churn_vs_complexity/normal/serializer/summary.rb
|
|
95
116
|
- lib/churn_vs_complexity/normal/serializer/summary_hash.rb
|
|
117
|
+
- lib/churn_vs_complexity/risk_annotator.rb
|
|
118
|
+
- lib/churn_vs_complexity/risk_classifier.rb
|
|
96
119
|
- lib/churn_vs_complexity/timetravel.rb
|
|
97
120
|
- lib/churn_vs_complexity/timetravel/config.rb
|
|
98
121
|
- lib/churn_vs_complexity/timetravel/factory.rb
|
|
@@ -101,6 +124,10 @@ files:
|
|
|
101
124
|
- lib/churn_vs_complexity/timetravel/serializer/stats_calculator.rb
|
|
102
125
|
- lib/churn_vs_complexity/timetravel/traveller.rb
|
|
103
126
|
- lib/churn_vs_complexity/timetravel/worktree.rb
|
|
127
|
+
- lib/churn_vs_complexity/triage.rb
|
|
128
|
+
- lib/churn_vs_complexity/triage/checker.rb
|
|
129
|
+
- lib/churn_vs_complexity/triage/config.rb
|
|
130
|
+
- lib/churn_vs_complexity/triage/serializer.rb
|
|
104
131
|
- lib/churn_vs_complexity/version.rb
|
|
105
132
|
- package-lock.json
|
|
106
133
|
- tmp/eslint-support/complexity-calculator.js
|
|
@@ -110,12 +137,16 @@ files:
|
|
|
110
137
|
- tmp/template/timetravel_graph.html
|
|
111
138
|
- tmp/test-support/delta/ruby-summary.txt
|
|
112
139
|
- tmp/test-support/delta/ruby.csv
|
|
140
|
+
- tmp/test-support/go/main.go
|
|
141
|
+
- tmp/test-support/go/utils.go
|
|
113
142
|
- tmp/test-support/java/small-example/src/main/java/org/example/Main.java
|
|
114
143
|
- tmp/test-support/java/small-example/src/main/java/org/example/spice/Checker.java
|
|
115
144
|
- tmp/test-support/javascript/complex.js
|
|
116
145
|
- tmp/test-support/javascript/moderate.js
|
|
117
146
|
- tmp/test-support/javascript/simple.js
|
|
118
147
|
- tmp/test-support/javascript/typescript-example.ts
|
|
148
|
+
- tmp/test-support/python/example.py
|
|
149
|
+
- tmp/test-support/python/utils.py
|
|
119
150
|
- tmp/test-support/txt/abc.txt
|
|
120
151
|
- tmp/test-support/txt/d.txt
|
|
121
152
|
- tmp/test-support/txt/ef.txt
|
|
@@ -148,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
148
179
|
- !ruby/object:Gem::Version
|
|
149
180
|
version: '0'
|
|
150
181
|
requirements: []
|
|
151
|
-
rubygems_version: 3.6.
|
|
182
|
+
rubygems_version: 3.6.7
|
|
152
183
|
specification_version: 4
|
|
153
184
|
summary: A tool to visualise code complexity in projects and help direct refactoring
|
|
154
185
|
efforts.
|