abc_size 0.1.2 → 0.1.3

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: 293927810a67c15335a07661d8cb27585ee9856b0e95aeb9721e5e38e40c2d2c
4
- data.tar.gz: 9a213a32372bf35afdf159222f192bd03fe46d79c5a8fc9480e1c0d31cd099ad
3
+ metadata.gz: 51190a5338c4af0c9142e1c7a34b038b36f27886423622e2f5ffba95abaa0115
4
+ data.tar.gz: 78085c24057b5c3c768afccbde767d3bfbb9cb00dfbece94317786980664198f
5
5
  SHA512:
6
- metadata.gz: 1cc720a41c800a7a6e7b7f2fbccef9e1b90e325fec341c65084b3eb313e709bfd09914bc99dd66dcd481d7cdd0e29129033ccf2bed0f9104f0ba0a55e070e41f
7
- data.tar.gz: 50d451798ee2b1f86acb242fb99cf347b3aaec1f75578e9603bd9b8ac6532406cad67534496bf669e25c5dbb1b2bec81bfe77833aa01606ca9fbea219401d144
6
+ metadata.gz: 6df3da3944879c32af3dc4a1880306529c3a966792c7ad308ae6c7c0e25598cbcbf0240363bbb3be839651dd7a867ed9e819dd5b4525feeb42bebdcd3d29aa11
7
+ data.tar.gz: 75beb2c8d15c2a700fdf7aabb6acad134e0ba70040cb775227ed32db850b19ba07e44f5d504bc10d0a16e8980170c05d4a54f08b4bbc93c40c42ac29e8fd5870
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.1.3] - 2021-12-24
2
+
3
+ - Processing Ruby code for specified Ruby version.
4
+ - Ruby version detection from `.ruby-version` file at working directory.
5
+ - Ruby version picking with `-r` or `--ruby` option.
6
+
1
7
  ## [0.1.2] - 2021-12-04
2
8
 
3
9
  - Updates README.md
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abc_size (0.1.0)
4
+ abc_size (0.1.3)
5
5
  rainbow (>= 3.0.0)
6
6
  rubocop (>= 1.23.0)
7
7
  rubocop-ast (>= 1.14.0)
data/README.md CHANGED
@@ -37,8 +37,14 @@ abc [file] [options]
37
37
  ```
38
38
  Options:
39
39
  -d, --discount Discount repeated attributes
40
+ -r, --ruby Ruby version
40
41
  ```
41
42
 
43
+ Ruby code can be processed for specified Ruby version.
44
+
45
+ Default behavior is to detect it from `.ruby-version` file at working directory.
46
+ Alternatively it can be picked with `-r` or `--ruby` option.
47
+
42
48
  ## Contributing
43
49
 
44
50
  Bug reports are welcome on GitHub at https://github.com/efurtak/abc_size.
data/exe/abc CHANGED
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env ruby
2
+
2
3
  # frozen_string_literal: true
3
4
 
4
5
  $LOAD_PATH.unshift("#{__dir__}/../lib")
5
6
 
6
7
  require 'abc_size'
7
8
 
8
- path = ARGV[0]
9
- discount = ['-d', '--discount'].include?(ARGV[1])
9
+ path, *parameters = ARGV
10
10
 
11
11
  if path
12
- AbcSize::Calculator.new.call(path: path, discount: discount)
12
+ AbcSize::Calculator.new(path: path, parameters: parameters).call
13
13
  else
14
14
  puts "Usage: abc [file] [options]\n"\
15
15
  "\n"\
16
16
  "Options:\n"\
17
- ' -d, --discount Discount repeated attributes'
17
+ " -d, --discount Discount repeated attributes\n"\
18
+ ' -r, --ruby Ruby version'
18
19
  end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rainbow'
