code_keeper 0.1.0 → 0.5.1

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: da70c28c42b1b848e40adb6145d25686ed8e8bea4dbf25adeb49bebbb82555a8
4
- data.tar.gz: dcf7b9aebd57660ded6869224c87769d836c8518a19b46c74a8d1c86edd1e9b4
3
+ metadata.gz: f1032e75ff8322d23a622e6bac5a04039939999032d5559e9ff54d46f04ccd16
4
+ data.tar.gz: 51e78032de7754ea37aacd6ea422d46e4c66cc94c5c5d10a2baf963cee475ee1
5
5
  SHA512:
6
- metadata.gz: e6dcab3c8280feb01e837e87025d5d71f6913f74b64c5afa22c36e126e8d69f8321c4445653088fc8fa82a4ee5c4bf2dffef825f92e6c5e5fbf4177a9ce725fd
7
- data.tar.gz: 6d40b0fe93e685cbe3d982dd467dc843138686bdf08a95964b90da4187587fb9e4a3ffcab454dbc1b90ad086e9df6bf56d96cb2152dabf72450bc203790bde42
6
+ metadata.gz: eedf3bcecbd0ad563300548c9b1ac9b7d2ddec52550b459754fa1556e052940ad36ce7c5fd9afdb6df0768ea5ce9dd04680d3cae6a68112d106cb4ddf6611073
7
+ data.tar.gz: c527a3f3a175535b53512f8291276b34edf6cf8b3afe267a093603a14b59c4bedb867af0383dd137b6b78992d7b9194dfd133535f811f2654a1077d61409c8ee
@@ -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]
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
 
@@ -44,3 +43,19 @@ Style/Documentation:
44
43
 
45
44
  Metrics/AbcSize:
46
45
  Max: 25
