code_keeper 0.4.0 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36a68ad1540e4e6adb062bc85c1ab015c280bfe604ac5644cdfc21dd1df58c9d
4
- data.tar.gz: 6850f00648efb8910be1eaf0125a3aa39a799a888a31e2c971946cab337dbdbb
3
+ metadata.gz: 66e68d33e3f03cbbe30bb5b77fcf0470667fc1ba9da620e3053f38707fd3b17b
4
+ data.tar.gz: 510711a6a8419fb0fcf803d532d332f7a353d9d84eda34a71cc52a56da6b265f
5
5
  SHA512:
6
- metadata.gz: 87718f55c24471bee5b26d21d108445103111b135e117872d8c0e709b20a21cdbd6b865d06db277e29722eb607ba3bb687f8eef6c509e68a47c1563052d7b2e3
7
- data.tar.gz: 63938e0590f3c9faa32ef9f71d7a1b45cc3685d0a46d2a53aaa6d8c222eefaf3119cb2bb5aac2eeb618a0bf092999c4283f3b98fc36554218624c4a9027b9054
6
+ metadata.gz: 36b18bf9a92fa12834dc74aa9e5985b2ad57c0e315a4b78ffc95deab045a14a08b884a83ef4592cf52cc3c4231695a0d8ed50334672e78e23d7fc4e6bb5ead33
7
+ data.tar.gz: cefd0d3ea837b5210b4bdb2ea63722fafb751f7c1b7d13f2a536a31b686993c97e2df832fac169239076d77497063a14cc92683d77334778c57e6fe91faa87b7
@@ -5,12 +5,16 @@ on: [push,pull_request]
5
5
  jobs:
6
6
  build:
7
7
  runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ ruby: [2.7, 3.0, 3.1]
11
+ name: Ruby ${{ matrix.ruby }}
8
12
  steps:
9
13
  - uses: actions/checkout@v2
10
14
  - name: Set up Ruby
11
15
  uses: ruby/setup-ruby@v1
12
16
  with:
13
- ruby-version: 3.0.0
17
+ ruby-version: ${{ matrix.ruby }}
14
18
  - name: Run the default task
15
19
  run: |
16
20
  gem install bundler -v 2.2.3
data/.rubocop.yml CHANGED
@@ -1,5 +1,4 @@
1
1
  AllCops:
2
- TargetRubyVersion: 3.0
3
2
  Exclude:
4
3
  - spec/fixtures/**/*.rb
5
4
 
@@ -57,3 +56,6 @@ Metrics/PerceivedComplexity:
57
56
  Exclude:
58
57
  # It's hard to control.
59
58
  - lib/code_keeper/metrics/class_length.rb
59
+
60
+ Metrics/MethodLength:
61
+ Max: 40
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unrelease
4
4
 
5
+ ## 0.6.0 (2022-03-27)
6
+ ### New features
7
+ - [35](https://github.com/ebihara99999/code_keeper/pull/35): Support Ruby 3.1.
8
+
9
+ ## 0.5.1 (2021-09-19)
10
+ ### Bug fixes
11
+ - [34](https://github.com/ebihara99999/code_keeper/pull/34): A result of the class_length doesn't show namespaces, and the class_length doesn't count comments of inner classes correctly.
12
+
13
+ ## 0.5.0 (2021-09-16)
14
+ ### Changes
15
+ - [32](https://github.com/ebihara99999/code_keeper/pull/32): Specify dependency versions and loosen the supported ruby version.
16
+
5
17
  ## 0.4.0 (2021-09-15)
6
18
  ### New features
7
19
  - [#30](https://github.com/ebihara99999/code_keeper/pull/30): Support CSV and JSON format.
@@ -11,7 +23,6 @@
11
23
  ### New features
12
24
  - [#26](https://github.com/ebihara99999/code_keeper/pull/26): Support an ABC software metric.
13
25
  - [#27](https://github.com/ebihara99999/code_keeper/pull/27): Support a class length metric.
14
- ### Bug fixes
15
26
 
16
27
  ### Changes
17
28
  - [#25](https://github.com/ebihara99999/code_keeper/pull/25): Remove redundant codes.
data/Gemfile.lock CHANGED
@@ -1,69 +1,57 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- code_keeper (0.1.0)
5
- parallel
6
- rubocop
7
- rubocop-ast
4
+ code_keeper (0.5.1)
5
+ parallel (~> 1.20.1)
6
+ rubocop (>= 1.13.0)
7
+ rubocop-ast (>= 1.4.1)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
12
  ast (2.4.2)
13
- coderay (1.1.3)
14
- diff-lcs (1.4.4)
15
- method_source (0.9.2)
13
+ diff-lcs (1.5.0)
16
14
  parallel (1.20.1)
17
- parser (3.0.1.0)
15
+ parser (3.1.1.0)
18
16
  ast (~> 2.4.1)
19
- pry (0.12.2)
20
- coderay (~> 1.1.0)
21
- method_source (~> 0.9.0)
22
- pry-nav (0.3.0)
23
- pry (>= 0.9.10, < 0.13.0)
24
- rainbow (3.0.0)
25
- rake (13.0.3)
26
- regexp_parser (2.1.1)
17
+ rainbow (3.1.1)
18
+ rake (13.0.6)
19
+ regexp_parser (2.2.1)
27
20
  rexml (3.2.5)
28
- rspec (3.10.0)
29
- rspec-core (~> 3.10.0)
30
- rspec-expectations (~> 3.10.0)
31
- rspec-mocks (~> 3.10.0)
32
- rspec-core (3.10.1)
33
- rspec-support (~> 3.10.0)
34
- rspec-expectations (3.10.1)
21
+ rspec (3.11.0)
22
+ rspec-core (~> 3.11.0)
23
+ rspec-expectations (~> 3.11.0)
24
+ rspec-mocks (~> 3.11.0)
25
+ rspec-core (3.11.0)
26
+ rspec-support (~> 3.11.0)
27
+ rspec-expectations (3.11.0)
35
28
  diff-lcs (>= 1.2.0, < 2.0)
36
- rspec-support (~> 3.10.0)
37
- rspec-mocks (3.10.2)
29
+ rspec-support (~> 3.11.0)
30
+ rspec-mocks (3.11.0)
38
31
  diff-lcs (>= 1.2.0, < 2.0)
39
- rspec-support (~> 3.10.0)
40
- rspec-support (3.10.2)
41
- rubocop (1.13.0)
32
+ rspec-support (~> 3.11.0)
33
+ rspec-support (3.11.0)
34
+ rubocop (1.26.0)
42
35
  parallel (~> 1.10)
43
- parser (>= 3.0.0.0)
36
+ parser (>= 3.1.0.0)
44
37
  rainbow (>= 2.2.2, < 4.0)
45
38
  regexp_parser (>= 1.8, < 3.0)
46
39
  rexml
47
- rubocop-ast (>= 1.2.0, < 2.0)
40
+ rubocop-ast (>= 1.16.0, < 2.0)
48
41
  ruby-progressbar (~> 1.7)
49
42
  unicode-display_width (>= 1.4.0, < 3.0)
50
- rubocop-ast (1.4.1)
51
- parser (>= 2.7.1.5)
43
+ rubocop-ast (1.16.0)
44
+ parser (>= 3.1.1.0)
52
45
  ruby-progressbar (1.11.0)
53
- unicode-display_width (2.0.0)
46
+ unicode-display_width (2.1.0)
54
47
 
55
48
  PLATFORMS
56
49
  x86_64-linux
57
50
 
58
51
  DEPENDENCIES
59
52
  code_keeper!
60
- parallel
61
- pry
62
- pry-nav
63
53
  rake (~> 13.0)
64
54
  rspec (~> 3.0)
65
- rubocop
66
- rubocop-ast
67
55
 
68
56
  BUNDLED WITH
69
- 2.2.3
57
+ 2.3.3
data/code_keeper.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = "The CodeKeeper measures metrics especially about complexity and size of Ruby files, aiming to be a Ruby version of gmetrics."
13
13
  spec.homepage = "https://github.com/ebihara99999/code_keeper"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = "https://github.com/ebihara99999/code_keeper/"
@@ -28,9 +28,9 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ["lib"]
29
29
 
30
30
  # Uncomment to register a new dependency of your gem
31
- spec.add_dependency "parallel"
32
- spec.add_dependency "rubocop"
33
- spec.add_dependency "rubocop-ast"
31
+ spec.add_dependency "parallel", '~> 1.20.1'
32
+ spec.add_dependency "rubocop", '>= 1.13.0'
33
+ spec.add_dependency "rubocop-ast", '>= 1.4.1'
34
34
 
35
35
  # For more information and examples about making a new gem, checkout our
36
36
  # guide at: https://bundler.io/guides/creating_gem.html
@@ -12,14 +12,15 @@ module CodeKeeper
12
12
 
13
13
  # NOTE: This doesn't exclude foldale sources like Array, Hash and Heredoc.
14
14
  def score
15
- @body.each_node(:class, :casgn) do |node|
16
- if node.class_type?
17
- @score_hash.store(node.loc.name.source.to_sym, calculate(node))
15
+ @body.each_node(:class, :casgn, :module) do |node|
16
+ if node.class_type? || node.module_type?
17
+ @score_hash.store(build_namespace(node), calculate(node))
18
18
  elsif node.casgn_type?
19
19
  parent = node.parent
20
20
 
21
21
  if parent&.assignment?
22
22
  block_node = node.children[2]
23
+ klass = node.loc.name.source
23
24
  elsif parent&.parent&.masgn_type?
24
25
  # In the case where `A, B = Struct.new(:a, :b)`,
25
26
  # B is always nil.
@@ -27,8 +28,10 @@ module CodeKeeper
27
28
  next unless node.loc.name.source == assigned
28
29
 
29
30
  block_node = parent.parent.children[1]
31
+ klass = node.loc.name.source
30
32
  else
31
33
  _scope, klass, block_node = *node
34
+ klass = klass.to_s
32
35
  end
33
36
 
34
37
  # This is not to raise error on dynamic assignments like `X = Y = Z = Class.new`.
@@ -37,10 +40,13 @@ module CodeKeeper
37
40
  # Similarly the block node is `:X` as follows if node is Y.
38
41
  next unless block_node.respond_to?(:class_definition?) && block_node.class_definition?
39
42
 
40
- # if the parent is an assignment_type or the parent of the parent is a masgn_type,
41
- klass ||= node.loc.name.source.to_sym
42
-
43
- @score_hash.store(klass, calculate(block_node))
43
+ # NOTE: klass doesn't have a namespace.
44
+ # Only supports namepaces in `class A; end` case.
45
+ if klass
46
+ @score_hash.store(klass, calculate(block_node)) if klass
47
+ else
48
+ @score_hash.store(build_namespace(block_node), calculate(block_node))
49
+ end
44
50
  end
45
51
  end
46
52
  @score_hash
@@ -50,24 +56,67 @@ module CodeKeeper
50
56
 
51
57
  def calculate(node)
52
58
  # node.body.line_count doesn't include comments after definition of a class.
53
- count = node.nonempty_line_count - 2
54
- count - line_count_of_inner_nodes(node) - comment_line_count(node)
59
+ # Don't use nonempty_lines. Empty lines are considered on only the node.
60
+ count = node.line_count - 2
61
+
62
+ count - line_count_of_inner_nodes(node) - comment_line_count(node) - empty_line_count(node)
63
+ end
64
+
65
+ def body_lines(node)
66
+ (node.first_line..node.last_line).to_a - descendant_class_lines(node)
67
+ end
68
+
69
+ def descendant_class_lines(node)
70
+ # A class may have multiple inner classes seperately.
71
+ # So it needs to store all descendant classes line ranges.
72
+ node.each_descendant(:class, :module).map do |desendant|
73
+ # To make easier to compare and consider inner nodes, change array of line range into an array of line numbers.
74
+ (desendant.first_line..desendant.last_line).to_a
75
+ end.flatten.uniq
76
+ end
77
+
78
+ def empty_line_count(node)
79
+ empty_lines = @ps.lines.filter_map.with_index { |line, i| i + 1 if line.empty? }
80
+ (empty_lines & body_lines(node)).size
55
81
  end
56
82
 
57
83
  def line_count_of_inner_nodes(node)
58
- count = 0
59
- node.each_descendant(:class, :module) do |klass_or_module_node|
60
- count += klass_or_module_node.nonempty_line_count
61
- end
62
- count
84
+ line_numbers = node.each_descendant(:class, :module).map do |descendant|
85
+ (descendant.first_line..descendant.last_line).to_a
86
+ end.flatten.uniq
87
+
88
+ line_numbers.size
63
89
  end
64
90
 
91
+ # Only counts the comment of the class or module of a node.
92
+ # Because `#line_count_of_inner_nodes` only considers the first inner node,
93
+ # the second or later inner nodes' commments are not necesarry to be counted.
65
94
  def comment_line_count(node)
66
- count = 0
67
- @ps.comments.each do |comment|
68
- count += 1 if (node.first_line...node.last_line).include? comment.loc.line
95
+ node_range = node.first_line...node.last_line
96
+ comment_lines = @ps.comments.map { |comment| comment.loc.line }
97
+ # The latter condition considers a class ouside or above the node.
98
+ comment_lines.select { |cl| !descendant_class_lines(node).include?(cl) && node_range.include?(cl) }.count
99
+ end
100
+
101
+ def build_namespace(node)
102
+ self_name = name_with_ns(node)
103
+
104
+ return self_name if node.each_ancestor(:class, :module).to_a.empty?
105
+
106
+ full_name = self_name.dup
107
+ node.each_ancestor(:class, :module) do |ancestor|
108
+ full_name = "#{name_with_ns(ancestor)}::#{full_name}"
109
+ end
110
+ full_name
111
+ end
112
+
113
+ def name_with_ns(node)
114
+ ns = node.children.first&.namespace&.source
115
+ if ns.nil?
116
+ node.children.first&.short_name.to_s
117
+ else
118
+ node.children.first.namespace.source + "::#{node.children.first.short_name}"
69
119
  end
70
- count
71
120
  end
72
121
  end
73
122
  end
@@ -7,7 +7,7 @@ module CodeKeeper
7
7
 
8
8
  def initialize(file_path)
9
9
  source = File.read(File.expand_path(file_path))
10
- @processed_source = ::RuboCop::AST::ProcessedSource.new(source, 3.0)
10
+ @processed_source = ::RuboCop::AST::ProcessedSource.new(source, RUBY_VERSION.to_f)
11
11
  rescue Errno::ENOENT
12
12
  raise TargetFileNotFoundError, "The target file does not exist. Check the file path: #{file_path}."
13
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CodeKeeper
4
- VERSION = "0.4.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_keeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Ebihara
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-14 00:00:00.000000000 Z
11
+ date: 2022-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 1.20.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 1.20.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 1.13.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 1.13.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rubocop-ast
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 1.4.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 1.4.1
55
55
  description: The CodeKeeper measures metrics especially about complexity and size
56
56
  of Ruby files, aiming to be a Ruby version of gmetrics.
57
57
  email:
@@ -104,14 +104,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
104
  requirements:
105
105
  - - ">="
106
106
  - !ruby/object:Gem::Version
107
- version: 3.0.0
107
+ version: 2.7.0
108
108
  required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  requirements:
110
110
  - - ">="
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0'
113
113
  requirements: []
114
- rubygems_version: 3.2.3
114
+ rubygems_version: 3.3.3
115
115
  signing_key:
116
116
  specification_version: 4
117
117
  summary: Measures metrics about complexity and size.