4
+ require 'rubocop'
5
+ require 'rubocop-ast'
6
+
7
+ module AbcSize
8
+ # main class
9
+ class Calculator
10
+ SATISFACTORY_ABC_SIZE = 17
11
+
12
+ attr_reader :source_code, :path, :parameters, :discount, :results, :ruby_version
13
+
14
+ def initialize(source_code: nil, path: nil, parameters: nil)
15
+ @source_code = source_code
16
+ @path = path
17
+ @parameters = parameters
18
+
19
+ @discount = @parameters.map { |parameter| ['-d', '--discount'].include?(parameter) }.any?(true)
20
+
21
+ @results = []
22
+ end
23
+
24
+ def call
25
+ source = source_code || read_source_code_from_file
26
+ @ruby_version = return_ruby_version
27
+
28
+ nodes = RuboCop::AST::ProcessedSource.new(source, ruby_version).ast
29
+ nodes.each_node { |node| results << calculate_result(node) if node.is_a?(RuboCop::AST::DefNode) }
30
+
31
+ print_all_messages
32
+
33
+ # return results for testing purposes
34
+ results
35
+ end
36
+
37
+ private
38
+
39
+ def read_source_code_from_file
40
+ data = File.read(path)
41
+ raise EmptyFileError, 'File is empty!' if data.empty?
42
+
43
+ data
44
+ rescue TypeError, Errno::ENOENT, Errno::EISDIR, EmptyFileError => e
45
+ puts "#{e.message}\n"\
46
+ 'Please provide valid path to valid file.'
47
+ exit
48
+ end
49
+
50
+ def return_ruby_version
51
+ RubyVersion::Picker.new(parameters).call || RubyVersion::Detector.new.call
52
+ end
53
+
54
+ def calculate_result(node)
55
+ abc_size, abc = RuboCop::Cop::Metrics::Utils::AbcSizeCalculator.calculate(
56
+ node,
57
+ discount_repeated_attributes: discount
58
+ )
59
+
60
+ [abc_size, abc, node.method_name]
61
+ end
62
+
63
+ def color(input, satisfactory)
64
+ color = satisfactory ? :yellow : :red
65
+ Rainbow(input).color(color)
66
+ end
67
+
68
+ def print_all_messages
69
+ print_version
70
+ print_results
71
+ print_interpretation
72
+ end
73
+
74
+ def print_version
75
+ puts "Processed for Ruby version: #{color(ruby_version, true)}\n"\
76
+ "\n"
77
+ end
78
+
79
+ def print_results
80
+ results.each do |result|
81
+ abc_size, abc, method_name = result
82
+
83
+ satisfactory = abc_size <= SATISFACTORY_ABC_SIZE
84
+
85
+ puts "ABC size: #{color(format('%.2f', abc_size), satisfactory)}, "\
86
+ "ABC: #{color(abc, satisfactory)} "\
87
+ "for method: #{color(method_name, satisfactory)}"
88
+ end
89
+ end
90
+
91
+ def print_interpretation
92
+ puts "\n"\
93
+ "ABC size: <= 17 satisfactory, 18..30 unsatisfactory, > 30 dangerous\n"\
94
+ 'ABC: <assignments, branches (method calls), conditions>'
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbcSize
4
+ class Error < StandardError; end
5
+
6
+ class EmptyFileError < Error; end
7
+
8
+ class UnknownFormatError < Error; end
9
+
10
+ class UnsupportedVersionError < Error; end
11
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbcSize
4
+ module RubyVersion
5
+ # Ruby version detector
6
+ class Detector
7
+ include Common
8
+
9
+ RUBY_VERSION_FILENAME = '.ruby-version'
10
+
11
+ def call
12
+ file_version = return_file_version
13
+
14
+ return_supported_version_if_version_supported(file_version)
15
+ rescue Errno::ENOENT, EmptyFileError, UnknownFormatError => e
16
+ rescue_detection_error(e)
17
+ end
18
+
19
+ private
20
+
21
+ def return_file_version
22
+ data = return_data
23
+
24
+ match_data = return_match_data(data)
25
+
26
+ match_data[0].to_f
27
+ end
28
+
29
+ def return_data
30
+ path = "#{Dir.pwd}/#{RUBY_VERSION_FILENAME}"
31
+
32
+ data = File.read(path)
33
+ raise EmptyFileError if data.empty?
34
+
35
+ data
36
+ end
37
+
38
+ def return_match_data(data)
39
+ match_data = data.match(/\A\d+\.\d+/)
40
+ raise UnknownFormatError if match_data.nil?
41
+
42
+ match_data
43
+ end
44
+
45
+ def rescue_detection_error(error)
46
+ case error
47
+ when Errno::ENOENT
48
+ puts 'Not detected `.ruby-version` file!'
49
+ when EmptyFileError
50
+ puts 'Detected `.ruby-version` file, but file is empty!'
51
+ when UnknownFormatError
52
+ puts 'Detected `.ruby-version` file, but file contain unknown format!'
53
+ end
54
+ exit
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbcSize
4
+ module RubyVersion
5
+ # Ruby version picker
6
+ class Picker
7
+ include Common
8
+
9
+ attr_reader :parameters, :parameter_index
10
+
11
+ def initialize(parameters)
12
+ @parameters = parameters
13
+ @parameter_index = @parameters.index('-r') || @parameters.index('--ruby')
14
+ end
15
+
16
+ def call
17
+ return if parameter_index.nil?
18
+
19
+ value_index = parameter_index + 1
20
+
21
+ parameters_version = parameters[value_index].to_f
22
+
23
+ return_supported_version_if_version_supported(parameters_version)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbcSize
4
+ module RubyVersion
5
+ SUPPORTED_VERSIONS = RuboCop::TargetRuby.supported_versions.freeze
6
+
7
+ # common methods
8
+ module Common
9
+ def return_supported_version_if_version_supported(version)
10
+ supported_version = RubyVersion::SUPPORTED_VERSIONS.include?(version) ? version : nil
11
+ raise UnsupportedVersionError, 'Unsupported Ruby version given.' if supported_version.nil?
12
+
13
+ supported_version
14
+ rescue UnsupportedVersionError => e
15
+ puts "#{e.message}\n"\
16
+ "Supported versions: #{RubyVersion::SUPPORTED_VERSIONS}"
17
+ exit
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbcSize
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.3'
5
5
  end
