churn_vs_complexity 1.4.0 → 1.5.2

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +29 -14
  4. data/README.md +10 -4
  5. data/lib/churn_vs_complexity/churn.rb +9 -1
  6. data/lib/churn_vs_complexity/cli/main.rb +46 -0
  7. data/lib/churn_vs_complexity/cli/parser.rb +91 -0
  8. data/lib/churn_vs_complexity/cli.rb +11 -94
  9. data/lib/churn_vs_complexity/complexity/eslint_calculator.rb +6 -0
  10. data/lib/churn_vs_complexity/complexity/pmd/files_calculator.rb +26 -0
  11. data/lib/churn_vs_complexity/complexity/pmd/folder_calculator.rb +20 -0
  12. data/lib/churn_vs_complexity/complexity/{pmd_calculator.rb → pmd.rb} +14 -21
  13. data/lib/churn_vs_complexity/complexity.rb +1 -1
  14. data/lib/churn_vs_complexity/complexity_validator.rb +14 -0
  15. data/lib/churn_vs_complexity/concurrent_calculator.rb +5 -3
  16. data/lib/churn_vs_complexity/delta/checker.rb +54 -0
  17. data/lib/churn_vs_complexity/delta/commit_hydrator.rb +22 -0
  18. data/lib/churn_vs_complexity/delta/complexity_annotator.rb +30 -0
  19. data/lib/churn_vs_complexity/delta/config.rb +50 -0
  20. data/lib/churn_vs_complexity/delta/factory.rb +22 -0
  21. data/lib/churn_vs_complexity/delta/multi_checker.rb +48 -0
  22. data/lib/churn_vs_complexity/delta/serializer.rb +69 -0
  23. data/lib/churn_vs_complexity/delta.rb +52 -0
  24. data/lib/churn_vs_complexity/engine.rb +1 -1
  25. data/lib/churn_vs_complexity/file_selector.rb +47 -4
  26. data/lib/churn_vs_complexity/git_strategy.rb +62 -0
  27. data/lib/churn_vs_complexity/language_validator.rb +9 -0
  28. data/lib/churn_vs_complexity/normal/config.rb +85 -0
  29. data/lib/churn_vs_complexity/normal/serializer/csv.rb +16 -0
  30. data/lib/churn_vs_complexity/normal/serializer/graph.rb +26 -0
  31. data/lib/churn_vs_complexity/normal/serializer/pass_through.rb +23 -0
  32. data/lib/churn_vs_complexity/normal/serializer/summary.rb +29 -0
  33. data/lib/churn_vs_complexity/normal/serializer/summary_hash.rb +56 -0
  34. data/lib/churn_vs_complexity/normal/serializer.rb +29 -0
  35. data/lib/churn_vs_complexity/normal.rb +45 -0
  36. data/lib/churn_vs_complexity/timetravel/config.rb +75 -0
  37. data/lib/churn_vs_complexity/timetravel/factory.rb +12 -0
  38. data/lib/churn_vs_complexity/{serializer/timetravel → timetravel/serializer}/quality_calculator.rb +2 -2
  39. data/lib/churn_vs_complexity/{serializer/timetravel → timetravel/serializer}/stats_calculator.rb +2 -2
  40. data/lib/churn_vs_complexity/{serializer/timetravel.rb → timetravel/serializer.rb} +6 -6
  41. data/lib/churn_vs_complexity/timetravel/traveller.rb +5 -11
  42. data/lib/churn_vs_complexity/timetravel/worktree.rb +30 -14
  43. data/lib/churn_vs_complexity/timetravel.rb +36 -39
  44. data/lib/churn_vs_complexity/version.rb +1 -1
  45. data/lib/churn_vs_complexity.rb +23 -7
  46. data/tmp/test-support/delta/ruby-summary.txt +50 -0
  47. data/tmp/test-support/delta/ruby.csv +12 -0
  48. metadata +38 -20
  49. data/.travis.yml +0 -7
  50. data/lib/churn_vs_complexity/config.rb +0 -159
  51. data/lib/churn_vs_complexity/serializer/csv.rb +0 -14
  52. data/lib/churn_vs_complexity/serializer/graph.rb +0 -24
  53. data/lib/churn_vs_complexity/serializer/pass_through.rb +0 -21
  54. data/lib/churn_vs_complexity/serializer/summary.rb +0 -27
  55. data/lib/churn_vs_complexity/serializer/summary_hash.rb +0 -54
  56. data/lib/churn_vs_complexity/serializer.rb +0 -26
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'normal/config'
4
+ require_relative 'normal/serializer'
5
+
6
+ module ChurnVsComplexity
7
+ module Normal
8
+ # TODO: unit test
9
+ module SerializerValidator
10
+ def self.validate!(serializer:)
11
+ raise ValidationError, "Unsupported serializer: #{serializer}" \
12
+ unless %i[none csv graph summary].include?(serializer)
13
+ end
14
+ end
15
+
16
+ # TODO: unit test
17
+ module RelativePeriodValidator
18
+ def self.validate!(relative_period:)
19
+ return if relative_period.nil? || %i[month quarter year].include?(relative_period)
20
+
21
+ raise ValidationError, "Invalid relative period #{relative_period}"
22
+ end
23
+ end
24
+
25
+ module SinceValidator
26
+ def self.validate!(since:, relative_period:)
27
+ # since can be nil, a date string or a keyword (:month, :quarter, :year)
28
+ return if since.nil?
29
+
30
+ unless since.nil? || relative_period.nil?
31
+ raise ValidationError,
32
+ '--since and relative period (--month, --quarter, --year) cannot be used together in normal mode'
33
+ end
34
+
35
+ raise ValidationError, "Invalid since value #{since}" unless since.is_a?(String)
36
+
37
+ begin
38
+ Date.strptime(since, '%Y-%m-%d')
39
+ rescue Date::Error
40
+ raise ValidationError, "Invalid date #{since}, please use correct format, YYYY-MM-DD"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChurnVsComplexity
4
+ module Timetravel
5
+ class Config
6
+ def initialize(
7
+ language:,
8
+ serializer:,
9
+ jump_days:, excluded: [],
10
+ since: nil,
11
+ relative_period: nil,
12
+ complexity_validator: ComplexityValidator,
13
+ since_validator: SinceValidator,
14
+ factory: Factory,
15
+ **options
16
+ )
17
+ @language = language
18
+ @serializer = serializer
19
+ @excluded = excluded
20
+ @since = since
21
+ @relative_period = relative_period
22
+ @jump_days = jump_days
23
+ @complexity_validator = complexity_validator
24
+ @since_validator = since_validator
25
+ @factory = factory
26
+ @options = options
27
+ end
28
+
29
+ def validate!
30
+ raise ValidationError, 'Must specify jump days!' if @jump_days.nil?
31
+
32
+ LanguageValidator.validate!(@language)
33
+
34
+ SerializerValidator.validate!(serializer: @serializer)
35
+
36
+ @since_validator.validate!(since: @since)
37
+ RelativePeriodValidator.validate!(relative_period: @relative_period)
38
+ @complexity_validator.validate!(@language)
39
+ end
40
+
41
+ def checker = traveller(git_period: GitDate.git_period(@since, Time.now.to_date))
42
+
43
+ private
44
+
45
+ def traveller(git_period:)
46
+ Traveller.new(
47
+ git_period:,
48
+ relative_period: @relative_period,
49
+ engine: engine_config.checker,
50
+ jump_days: @jump_days,
51
+ serializer: serializer(git_period:),
52
+ factory: @factory,
53
+ )
54
+ end
55
+
56
+ def serializer(git_period:)
57
+ Serializer.resolve(serializer: @serializer, git_period:, relative_period: @relative_period,
58
+ jump_days: @jump_days,)
59
+ end
60
+
61
+ def engine_config
62
+ Normal::Config.new(
63
+ language: @language,
64
+ serializer: :pass_through,
65
+ excluded: @excluded,
66
+ since: nil, # since has a different meaning in timetravel mode
67
+ relative_period: @relative_period,
68
+ complexity_validator: @complexity_validator,
69
+ since_validator: @since_validator,
70
+ **@options,
71
+ )
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChurnVsComplexity
4
+ module Timetravel
5
+ module Factory
6
+ def self.git_strategy(folder:) = GitStrategy.new(folder:)
7
+ def self.pipe = IO.pipe
8
+ def self.worker(engine:, worktree:) = Worker.new(engine:, worktree:)
9
+ def self.worktree(root_folder:, git_strategy:, number:) = Worktree.new(root_folder:, git_strategy:, number:)
10
+ end
11
+ end
12
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChurnVsComplexity
4
- module Serializer
5
- module Timetravel
4
+ module Timetravel
5
+ module Serializer
6
6
  EPSILON = 0.0001
7
7
 
8
8
  class QualityCalculator
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChurnVsComplexity
4
- module Serializer
5
- module Timetravel
4
+ module Timetravel
5
+ module Serializer
6
6
  class StatsCalculator
7
7
  # ['some_sha', { 'end_date' => '2024-01-01', 'values' => [[1, 2], [3, 4]] }]
8
8
  def summaries(result)
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'timetravel/quality_calculator'
4
- require_relative 'timetravel/stats_calculator'
3
+ require_relative 'serializer/quality_calculator'
4
+ require_relative 'serializer/stats_calculator'
5
5
 
6
6
  module ChurnVsComplexity
7
- module Serializer
8
- module Timetravel
7
+ module Timetravel
8
+ module Serializer
9
9
  def self.summaries(result)
10
10
  StatsCalculator.new.summaries(result)
11
11
  end
@@ -21,7 +21,7 @@ module ChurnVsComplexity
21
21
 
22
22
  module CSV
23
23
  def self.serialize(result)
24
- summaries = Timetravel.summaries(result)
24
+ summaries = Serializer.summaries(result)
25
25
 
26
26
  # 2. Add title row to front of summaries
27
27
  summaries.unshift(
@@ -60,7 +60,7 @@ module ChurnVsComplexity
60
60
  end
61
61
 
62
62
  def serialize(result)
63
- summaries = Timetravel.summaries(result)
63
+ summaries = Serializer.summaries(result)
64
64
 
65
65
  data = summaries.map do |summary|
66
66
  JSON.dump(summary)
@@ -4,16 +4,16 @@ module ChurnVsComplexity
4
4
  # TODO: unit test and integration test
5
5
  module Timetravel
6
6
  class Traveller
7
- def initialize(since:, relative_period:, engine:, serializer:, jump_days:, factory: Factory)
7
+ def initialize(git_period:, relative_period:, engine:, serializer:, jump_days:, factory:)
8
8
  @relative_period = relative_period
9
9
  @engine = engine
10
10
  @jump_days = jump_days
11
11
  @serializer = serializer
12
- @git_period = GitDate.git_period(since, Time.now.to_date)
12
+ @git_period = git_period
13
13
  @factory = factory
14
14
  end
15
15
 
16
- def go(folder:)
16
+ def check(folder:)
17
17
  git_strategy = @factory.git_strategy(folder:)
18
18
  commits = git_strategy.resolve_commits_with_interval(git_period: @git_period, jump_days: @jump_days)
19
19
 
@@ -21,7 +21,7 @@ module ChurnVsComplexity
21
21
  work_on(chunked:, folder:, git_strategy:)
22
22
  combined = chunked.map { |c_and_p| read_result(c_and_p[:pipe]) }.reduce({}, :merge)
23
23
 
24
- serializer.serialize(combined)
24
+ @serializer.serialize(combined)
25
25
  end
26
26
 
27
27
  private
@@ -44,8 +44,7 @@ module ChurnVsComplexity
44
44
  def read_result(pipe)
45
45
  part = begin
46
46
  JSON.parse(pipe[0].gets)
47
- rescue StandardError => e
48
- warn "Error parsing JSON: #{e}"
47
+ rescue StandardError
49
48
  {}
50
49
  end
51
50
  pipe.each(&:close)
@@ -56,11 +55,6 @@ module ChurnVsComplexity
56
55
  @factory.worker(engine: @engine, worktree:)
57
56
  .schedule(chunk:, pipe:)
58
57
  end
59
-
60
- def serializer
61
- @factory.serializer(serializer: @serializer, git_period: @git_period,
62
- relative_period: @relative_period, jump_days: @jump_days,)
63
- end
64
58
  end
65
59
  end
66
60
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'digest'
4
- require 'tmpdir'
5
-
6
3
  module ChurnVsComplexity
7
4
  module Timetravel
8
5
  class Worktree
@@ -16,6 +13,8 @@ module ChurnVsComplexity
16
13
 
17
14
  def prepare
18
15
  @folder = prepare_worktree
16
+ rescue StandardError => e
17
+ raise Error, "Failed to prepare worktree: #{e.message}"
19
18
  end
20
19
 
21
20
  def checkout(sha)
@@ -30,27 +29,44 @@ module ChurnVsComplexity
30
29
  @git_strategy.remove_worktree(@folder)
31
30
  end
32
31
 
33
- private
32
+ protected
34
33
 
35
34
  def tt_folder
36
- folder_hash = Digest::SHA256.hexdigest(@root_folder)[0..7]
37
- File.join(Dir.tmpdir, 'churn_vs_complexity', 'timetravel', folder_hash)
35
+ File.join(ChurnVsComplexity.tmp_dir_path(@root_folder), 'timetravel')
36
+ end
37
+
38
+ private
39
+
40
+ def worktree_folder
41
+ @worktree_folder ||= File.join(tt_folder, "worktree_#{@number}")
38
42
  end
39
43
 
40
44
  def prepare_worktree
41
- worktree_folder = File.join(tt_folder, "worktree_#{@number}")
42
-
43
- unless File.directory?(worktree_folder)
44
- begin
45
- FileUtils.mkdir_p(worktree_folder)
46
- rescue StandardError
47
- nil
48
- end
45
+ if File.directory?(worktree_folder)
46
+ prepare_worktree_in_existing_dir
47
+ else
48
+ create_worktree_folder
49
49
  @git_strategy.add_worktree(worktree_folder)
50
50
  end
51
51
 
52
52
  worktree_folder
53
53
  end
54
+
55
+ def create_worktree_folder
56
+ FileUtils.mkdir_p(worktree_folder)
57
+ rescue Errno::EEXIST
58
+ # Folder was created by another process, which is fine
59
+ end
60
+
61
+ def prepare_worktree_in_existing_dir
62
+ Git.open(worktree_folder)
63
+ rescue ArgumentError
64
+ # Delete the worktree folder and try again
65
+ FileUtils.rm_rf(worktree_folder)
66
+ prepare_worktree
67
+ end
68
+
69
+ class Error < ChurnVsComplexity::Error; end
54
70
  end
55
71
  end
56
72
  end
@@ -2,15 +2,45 @@
2
2
 
3
3
  require_relative 'timetravel/traveller'
4
4
  require_relative 'timetravel/worktree'
5
+ require_relative 'timetravel/config'
6
+ require_relative 'timetravel/serializer'
7
+ require_relative 'timetravel/factory'
5
8
 
6
9
  module ChurnVsComplexity
7
10
  module Timetravel
8
- class Factory
9
- def self.git_strategy(folder:) = GitStrategy.new(folder:)
10
- def self.pipe = IO.pipe
11
- def self.worker(engine:, worktree:) = Worker.new(engine:, worktree:)
12
- def self.worktree(root_folder:, git_strategy:, number:) = Worktree.new(root_folder:, git_strategy:, number:)
13
- def self.serializer(**args) = Serializer::Timetravel.resolve(**args)
11
+ # TODO: unit test
12
+ module SerializerValidator
13
+ def self.validate!(serializer:)
14
+ raise ValidationError, 'Does not support --summary in --timetravel mode' \
15
+ if serializer == :summary
16
+ raise ValidationError, "Unsupported serializer: #{serializer}" \
17
+ unless %i[none csv graph].include?(serializer)
18
+ end
19
+ end
20
+
21
+ # TODO: unit test
22
+ module RelativePeriodValidator
23
+ def self.validate!(relative_period:)
24
+ raise ValidationError, 'Relative period is required in timetravel mode' if relative_period.nil?
25
+ return if relative_period.nil? || %i[month quarter year].include?(relative_period)
26
+
27
+ raise ValidationError, "Invalid relative period #{relative_period}"
28
+ end
29
+ end
30
+
31
+ module SinceValidator
32
+ def self.validate!(since:)
33
+ # since can be nil, a date string or a keyword (:month, :quarter, :year)
34
+ return if since.nil?
35
+
36
+ raise ValidationError, "Invalid since value #{since}" unless since.is_a?(String)
37
+
38
+ begin
39
+ Date.strptime(since, '%Y-%m-%d')
40
+ rescue Date::Error
41
+ raise ValidationError, "Invalid date #{since}, please use correct format, YYYY-MM-DD"
42
+ end
43
+ end
14
44
  end
15
45
 
16
46
  class Worker
@@ -33,38 +63,5 @@ module ChurnVsComplexity
33
63
  end
34
64
  end
35
65
  end
36
-
37
- class GitStrategy
38
- def initialize(folder:)
39
- @repo = Git.open(folder)
40
- @folder = folder
41
- end
42
-
43
- def checkout_in_worktree(worktree_folder, sha)
44
- command = "(cd #{worktree_folder} && git checkout #{sha}) > /dev/null 2>&1"
45
- `#{command}`
46
- end
47
-
48
- def resolve_commits_with_interval(git_period:, jump_days:)
49
- candidates = @repo.log(1_000_000).since(git_period.effective_start_date).until(git_period.end_date).to_a
50
-
51
- commits_by_date = candidates.filter { |c| c.date.to_date >= git_period.effective_start_date }
52
- .group_by { |c| c.date.to_date }
53
-
54
- found_dates = GitDate.select_dates_with_at_least_interval(commits_by_date.keys, jump_days)
55
-
56
- found_dates.map { |date| commits_by_date[date].max_by(&:date) }
57
- end
58
-
59
- def add_worktree(wt_folder)
60
- command = "(cd #{@folder} && git worktree add -f #{wt_folder}) > /dev/null 2>&1"
61
- `#{command}`
62
- end
63
-
64
- def remove_worktree(worktree_folder)
65
- command = "(cd #{worktree_folder} && git worktree remove -f #{worktree_folder}) > /dev/null 2>&1"
66
- `#{command}`
67
- end
68
- end
69
66
  end
70
67
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChurnVsComplexity
4
- VERSION = '1.4.0'
4
+ VERSION = '1.5.2'
5
5
  end
@@ -2,6 +2,24 @@
2
2
 
3
3
  require 'json'
4
4
  require 'etc'
5
+ require 'date'
6
+ require 'time'
7
+ require 'tmpdir'
8
+
9
+ require 'digest'
10
+
11
+ module ChurnVsComplexity
12
+ class Error < StandardError; end
13
+ class ValidationError < Error; end
14
+
15
+ ROOT_PATH = File.expand_path('..', __dir__)
16
+
17
+ def self.tmp_dir_path(*components)
18
+ combined = components.join('/')
19
+ folder_hash = Digest::SHA256.hexdigest(combined)[0..7]
20
+ File.join(Dir.tmpdir, 'churn_vs_complexity', folder_hash)
21
+ end
22
+ end
5
23
 
6
24
  require_relative 'churn_vs_complexity/version'
7
25
  require_relative 'churn_vs_complexity/engine'
@@ -10,12 +28,10 @@ require_relative 'churn_vs_complexity/file_selector'
10
28
  require_relative 'churn_vs_complexity/complexity'
11
29
  require_relative 'churn_vs_complexity/churn'
12
30
  require_relative 'churn_vs_complexity/cli'
13
- require_relative 'churn_vs_complexity/config'
14
- require_relative 'churn_vs_complexity/serializer'
15
31
  require_relative 'churn_vs_complexity/git_date'
32
+ require_relative 'churn_vs_complexity/complexity_validator'
33
+ require_relative 'churn_vs_complexity/language_validator'
34
+ require_relative 'churn_vs_complexity/git_strategy'
35
+ require_relative 'churn_vs_complexity/normal'
16
36
  require_relative 'churn_vs_complexity/timetravel'
17
-
18
- module ChurnVsComplexity
19
- class Error < StandardError; end
20
- class ValidationError < Error; end
21
- end
37
+ require_relative 'churn_vs_complexity/delta'
@@ -0,0 +1,50 @@
1
+ Commit: b20a9bddd04afb9c7a736cf4530fd3188b5f785e
2
+ Parent: 4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0
3
+ Next: 8cdaac516365bd7007b9f755bbe6f6e86d8e13dd
4
+
5
+
6
+ File, relative path: lib/churn_vs_complexity/serializer/timetravel.rb
7
+ Type of change: modified
8
+ Complexity: 58.34326171010786
9
+
10
+ File, relative path: lib/churn_vs_complexity/serializer/timetravel/stats_calculator.rb
11
+ Type of change: deleted
12
+
13
+ File, relative path: test/churn_vs_complexity/serializer/timetravel/quality_calculator_test.rb
14
+ Type of change: modified
15
+ Complexity: 13.054183368177016
16
+
17
+ File, relative path: test/churn_vs_complexity/serializer/timetravel/stats_calculator_test.rb
18
+ Type of change: deleted
19
+
20
+
21
+
22
+ Commit: 4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0
23
+ Parent: 83deeccf8aa40e46cd0ca7e2c603c9726633256e
24
+ Next: b20a9bddd04afb9c7a736cf4530fd3188b5f785e
25
+
26
+
27
+ File, relative path: lib/churn_vs_complexity/config.rb
28
+ Type of change: modified
29
+ Complexity: 70.26655854867414
30
+
31
+ File, relative path: lib/churn_vs_complexity/serializer/pass_through.rb
32
+ Type of change: deleted
33
+
34
+ File, relative path: lib/churn_vs_complexity/serializer/summary_hash.rb
35
+ Type of change: modified
36
+ Complexity: 89.25682464940157
37
+
38
+ File, relative path: lib/churn_vs_complexity/serializer/timetravel.rb
39
+ Type of change: modified
40
+ Complexity: 131.0989019732436
41
+
42
+ File, relative path: lib/churn_vs_complexity/serializer/timetravel/quality_calculator.rb
43
+ Type of change: deleted
44
+
45
+ File, relative path: test/churn_vs_complexity/serializer/summary_hash_test.rb
46
+ Type of change: modified
47
+ Complexity: 14.396336540125482
48
+
49
+ File, relative path: test/churn_vs_complexity/serializer/timetravel/quality_calculator_test.rb
50
+ Type of change: deleted
@@ -0,0 +1,12 @@
1
+ Commit, Relative Path, Type of Change, Complexity
2
+ b20a9bddd04afb9c7a736cf4530fd3188b5f785e, lib/churn_vs_complexity/serializer/timetravel.rb, modified, 58.34326171010786
3
+ b20a9bddd04afb9c7a736cf4530fd3188b5f785e, lib/churn_vs_complexity/serializer/timetravel/stats_calculator.rb, deleted,
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, deleted,
6
+ 4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/config.rb, modified, 70.26655854867414
7
+ 4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/pass_through.rb, deleted,
8
+ 4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/summary_hash.rb, modified, 89.25682464940157
9
+ 4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/timetravel.rb, modified, 131.0989019732436
10
+ 4f3151f83e982eb8f2b8a4e7a7572a0af156c3c0, lib/churn_vs_complexity/serializer/timetravel/quality_calculator.rb, deleted,
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, deleted,
metadata CHANGED
@@ -1,14 +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.0
4
+ version: 1.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik T. Madsen
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-10 00:00:00.000000000 Z
10
+ date: 2024-10-21 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: flog
@@ -39,8 +38,10 @@ dependencies:
39
38
  - !ruby/object:Gem::Version
40
39
  version: '2.1'
41
40
  description: Inspired by Michael Feathers' article "Getting Empirical about Refactoring"
42
- and the gem 'turbulence' by Chad Fowler and others. This gem was built primarily
43
- to support analysis of Java and Ruby repositories, but it can easily be extended.
41
+ and the gem 'turbulence' by Chad Fowler and others. This gem currently supports
42
+ analysis of Java, Ruby, JavaScript, and TypeScript repositories, but it can easily
43
+ be extended. For a more detailed introduction, please consult the project README
44
+ in the GitHub repository.
44
45
  email:
45
46
  - beatmadsen@gmail.com
46
47
  executables:
@@ -50,7 +51,6 @@ extra_rdoc_files: []
50
51
  files:
51
52
  - ".devcontainer/devcontainer.json"
52
53
  - ".rubocop.yml"
53
- - ".travis.yml"
54
54
  - CHANGELOG.md
55
55
  - Dockerfile
56
56
  - Dockerfile.dev
@@ -62,25 +62,43 @@ files:
62
62
  - lib/churn_vs_complexity.rb
63
63
  - lib/churn_vs_complexity/churn.rb
64
64
  - lib/churn_vs_complexity/cli.rb
65
+ - lib/churn_vs_complexity/cli/main.rb
66
+ - lib/churn_vs_complexity/cli/parser.rb
65
67
  - lib/churn_vs_complexity/complexity.rb
66
68
  - lib/churn_vs_complexity/complexity/eslint_calculator.rb
67
69
  - lib/churn_vs_complexity/complexity/flog_calculator.rb
68
- - lib/churn_vs_complexity/complexity/pmd_calculator.rb
70
+ - lib/churn_vs_complexity/complexity/pmd.rb
71
+ - lib/churn_vs_complexity/complexity/pmd/files_calculator.rb
72
+ - lib/churn_vs_complexity/complexity/pmd/folder_calculator.rb
73
+ - lib/churn_vs_complexity/complexity_validator.rb
69
74
  - lib/churn_vs_complexity/concurrent_calculator.rb
70
- - lib/churn_vs_complexity/config.rb
75
+ - lib/churn_vs_complexity/delta.rb
76
+ - lib/churn_vs_complexity/delta/checker.rb
77
+ - lib/churn_vs_complexity/delta/commit_hydrator.rb
78
+ - lib/churn_vs_complexity/delta/complexity_annotator.rb
79
+ - lib/churn_vs_complexity/delta/config.rb
80
+ - lib/churn_vs_complexity/delta/factory.rb
81
+ - lib/churn_vs_complexity/delta/multi_checker.rb
82
+ - lib/churn_vs_complexity/delta/serializer.rb
71
83
  - lib/churn_vs_complexity/engine.rb
72
84
  - lib/churn_vs_complexity/file_selector.rb
73
85
  - lib/churn_vs_complexity/git_date.rb
74
- - lib/churn_vs_complexity/serializer.rb
75
- - lib/churn_vs_complexity/serializer/csv.rb
76
- - lib/churn_vs_complexity/serializer/graph.rb
77
- - lib/churn_vs_complexity/serializer/pass_through.rb
78
- - lib/churn_vs_complexity/serializer/summary.rb
79
- - lib/churn_vs_complexity/serializer/summary_hash.rb
80
- - lib/churn_vs_complexity/serializer/timetravel.rb
81
- - lib/churn_vs_complexity/serializer/timetravel/quality_calculator.rb
82
- - lib/churn_vs_complexity/serializer/timetravel/stats_calculator.rb
86
+ - lib/churn_vs_complexity/git_strategy.rb
87
+ - lib/churn_vs_complexity/language_validator.rb
88
+ - lib/churn_vs_complexity/normal.rb
89
+ - lib/churn_vs_complexity/normal/config.rb
90
+ - lib/churn_vs_complexity/normal/serializer.rb
91
+ - lib/churn_vs_complexity/normal/serializer/csv.rb
92
+ - lib/churn_vs_complexity/normal/serializer/graph.rb
93
+ - lib/churn_vs_complexity/normal/serializer/pass_through.rb
94
+ - lib/churn_vs_complexity/normal/serializer/summary.rb
95
+ - lib/churn_vs_complexity/normal/serializer/summary_hash.rb
83
96
  - lib/churn_vs_complexity/timetravel.rb
97
+ - lib/churn_vs_complexity/timetravel/config.rb
98
+ - lib/churn_vs_complexity/timetravel/factory.rb
99
+ - lib/churn_vs_complexity/timetravel/serializer.rb
100
+ - lib/churn_vs_complexity/timetravel/serializer/quality_calculator.rb
101
+ - lib/churn_vs_complexity/timetravel/serializer/stats_calculator.rb
84
102
  - lib/churn_vs_complexity/timetravel/traveller.rb
85
103
  - lib/churn_vs_complexity/timetravel/worktree.rb
86
104
  - lib/churn_vs_complexity/version.rb
@@ -90,6 +108,8 @@ files:
90
108
  - tmp/pmd-support/ruleset.xml
91
109
  - tmp/template/graph.html
92
110
  - tmp/template/timetravel_graph.html
111
+ - tmp/test-support/delta/ruby-summary.txt
112
+ - tmp/test-support/delta/ruby.csv
93
113
  - tmp/test-support/java/small-example/src/main/java/org/example/Main.java
94
114
  - tmp/test-support/java/small-example/src/main/java/org/example/spice/Checker.java
95
115
  - tmp/test-support/javascript/complex.js
@@ -114,7 +134,6 @@ metadata:
114
134
  source_code_uri: https://github.com/beatmadsen/churn_vs_complexity
115
135
  changelog_uri: https://github.com/beatmadsen/churn_vs_complexity/blob/main/CHANGELOG.md
116
136
  rubygems_mfa_required: 'true'
117
- post_install_message:
118
137
  rdoc_options: []
119
138
  require_paths:
120
139
  - lib
@@ -129,8 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
148
  - !ruby/object:Gem::Version
130
149
  version: '0'
131
150
  requirements: []
132
- rubygems_version: 3.5.11
133
- signing_key:
151
+ rubygems_version: 3.6.0.dev
134
152
  specification_version: 4
135
153
  summary: A tool to visualise code complexity in projects and help direct refactoring
136
154
  efforts.
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.10
7
- before_install: gem install bundler -v 1.17.2