46
+ Exclude:
47
+ # It's hard to control.
48
+ - lib/code_keeper/metrics/class_length.rb
49
+
50
+ Metrics/CyclomaticComplexity:
51
+ Exclude:
52
+ # It's hard to control.
53
+ - lib/code_keeper/metrics/class_length.rb
54
+
55
+ Metrics/PerceivedComplexity:
56
+ Exclude:
57
+ # It's hard to control.
58
+ - lib/code_keeper/metrics/class_length.rb
59
+
60
+ Metrics/MethodLength:
61
+ Max: 40
data/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ # Change log
2
+
3
+ ## Unrelease
4
+
5
+ ## 0.5.1 (2021-09-19)
6
+ ### Bug fixes
7
+ - [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.
8
+
9
+ ## 0.5.0 (2021-09-16)
10
+ ### Changes
11
+ - [32](https://github.com/ebihara99999/code_keeper/pull/32): Specify dependency versions and loosen the supported ruby version.
12
+
13
+ ## 0.4.0 (2021-09-15)
14
+ ### New features
15
+ - [#30](https://github.com/ebihara99999/code_keeper/pull/30): Support CSV and JSON format.
16
+
17
+ ## 0.3.0 (2021-09-15)
18
+
19
+ ### New features
20
+ - [#26](https://github.com/ebihara99999/code_keeper/pull/26): Support an ABC software metric.
21
+ - [#27](https://github.com/ebihara99999/code_keeper/pull/27): Support a class length metric.
22
+
23
+ ### Changes
24
+ - [#25](https://github.com/ebihara99999/code_keeper/pull/25): Remove redundant codes.
data/README.md CHANGED
@@ -3,7 +3,7 @@ The CodeKeeper measures metrics especially about complexity and size of Ruby fil
3
3
 
4
4
  Mesuring metrics leads to keep codebase simple and clean, and I name the gem CodeKeeper.
5
5
 
6
- Now CodeKeeper supports the cyclomatic complexity. The scores are output to stdout.
6
+ Now CodeKeeper supports the cyclomatic complexity of a file, the ABC software metric of a file, and class length. The scores are output to stdout of a json or csv format.
7
7
 
8
8
  ## Installation
9
9
 
@@ -25,18 +25,11 @@ Or install it yourself as:
25
25
  Run CodeKeeper and you get scores of metrics from stdout like
26
26
 
27
27
  ```rb
28
- $ bundle exec code_keeper ./app/models
29
- Scores:
30
-
31
- Metric: cyclomatic_complexity
32
- Filename: app/models/admin.rb
33
- Score: 1
34
- ---
35
- Metric: cyclomatic_complexity
36
- Filename: app/models/user.rb
37
- Score: 23
38
- ---
28
+ $ bundle exec code_keeper app/models/user.rb app/models/admin.rb > metrics.json
29
+ $ cat metrics.json
30
+ {"cyclomatic_complexity":{"app/models/admin.rb":9,"app/models/user.rb":23},"class_length":{"Admin":86,"User":1475},"abc_metric":{"app/models/admin.rb":76.909,"app/models/user.rb":1546.4155}}
39
31
  ```
32
+ If you need a csv format, change the configuration as explained later.
40
33
 
41
34
  ### Run CodeKeeper
42
35
  To measure metrics of all the ruby files recursively in the current directory, run
@@ -55,9 +48,11 @@ CodeKeeper makes you configure the following way:
55
48
  ```rb
56
49
  CodeKeeper.configure do |config|
57
50
  # If you choose metrics, specify as follows:
58
- config.metrics = [:cyclomatic_complexity]
51
+ config.metrics = %i(cyclomatic_complexity abc_metric class_length)
59
52
  # The number of threads. The default is 2. Executed sequentially if you set 1.
60
53
  config.number_of_threads = 4
54
+ # The default is json
55
+ config.format = :json
61
56
  end
62
57
  ```
63
58
 
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
@@ -3,11 +3,12 @@
3
3
  module CodeKeeper
4
4
  # Provide configuration
5
5
  class Config
6
- attr_accessor :metrics, :number_of_threads
6
+ attr_accessor :metrics, :number_of_threads, :format
7
7
 
8
8
  def initialize
9
- @metrics = [:cyclomatic_complexity]
9
+ @metrics = %i[cyclomatic_complexity class_length abc_metric]
10
10
  @number_of_threads = 2
11
+ @format = :json # json and csv are supported.
11
12
  end
12
13
  end
13
14
  end
@@ -16,13 +16,7 @@ module CodeKeeper
16
16
  private
17
17
 
18
18
  def search_recursively(file_or_dir_paths)
19
- checked = {}
20
-
21
19
  file_or_dir_paths.each do |edge|
22
- next if checked[:"#{edge}"]
23
-
24
- checked[:"#{edge}"] = true
25
-
26
20
  if FileTest.file?(edge)
27
21
  file_or_dir_paths << edge unless file_or_dir_paths.include?(edge)
28
22
  else
@@ -1,26 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'csv'
4
+
3
5
  module CodeKeeper
4
6
  # Format a result and make it human-readable.
5
7
  class Formatter
6
8
  class << self
7
9
  def format(result)
8
- title = "Scores:\n\n"
9
- formatted_result = +title
10
+ return result.scores.to_json if CodeKeeper.config.format == :json
10
11
 
12
+ # csv is supported besides json
13
+ csv_array = []
11
14
  result.scores.each_key do |metric|
12
- result.scores[metric].each do |k, v|
13
- formatted_result.concat(
14
- <<~EOS
15
- Metric: #{metric}
16
- Filename: #{k}
17
- Score: #{v}
18
- ---
19
- EOS
20
- )
21
- end
15
+ result.scores[metric].each { |k, v| csv_array << [metric, k, v] }
16
+ end
17
+
18
+ headers = %w[metric file score]
19
+ CSV.generate(headers: true) do |csv|
20
+ csv << headers
21
+ csv_array.each { |array| csv << array }
22
22
  end
23
- formatted_result
24
23
  end
25
24
  end
26
25
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CodeKeeper
4
+ module Metrics
5
+ # Caluculate cyclomatic complexity
6
+ class AbcMetric
7
+ include ::RuboCop::Cop::Metrics::Utils::IteratingBlock
8
+ include ::RuboCop::Cop::Metrics::Utils::RepeatedCsendDiscount
9
+
10
+ def initialize(file_path)
11
+ ps = Parser.parse(file_path)
12
+ @path = file_path
13
+ @body = ps.ast
14
+ @assignments = 0
15
+ @branches = 0
16
+ @conditionals = 0
17
+ end
18
+
19
+ def score
20
+ caluculator = ::RuboCop::Cop::Metrics::Utils::AbcSizeCalculator.new(@body)
21
+ caluculator.calculate
22
+ @assignments = caluculator.instance_variable_get('@assignment')
23
+ @conditionals = caluculator.instance_variable_get('@condition')
24
+ @branches = caluculator.instance_variable_get('@branch')
25
+
26
+ value = Math.sqrt(@assignments**2 + @branches**2 + @conditionals**2).round(4)
27
+ { "#{@path}": value }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CodeKeeper
4
+ module Metrics
5
+ # Caluculate Class Length.
6
+ class ClassLength
7
+ def initialize(file_path)
8
+ @ps = Parser.parse(file_path)
9
+ @body = @ps.ast
10
+ @score_hash = {}
11
+ end
12
+
13
+ # NOTE: This doesn't exclude foldale sources like Array, Hash and Heredoc.
14
+ def score
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
+ elsif node.casgn_type?
19
+ parent = node.parent
20
+
21
+ if parent&.assignment?
22
+ block_node = node.children[2]
23
+ klass = node.loc.name.source
24
+ elsif parent&.parent&.masgn_type?
25
+ # In the case where `A, B = Struct.new(:a, :b)`,
26
+ # B is always nil.
27
+ assigned = parent.loc.expression.source.split(',').first
28
+ next unless node.loc.name.source == assigned
29
+
30
+ block_node = parent.parent.children[1]
31
+ klass = node.loc.name.source
32
+ else
33
+ _scope, klass, block_node = *node
34
+ klass = klass.to_s
35
+ end
36
+
37
+ # This is not to raise error on dynamic assignments like `X = Y = Z = Class.new`.
38
+ # the block node is as follows if node is X:
39
+ # `s(:casgn, nil, :Y, s(:casgn, nil, :Z, s(:block, ...`
40
+ # Similarly the block node is `:X` as follows if node is Y.
41
+ next unless block_node.respond_to?(:class_definition?) && block_node.class_definition?
42
+
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
50
+ end
51
+ end
52
+ @score_hash
53
+ end
54
+
55
+ private
56
+
57
+ def calculate(node)
58
+ # node.body.line_count doesn't include comments after definition of a class.
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
81
+ end
82
+
83
+ def line_count_of_inner_nodes(node)
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
89
+ end
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.
94
+ def comment_line_count(node)
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}"
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -10,18 +10,20 @@ module CodeKeeper
10
10
  CONSIDERED_NODES = %i[if while until for csend block block_pass rescue when and or or_asgnand_asgn].freeze
11
11
 
12
12
  def initialize(file_path)
13
- ps = Parser.parse(file_path)
13
+ @path = file_path
14
+ ps = Parser.parse(@path)
14
15
  @body = ps.ast
15
16
  end
16
17
 
17
18
  # returns score of cyclomatic complexity
18
19
  def score
19
- @body.each_node(:lvasgn, *CONSIDERED_NODES).reduce(1) do |score, node|
20
+ final_score = @body.each_node(:lvasgn, *CONSIDERED_NODES).reduce(1) do |score, node|
20
21
  next score if !iterating_block?(node) || node.lvasgn_type?
21
22
  next score if node.csend_type? && discount_for_repeated_csend?(node)
22
23
 
23
24
  next 1 + score
24
25
  end
26
+ { "#{@path}": final_score }
25
27
  end
26
28
  end
27
29
  end
@@ -1,10 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'code_keeper/metrics/abc_metric'
3
4
  require 'code_keeper/metrics/cyclomatic_complexity'
5
+ require 'code_keeper/metrics/class_length'
4
6
 
5
7
  module CodeKeeper
6
8
  # Manage config values of metrics and the correspond classes
7
9
  module Metrics
8
- MAPPINGS = { cyclomatic_complexity: CodeKeeper::Metrics::CyclomaticComplexity }.freeze
10
+ MAPPINGS = {
11
+ abc_metric: CodeKeeper::Metrics::AbcMetric,
12
+ cyclomatic_complexity: CodeKeeper::Metrics::CyclomaticComplexity,
13
+ class_length: CodeKeeper::Metrics::ClassLength
14
+ }.freeze
9
15
  end
10
16
  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
@@ -9,8 +9,8 @@ module CodeKeeper
9
9
  @scores = CodeKeeper.config.metrics.map { |key| [key, {}] }.to_h
10
10
  end
11
11
 
12
- def add(metric, path, score)
13
- scores[:"#{metric}"].store(path, score)
12
+ def add(metric, klass_or_path, score)
13
+ scores[:"#{metric}"].store(klass_or_path, score)
14
14
  end
15
15
  end
16
16
  end
@@ -14,20 +14,27 @@ module CodeKeeper
14
14
  # `in_threads: 1` makes 2 threads, a sleep_forever thread and the main thread.
15
15
  if num_threads == 1
16
16
  ruby_file_paths.each do |path|
17
- metrics.each do |metric|
18
- result.add(:cyclomatic_complexity, path, ::CodeKeeper::Metrics::MAPPINGS[metric].new(path).score)
19
- end
17
+ metrics.each { |metric| calculate_score(metric, path, result) }
20
18
  end
21
19
  else
22
20
  Parallel.map(ruby_file_paths, in_threads: num_threads) do |path|
23
- metrics.each do |metric|
24
- result.add(:cyclomatic_complexity, path, ::CodeKeeper::Metrics::MAPPINGS[metric].new(path).score)
25
- end
21
+ metrics.each { |metric| calculate_score(metric, path, result) }
26
22
  end
27
23
  end
28
24
 
29
25
  result
30
26
  end
27
+
28
+ private
29
+
30
+ def calculate_score(metric, path, result)
31
+ score = ::CodeKeeper::Metrics::MAPPINGS[metric].new(path).score
32
+
33
+ # The class length metric's score has multiple classes.
34
+ score.each do |k, v|
35
+ result.add(metric, k.to_s, v)
36
+ end
37
+ end
31
38
  end
32
39
  end
33
40
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CodeKeeper
4
- VERSION = "0.1.0"
4
+ VERSION = "0.5.1"
5
5
  end
data/lib/code_keeper.rb CHANGED
@@ -10,7 +10,9 @@ require 'code_keeper/config'
10
10
  require 'code_keeper/scorer'
11
11
  require 'code_keeper/result'
12
12
  require 'code_keeper/metrics'
13
+ require 'code_keeper/metrics/abc_metric'
13
14
  require 'code_keeper/metrics/cyclomatic_complexity'
15
+ require 'code_keeper/metrics/class_length'
14
16
 
15
17
  module CodeKeeper
16
18
  class << self
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.1.0
4
+ version: 0.5.1
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-08-18 00:00:00.000000000 Z
11
+ date: 2021-09-19 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:
@@ -65,9 +65,9 @@ files:
65
65
  - ".gitignore"
66
66
  - ".rspec"
67
67
  - ".rubocop.yml"
68
+ - CHANGELOG.md
68
69
  - CODE_OF_CONDUCT.md
69
70
  - Gemfile
70
- - Gemfile.lock
71
71
  - LICENSE.txt
72
72
  - README.md
73
73
  - Rakefile
@@ -81,6 +81,8 @@ files:
81
81
  - lib/code_keeper/finder.rb
82
82
  - lib/code_keeper/formatter.rb
83
83
  - lib/code_keeper/metrics.rb
84
+ - lib/code_keeper/metrics/abc_metric.rb
85
+ - lib/code_keeper/metrics/class_length.rb
84
86
  - lib/code_keeper/metrics/cyclomatic_complexity.rb
85
87
  - lib/code_keeper/parser.rb
86
88
  - lib/code_keeper/result.rb
@@ -101,7 +103,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
103
  requirements:
102
104
  - - ">="
103
105
  - !ruby/object:Gem::Version
104
- version: 3.0.0
106
+ version: 2.7.0
105
107
  required_rubygems_version: !ruby/object:Gem::Requirement
106
108
  requirements:
107
109
  - - ">="
data/Gemfile.lock DELETED
@@ -1,69 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- code_keeper (0.1.0)
5
- parallel
6
- rubocop
7
- rubocop-ast
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- ast (2.4.2)
13
- coderay (1.1.3)
14
- diff-lcs (1.4.4)
15
- method_source (0.9.2)
16
- parallel (1.20.1)
17
- parser (3.0.1.0)
18
- 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)
27
- 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)
35
- diff-lcs (>= 1.2.0, < 2.0)
36
- rspec-support (~> 3.10.0)
37
- rspec-mocks (3.10.2)
38
- diff-lcs (>= 1.2.0, < 2.0)
39
- rspec-support (~> 3.10.0)
40
- rspec-support (3.10.2)
41
- rubocop (1.13.0)
42
- parallel (~> 1.10)
43
- parser (>= 3.0.0.0)
44
- rainbow (>= 2.2.2, < 4.0)
45
- regexp_parser (>= 1.8, < 3.0)
46
- rexml
47
- rubocop-ast (>= 1.2.0, < 2.0)
48
- ruby-progressbar (~> 1.7)
49
- unicode-display_width (>= 1.4.0, < 3.0)
50
- rubocop-ast (1.4.1)
51
- parser (>= 2.7.1.5)
52
- ruby-progressbar (1.11.0)
53
- unicode-display_width (2.0.0)
54
-
55
- PLATFORMS
56
- x86_64-linux
57
-
58
- DEPENDENCIES
59
- code_keeper!
60
- parallel
61
- pry
62
- pry-nav
63
- rake (~> 13.0)
64
- rspec (~> 3.0)
65
- rubocop
66
- rubocop-ast
67
-
68
- BUNDLED WITH
69
- 2.2.3