data/lib/abc_size.rb CHANGED
@@ -1,83 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'abc_size/calculator'
4
+ require_relative 'abc_size/errors'
5
+ require_relative 'abc_size/ruby_version'
6
+ require_relative 'abc_size/ruby_version/detector'
7
+ require_relative 'abc_size/ruby_version/picker'
3
8
  require_relative 'abc_size/version'
4
-
5
- require 'rainbow'
6
- require 'rubocop'
7
- require 'rubocop-ast'
8
-
9
- module AbcSize
10
- class Error < StandardError; end
11
-
12
- # class responsible for returning ABC size from ABC size calculator
13
- class Calculator
14
- SATISFACTORY_ABC_SIZE = 17
15
-
16
- attr_reader :results
17
-
18
- def initialize
19
- @results = []
20
- end
21
-
22
- def call(source_code: nil, path: nil, discount: false)
23
- source = source_code || source_code_from_file(path)
24
- ruby_version = RuboCop::TargetRuby.supported_versions.last
25
-
26
- nodes = RuboCop::AST::ProcessedSource.new(source, ruby_version).ast
27
-
28
- nodes.each_node { |node| results << calculate_result(node, discount) if node.is_a?(RuboCop::AST::DefNode) }
29
-
30
- print_results
31
-
32
- print_interpretation
33
-
34
- # return results for testing purposes
35
- results
36
- end
37
-
38
- private
39
-
40
- def source_code_from_file(path)
41
- data = File.open(path, 'r').read
42
- raise Error, 'File is empty!' if data.empty?
43
-
44
- data
45
- rescue TypeError, Errno::ENOENT, Errno::EISDIR, Error => e
46
- puts "#{e.message}\n"\
47
- 'Please provide valid path to valid file.'
48
- exit
49
- end
50
-
51
- def calculate_result(node, discount)
52
- abc_size, abc = RuboCop::Cop::Metrics::Utils::AbcSizeCalculator.calculate(
53
- node,
54
- discount_repeated_attributes: discount
55
- )
56
-
57
- [abc_size, abc, node.method_name]
58
- end
59
-
60
- def print_results
61
- results.each do |result|
62
- abc_size, abc, method_name = result
63
-
64
- satisfactory = abc_size <= SATISFACTORY_ABC_SIZE
65
-
66
- puts "ABC size: #{color(format('%.2f', abc_size), satisfactory)}, "\
67
- "ABC: #{color(abc, satisfactory)} "\
68
- "for method: #{color(method_name, satisfactory)}"
69
- end
70
- end
71
-
72
- def color(input, satisfactory)
73
- color = satisfactory ? :yellow : :red
74
- Rainbow(input).color(color)
75
- end
76
-
77
- def print_interpretation
78
- puts "\n"\
79
- "ABC size: <= 17 satisfactory, 18..30 unsatisfactory, > 30 dangerous\n"\
80
- 'ABC: <assignments, branches (method calls), conditions>'
81
- end
82
- end
83
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abc_size
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Furtak
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-04 00:00:00.000000000 Z
11
+ date: 2021-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -72,6 +72,11 @@ files:
72
72
  - bin/setup
73
73
  - exe/abc
74
74
  - lib/abc_size.rb
75
+ - lib/abc_size/calculator.rb
76
+ - lib/abc_size/errors.rb
77
+ - lib/abc_size/ruby_version.rb
78
+ - lib/abc_size/ruby_version/detector.rb
79
+ - lib/abc_size/ruby_version/picker.rb
75
80
  - lib/abc_size/version.rb
76
81
  homepage: https://github.com/efurtak/abc_size
77
82
  licenses: