code_keeper 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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.