gem_bench 1.0.5 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,46 +3,41 @@ module GemBench
3
3
  GEM_REGEX = /\A\s*gem\s+([^#]*).*\Z/.freeze # run against gem lines like: "gem 'aftership', # Ruby SDK of AfterShip API."
4
4
  GEM_NAME_REGEX = /\A\s*gem\s+['"]{1}(?<name>[^'"]*)['"].*\Z/.freeze # run against gem lines like: "gem 'aftership', # Ruby SDK of AfterShip API."
5
5
  VERSION_CONSTRAINT = /['"]{1}([^'"]*)['"]/.freeze
6
- GEMFILE_HASH_CONFIG_KEY_REGEX_PROC = ->(key) { /\A\s*[^#]*(?<key1>#{key}: *)['"]{1}(?<value1>[^'"]*)['"]|(?<key2>['"]#{key}['"] *=> *)['"]{1}(?<value2>[^'"]*)['"]|(?<key3>:#{key} *=> *)['"]{1}(?<value3>[^'"]*)['"]/ }
7
- VERSION_PATH = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call('path').freeze
8
- VERSION_GIT = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call('git').freeze
9
- VERSION_GITHUB = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call('github').freeze
10
- VERSION_GIT_REF = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call('ref').freeze
11
- VERSION_GIT_TAG = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call('tag').freeze
12
- VERSION_GIT_BRANCH = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call('branch').freeze
13
- VALID_VERSION_TYPES = %i(
6
+ GEMFILE_HASH_CONFIG_KEY_REGEX_PROC = lambda { |key|
7
+ /\A\s*[^#]*(?<key1>#{key}: *)['"]{1}(?<value1>[^'"]*)['"]|(?<key2>['"]#{key}['"] *=> *)['"]{1}(?<value2>[^'"]*)['"]|(?<key3>:#{key} *=> *)['"]{1}(?<value3>[^'"]*)['"]/
8
+ }
9
+ VERSION_PATH = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("path").freeze
10
+ VERSION_GIT = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("git").freeze
11
+ VERSION_GITHUB = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("github").freeze
12
+ VERSION_GIT_REF = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("ref").freeze
13
+ VERSION_GIT_TAG = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("tag").freeze
14
+ VERSION_GIT_BRANCH = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("branch").freeze
15
+ VALID_VERSION_TYPES = %i[
14
16
  constraint
15
17
  git_ref
16
18
  git_tag
17
- )
19
+ ]
18
20
  # branch is only valid if the branch is not master
19
21
  attr_reader :line
20
- attr_reader :relevant_lines
21
- attr_reader :is_gem
22
- attr_reader :all_lines
23
- attr_reader :index
24
- attr_reader :tokens
22
+ attr_reader :relevant_lines, :is_gem, :all_lines, :index, :tokens, :version_type, :name, :parse_success, :valid
25
23
  # version will be a string if it is a normal constraint like '~> 1.2.3'
26
24
  # version will be a hash if it is an alternative constraint like:
27
25
  # git: "blah/blah", ref: "shasha"
28
26
  attr_reader :version
29
- attr_reader :version_type
30
- attr_reader :name
31
- attr_reader :parse_success
32
- attr_reader :valid
27
+
33
28
  def initialize(all_lines, line, index)
34
29
  @line = line.strip
35
30
  @is_gem = self.line.match(GEM_REGEX)
36
- if self.is_gem
31
+ if is_gem
37
32
  @all_lines = all_lines
38
33
  @index = index
39
- @tokens = self.line.split(',')
34
+ @tokens = self.line.split(",")
40
35
  determine_name
41
- if self.name
36
+ if name
42
37
  determine_relevant_lines
43
38
  determine_version
44
39
  @parse_success = true
45
- @valid = VALID_VERSION_TYPES.include?(self.version_type)
40
+ @valid = VALID_VERSION_TYPES.include?(version_type)
46
41
  else
47
42
  noop
48
43
  end
@@ -87,6 +82,7 @@ module GemBench
87
82
  # index 1 of the comma-split tokens will usually be the version constraint, if there is one
88
83
  possible_constraint = @tokens[1]
89
84
  return false unless possible_constraint
85
+
90
86
  match_data = possible_constraint.strip.match(VERSION_CONSTRAINT)
91
87
  # the version constraint is in a regex capture group
92
88
  if match_data && (@version = match_data[1].strip)
@@ -99,92 +95,100 @@ module GemBench
99
95
 
100
96
  def version_path
101
97
  @version = {}
102
- line = relevant_lines.detect { |next_line| (next_line.match(VERSION_PATH)) }
98
+ line = relevant_lines.detect { |next_line| next_line.match(VERSION_PATH) }
103
99
  return false unless line
100
+
104
101
  enhance_version(
105
- line.match(VERSION_PATH),
106
- :path,
107
- :path
102
+ line.match(VERSION_PATH),
103
+ :path,
104
+ :path,
108
105
  )
109
106
  end
110
107
 
111
108
  def version_git
112
109
  @version = {}
113
- line = relevant_lines.detect { |next_line| (next_line.match(VERSION_GIT)) }
110
+ line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT) }
114
111
  return false unless line
112
+
115
113
  enhance_version(
116
- line.match(VERSION_GIT),
117
- :git,
118
- :git
114
+ line.match(VERSION_GIT),
115
+ :git,
116
+ :git,
119
117
  )
120
118
  end
121
119
 
122
120
  def version_github
123
121
  @version = {}
124
- line = relevant_lines.detect { |next_line| (next_line.match(VERSION_GITHUB)) }
122
+ line = relevant_lines.detect { |next_line| next_line.match(VERSION_GITHUB) }
125
123
  return false unless line
124
+
126
125
  enhance_version(
127
- line.match(VERSION_GITHUB),
128
- :github,
129
- :github
126
+ line.match(VERSION_GITHUB),
127
+ :github,
128
+ :github,
130
129
  )
131
130
  end
132
131
 
133
132
  def check_for_version_of_type_git_ref
134
- line = relevant_lines.detect { |next_line| (next_line.match(VERSION_GIT_REF)) }
133
+ line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT_REF) }
135
134
  return false unless line
135
+
136
136
  enhance_version(
137
- line.match(VERSION_GIT_REF),
138
- :ref,
139
- :git_ref
137
+ line.match(VERSION_GIT_REF),
138
+ :ref,
139
+ :git_ref,
140
140
  )
141
141
  end
142
142
 
143
143
  def check_for_version_of_type_git_tag
144
- line = relevant_lines.detect { |next_line| (next_line.match(VERSION_GIT_TAG)) }
144
+ line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT_TAG) }
145
145
  return false unless line
146
+
146
147
  enhance_version(
147
- line.match(VERSION_GIT_TAG),
148
- :tag,
149
- :git_tag
148
+ line.match(VERSION_GIT_TAG),
149
+ :tag,
150
+ :git_tag,
150
151
  )
151
152
  end
152
153
 
153
154
  def check_for_version_of_type_git_branch
154
- line = relevant_lines.detect { |next_line| (next_line.match(VERSION_GIT_BRANCH)) }
155
+ line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT_BRANCH) }
155
156
  return false unless line
157
+
156
158
  enhance_version(
157
- line.match(VERSION_GIT_BRANCH),
158
- :branch,
159
- :git_branch
159
+ line.match(VERSION_GIT_BRANCH),
160
+ :branch,
161
+ :git_branch,
160
162
  )
161
163
  end
162
164
 
163
165
  # returns an array with each line following the current line, which is not a gem line
164
166
  def following_non_gem_lines
165
- all_lines[(index+1)..(-1)].
166
- reject {|x| x.strip.empty? || x.match(GemBench::TRASH_REGEX) }.
167
- map(&:strip).
168
- inject([]) do |following_lines, next_line|
169
- break following_lines if next_line.match(GEM_REGEX)
170
- following_lines << next_line
167
+ all_lines[(index + 1)..-1]
168
+ .reject { |x| x.strip.empty? || x.match(GemBench::TRASH_REGEX) }
169
+ .map(&:strip)
170
+ .inject([]) do |following_lines, next_line|
171
+ break following_lines if next_line.match(GEM_REGEX)
172
+
173
+ following_lines << next_line
171
174
  end
172
175
  end
173
176
 
174
177
  # returns a hash like:
175
178
  # {"key" => ":git => ", "value" => "https://github.com/cte/aftership-sdk-ruby.git"}
176
179
  def normalize_match_data_captures(match_data)
177
- match_data.names.inject({}) do |mem, capture|
178
- mem[capture.gsub(/\d/,'')] = match_data[capture]
180
+ match_data.names.each_with_object({}) do |capture, mem|
181
+ mem[capture.gsub(/\d/, "")] = match_data[capture]
179
182
  break mem if mem.keys.length >= 2
180
- mem
181
183
  end
182
184
  end
183
185
 
184
186
  def enhance_version(match_data, version_key, type)
185
187
  return false unless match_data
188
+
186
189
  normalized_capture = normalize_match_data_captures(match_data) if match_data
187
190
  return false unless normalized_capture
191
+
188
192
  @version.merge!({version_key => normalized_capture["value"]})
189
193
  @version_type = type
190
194
  true
@@ -0,0 +1,150 @@
1
+ # Std Libs Dependencies
2
+ require "tmpdir"
3
+
4
+ # Re-write a gem to a temp directory, re-namespace the primary namespace of that gem module, and load it.
5
+ # If the original gem defines multiple top-level namespaces, they can all be renamed by providing more key value pairs.
6
+ # If the original gem monkey patches other libraries, that behavior can't be isolated, so YMMV.
7
+ #
8
+ # NOTE: Non-top-level namespaces do not need to be renamed, as they are isolated within their parent namespace.
9
+ #
10
+ # Usage
11
+ #
12
+ # jersey = GemBench::Jersey.new(
13
+ # gem_name: "alt_memery"
14
+ # trades: {
15
+ # "Memery" => "AltMemery"
16
+ # },
17
+ # metadata: {
18
+ # something: "a value here",
19
+ # something_else: :obviously,
20
+ # },
21
+ # )
22
+ # jersey.doff_and_don
23
+ # # The re-namespaced constant is now available!
24
+ # AltMemery # => AltMemery
25
+ #
26
+ module GemBench
27
+ class Jersey
28
+ attr_reader :gem_name
29
+ attr_reader :gem_path
30
+ attr_reader :trades
31
+ attr_reader :metadata
32
+ attr_reader :files
33
+ attr_reader :verbose
34
+
35
+ def initialize(gem_name:, trades:, metadata: {}, verbose: false)
36
+ @gem_name = gem_name
37
+ @gem_path = Gem.loaded_specs[gem_name]&.full_gem_path
38
+ @gem_lib_dir = Gem
39
+ @trades = trades
40
+ @metadata = metadata
41
+ @verbose = verbose
42
+ end
43
+
44
+ def required?
45
+ gem_path && trades.values.all? { |new_namespace| Object.const_defined?(new_namespace) }
46
+ end
47
+
48
+ # Generates tempfiles and requires them, resulting
49
+ # in a loaded gem that will not have namespace
50
+ # collisions when alongside the original-namespaced gem.
51
+ # If a block is provided the contents of each file will be yielded to the block,
52
+ # after all namespace substitutions are complete, but before the contents
53
+ # are written to the re-namespaced gem. The return value of the block will be
54
+ # written to the file in this scenario.
55
+ #
56
+ # @return void
57
+ def doff_and_don(&block)
58
+ return puts "Skipping #{gem_name} (not loaded on #{RUBY_VERSION})" unless gem_path
59
+
60
+ puts "Doffing #{gem_path}" if verbose
61
+ Dir.mktmpdir do |directory|
62
+ files = []
63
+ Dir[File.join(gem_path, "lib", "**", "*.rb")].map do |file|
64
+ if verbose
65
+ puts file
66
+ puts File.basename(file)
67
+ puts "--------------------------------"
68
+ end
69
+ dirname = File.dirname(file)
70
+ puts "dirname: #{dirname}" if verbose
71
+ is_at_gem_root = dirname[(-4)..(-1)] == "/lib"
72
+ puts "is_at_gem_root: #{is_at_gem_root}" if verbose
73
+ lib_split = dirname.split("/lib/")[-1]
74
+ puts "lib_split: #{lib_split}" if verbose
75
+ # lib_split could be like:
76
+ # - "ruby/gems/3.2.0/gems/method_source-1.1.0/lib"
77
+ # - "method_source"
78
+ # Se we check to make sure it is actually a subdir of the gem's lib directory
79
+ full_path = File.join(gem_path, "lib", lib_split)
80
+ relative_path = !is_at_gem_root && Dir.exist?(full_path) && lib_split
81
+ puts "relative_path: #{relative_path}" if verbose
82
+ filename = File.basename(file)[0..-4]
83
+ puts "filename: #{filename}" if verbose
84
+
85
+ if relative_path
86
+ dir_path = File.join(directory, relative_path)
87
+ Dir.mkdir(dir_path) unless Dir.exist?(dir_path)
88
+ puts "creating #{filename} in #{dir_path}" if verbose
89
+ files << create_tempfile_copy(file, filename, dir_path, :dd1, &block)
90
+ else
91
+ puts "directory not relative (#{directory}) for file #{filename}" if verbose
92
+ files << create_tempfile_copy(file, filename, directory, :dd2, &block)
93
+ end
94
+ end
95
+ load_gem_copy(files)
96
+ end
97
+
98
+ nil
99
+ end
100
+
101
+ def primary_namespace
102
+ trades.values.first
103
+ end
104
+
105
+ # Will raise NameError if called before #doff_and_don
106
+ def as_klass
107
+ Object.const_get(primary_namespace) if gem_path
108
+ end
109
+
110
+ private
111
+
112
+ def load_gem_copy(files)
113
+ files.each do |filepath|
114
+ # begin
115
+ require filepath
116
+ # rescue LoadError => e
117
+ # puts file.to_s
118
+ # puts tempfile.path
119
+ # puts e.class
120
+ # puts e.message
121
+ # end
122
+ end
123
+ end
124
+
125
+ # @return [String] the file path of the new copy of the original file
126
+ def create_tempfile_copy(file, filename, directory, from, &block)
127
+ # Value of block is returned from File.open
128
+ File.open(File.join(directory, "#{filename}.rb"), "w") do |file_copy|
129
+ new_jersey(file, file_copy, from, &block)
130
+ end
131
+ end
132
+
133
+ # @return [String] the file path of the new copy of the original file
134
+ def new_jersey(file, file_copy, from)
135
+ nj = File.read(file)
136
+ trades.each do |old_namespace, new_namespace|
137
+ nj.gsub!(old_namespace, new_namespace)
138
+ end
139
+ if verbose
140
+ puts "new_jersey has from: #{from}"
141
+ puts "new_jersey has file: #{file}"
142
+ puts "new_jersey file_copy path: #{file_copy.path}"
143
+ end
144
+ nj = yield nj if block_given?
145
+ file_copy.write(nj)
146
+ file_copy.close
147
+ file_copy.path
148
+ end
149
+ end
150
+ end
@@ -21,49 +21,58 @@ module GemBench
21
21
 
22
22
  def set_starter(file_path, line_match: nil)
23
23
  return false if file_path =~ exclude_file_pattern
24
+
24
25
  # Some gems may have zero files to check, as they may be using gem as a
25
26
  # delivery system for shell scripts! As such we need to check which
26
27
  # gems got checked, and which had nothing to check
27
28
  @checked = true
28
29
  line_match ||= GemBench::RAILTIE_REGEX
29
- scan = begin
30
- if GemBench::DO_NOT_SCAN.include?(name)
31
- false
32
- else
33
- begin
34
- File.read(file_path).encode('utf-8', :invalid => :replace, :undef => :replace, :replace => '_') =~ line_match
35
- rescue ArgumentError => e
36
- if e.message =~ /invalid byte sequence/
37
- puts "[GemBench] checking #{file_path} failed due to unparseable file content"
38
- false # Assume the likelihood of files with encoding issues that also contain railtie to be low, so: false.
39
- end
40
- end
41
- end
42
- end
43
- self.stats << [file_path,scan] if scan
44
- self.state = !!scan ?
45
- GemBench::PLAYER_STATES[:starter] :
30
+ scan = !GemBench::DO_NOT_SCAN.include?(name) && check_line(file_path, line_match)
31
+ stats << [file_path, scan] if scan
32
+ self.state = if !!scan
33
+ GemBench::PLAYER_STATES[:starter]
34
+ else
46
35
  GemBench::PLAYER_STATES[:bench]
36
+ end
37
+ end
38
+
39
+ def check_line(file_path, line_match)
40
+ File.read(file_path).encode(
41
+ "utf-8",
42
+ invalid: :replace,
43
+ undef: :replace,
44
+ replace: "_",
45
+ ) =~ line_match
46
+ rescue ArgumentError => e
47
+ if e.message =~ /invalid byte sequence/
48
+ puts "[GemBench] checking #{file_path} failed due to unparseable file content"
49
+ false # Assume the likelihood of files with encoding issues that also contain railtie to be low, so: false.
50
+ else
51
+ puts "[GemBench] checking #{file_path} failed. Please report a bug to https://github.com/pboling/gembench/issues"
52
+ raise e
53
+ end
47
54
  end
48
55
 
49
56
  def starter?
50
- self.state == GemBench::PLAYER_STATES[:starter]
57
+ state == GemBench::PLAYER_STATES[:starter]
51
58
  end
52
59
 
53
60
  def to_s(format = :name)
54
61
  case format
55
- when :name then
56
- name
57
- when :v then
58
- "#{name} v#{version}"
59
- when :semver
60
- "gem '#{name}', '~> #{semver}'"
61
- when :locked
62
- "gem '#{name}', '#{version}'"
63
- when :legacy # when depending on legacy gems, you specifically want to not upgrade, except patches.
64
- "gem '#{name}', '~> #{version}'"
65
- when :upgrade # when upgrading, and testing gem compatibility you want to try anything newer
66
- "gem '#{name}', '>= #{version}'"
62
+ when :name
63
+ name
64
+ when :v
65
+ "#{name} v#{version}"
66
+ when :semver
67
+ "gem '#{name}', '~> #{semver}'"
68
+ when :locked
69
+ "gem '#{name}', '#{version}'"
70
+ when :legacy # when depending on legacy gems, you specifically want to not upgrade, except patches.
71
+ "gem '#{name}', '~> #{version}'"
72
+ when :upgrade # when upgrading, and testing gem compatibility you want to try anything newer
73
+ "gem '#{name}', '>= #{version}'"
74
+ else
75
+ raise ArgumentError, "Unknown format for #{self.class.name}#to_s"
67
76
  end
68
77
  end
69
78
 
@@ -73,17 +82,15 @@ module GemBench
73
82
 
74
83
  def semver
75
84
  ver = version
76
- until ver.split(".").length <= SEMVER_SPLIT_ON_POINT_LENGTH do
77
- ver = ver[0..(ver.rindex(".")-1)]
78
- end
85
+ ver = ver[0..(ver.rindex(".") - 1)] until ver.split(".").length <= SEMVER_SPLIT_ON_POINT_LENGTH
79
86
  ver
80
87
  end
81
88
 
82
89
  def how
83
- case self.state
84
- when GemBench::PLAYER_STATES[:starter] then
90
+ case state
91
+ when GemBench::PLAYER_STATES[:starter]
85
92
  to_s(:semver)
86
- when GemBench::PLAYER_STATES[:bench] then
93
+ when GemBench::PLAYER_STATES[:bench]
87
94
  "#{to_s(:semver)}, require: false"
88
95
  else
89
96
  if checked
@@ -3,13 +3,14 @@
3
3
  module GemBench
4
4
  class Scout
5
5
  attr_reader :gem_paths, :gemfile_path, :gemfile_lines, :gemfile_trash, :loaded_gems
6
+
6
7
  def initialize(check_gemfile: nil)
7
8
  @check_gemfile = check_gemfile.nil? ? true : check_gemfile
8
9
  @gemfile_path = "#{Dir.pwd}/Gemfile"
9
10
  gem_lookup_paths_from_bundler
10
11
  gem_lines_from_gemfile
11
12
  # Gem.loaded_specs are the gems that have been loaded / required.
12
- @loaded_gems = Gem.loaded_specs.values.map {|x| [x.name, x.version.to_s] }
13
+ @loaded_gems = Gem.loaded_specs.values.map { |x| [x.name, x.version.to_s] }
13
14
  end
14
15
 
15
16
  def check_gemfile?
@@ -19,23 +20,21 @@ module GemBench
19
20
  private
20
21
 
21
22
  def gem_lookup_paths_from_bundler
22
- begin
23
- @gem_paths = [Bundler.rubygems.gem_dir, Bundler.rubygems.gem_path].
24
- flatten.
25
- compact.
26
- uniq.
27
- map {|x| x.to_s }.
28
- reject { |p| p.empty? }.
29
- map {|x| "#{x}/gems" }
30
- @gem_paths << "#{Bundler.install_path}"
31
- @gem_paths << "#{Bundler.bundle_path}/gems"
32
- @gem_paths.uniq!
33
- rescue Bundler::GemfileNotFound => e
34
- # Don't fail here, but also don't check the Gemfile.
35
- @check_gemfile = false
36
- ensure
37
- @gem_paths = [] unless @gem_paths.is_a?(Array)
38
- end
23
+ @gem_paths = [Bundler.rubygems.gem_dir, Bundler.rubygems.gem_path]
24
+ .flatten
25
+ .compact
26
+ .uniq
27
+ .map { |x| x.to_s }
28
+ .reject { |p| p.empty? }
29
+ .map { |x| "#{x}/gems" }
30
+ @gem_paths << "#{Bundler.install_path}"
31
+ @gem_paths << "#{Bundler.bundle_path}/gems"
32
+ @gem_paths.uniq!
33
+ rescue Bundler::GemfileNotFound => e
34
+ # Don't fail here, but also don't check the Gemfile.
35
+ @check_gemfile = false
36
+ ensure
37
+ @gem_paths = [] unless @gem_paths.is_a?(Array)
39
38
  end
40
39
 
41
40
  def gem_lines_from_gemfile
@@ -44,8 +43,8 @@ module GemBench
44
43
  # Get all lines as an array
45
44
  all_lines = file.readlines
46
45
  # Remove all the commented || blank lines
47
- @gemfile_trash, @gemfile_lines = all_lines.partition {|x| x =~ GemBench::TRASH_REGEX}
48
- @gemfile_trash.reject! {|x| x == "\n" } # remove blank lines
46
+ @gemfile_trash, @gemfile_lines = all_lines.partition { |x| x =~ GemBench::TRASH_REGEX }
47
+ @gemfile_trash.reject! { |x| x == "\n" } # remove blank lines
49
48
  else
50
49
  @gemfile_trash = []
51
50
  @gemfile_lines = []
@@ -1,25 +1,20 @@
1
1
  module GemBench
2
2
  class StrictVersionGem
3
- attr_reader :name
4
- attr_reader :version
5
- attr_reader :version_type
6
- attr_reader :valid
7
- attr_reader :relevant_lines
8
- attr_reader :index
9
- attr_reader :tokenized_line
3
+ attr_reader :name, :version, :version_type, :valid, :relevant_lines, :index, :tokenized_line
10
4
 
11
5
  class << self
12
6
  def from_line(all_lines, line, index, opts = {})
13
7
  tokenized_line = GemfileLineTokenizer.new(all_lines, line, index)
14
- return nil unless tokenized_line.is_gem
8
+ return unless tokenized_line.is_gem
9
+
15
10
  new(
16
- tokenized_line.name,
17
- tokenized_line.version,
18
- tokenized_line.version_type,
19
- tokenized_line.valid,
20
- tokenized_line.relevant_lines,
21
- tokenized_line.index,
22
- opts[:debug] == true ? tokenized_line : nil
11
+ tokenized_line.name,
12
+ tokenized_line.version,
13
+ tokenized_line.version_type,
14
+ tokenized_line.valid,
15
+ tokenized_line.relevant_lines,
16
+ tokenized_line.index,
17
+ (opts[:debug] == true) ? tokenized_line : nil,
23
18
  )
24
19
  end
25
20
  end
@@ -43,12 +38,12 @@ module GemBench
43
38
  end
44
39
 
45
40
  def to_s
46
- <<-EOS
47
- Gem: #{name}
48
- Line Number: #{index}
49
- Version: #{version.inspect}
50
- Relevant Gemfile Lines:
51
- #{relevant_lines.join("\n")}
41
+ <<~EOS
42
+ Gem: #{name}
43
+ Line Number: #{index}
44
+ Version: #{version.inspect}
45
+ Relevant Gemfile Lines:
46
+ #{relevant_lines.join("\n")}
52
47
  EOS
53
48
  end
54
49
  end
@@ -1,10 +1,6 @@
1
1
  module GemBench
2
2
  class StrictVersionRequirement
3
- attr_reader :gemfile_path
4
- attr_reader :gems
5
- attr_reader :starters
6
- attr_reader :benchers
7
- attr_reader :verbose
3
+ attr_reader :gemfile_path, :gems, :starters, :benchers, :verbose
8
4
 
9
5
  def initialize(options = {})
10
6
  @gemfile_path = "#{Dir.pwd}/Gemfile"
@@ -18,14 +14,14 @@ module GemBench
18
14
  @gems << gem if gem
19
15
  end
20
16
 
21
- @starters, @benchers = @gems.partition {|x| x.valid? }
17
+ @starters, @benchers = @gems.partition { |x| x.valid? }
22
18
  # Remove all the commented || blank lines
23
19
  @verbose = options[:verbose]
24
- self.print if self.verbose
20
+ self.print if verbose
25
21
  end
26
22
 
27
23
  def versions_present?
28
- gems.detect {|x| !x.valid? }.nil?
24
+ gems.detect { |x| !x.valid? }.nil?
29
25
  end
30
26
 
31
27
  def list_missing_version_constraints
@@ -33,34 +29,34 @@ module GemBench
33
29
  end
34
30
 
35
31
  def find(name)
36
- gems.detect {|x| x.name == name }
32
+ gems.detect { |x| x.name == name }
37
33
  end
38
34
 
39
35
  def gem_at(index)
40
- gems.detect {|x| x.index == index }
36
+ gems.detect { |x| x.index == index }
41
37
  end
42
38
 
43
39
  def print
44
- using_path = benchers.count {|x| x.is_type?(:path) }
45
- puts <<-EOS
46
-
47
- The gems that need to be improved are:
48
-
49
- #{benchers.map(&:to_s).join("\n")}
50
-
51
- There are #{starters.length} gems that have valid strict version constraints.
52
- Of those:
53
- #{starters.count {|x| x.is_type?(:constraint) }} use primary constraints (e.g. '~> 1.2.3').
54
- #{starters.count {|x| x.is_type?(:git_ref) }} use git ref constraints.
55
- #{starters.count {|x| x.is_type?(:git_tag) }} use git tag constraints.
56
-
57
- There are #{benchers.length} gems that do not have strict version constraints.
58
- Of those:
59
- #{benchers.count {|x| x.is_type?(:git_branch) }} use git branch constraints.
60
- #{benchers.count {|x| x.is_type?(:git) }} use some other form of git constraint considered not strict enough.
61
- #{benchers.count {|x| x.is_type?(:unknown) }} gems seem to not have any constraint at all.
62
- #{using_path} gems are using a local path. #{'WARNING!!!' if using_path > 0}
63
- EOS
40
+ using_path = benchers.count { |x| x.is_type?(:path) }
41
+ puts <<~EOS
42
+ #{" "}
43
+ The gems that need to be improved are:
44
+
45
+ #{benchers.map(&:to_s).join("\n")}
46
+
47
+ There are #{starters.length} gems that have valid strict version constraints.
48
+ Of those:
49
+ #{starters.count { |x| x.is_type?(:constraint) }} use primary constraints (e.g. '~> 1.2.3').
50
+ #{starters.count { |x| x.is_type?(:git_ref) }} use git ref constraints.
51
+ #{starters.count { |x| x.is_type?(:git_tag) }} use git tag constraints.
52
+
53
+ There are #{benchers.length} gems that do not have strict version constraints.
54
+ Of those:
55
+ #{benchers.count { |x| x.is_type?(:git_branch) }} use git branch constraints.
56
+ #{benchers.count { |x| x.is_type?(:git) }} use some other form of git constraint considered not strict enough.
57
+ #{benchers.count { |x| x.is_type?(:unknown) }} gems seem to not have any constraint at all.
58
+ #{using_path} gems are using a local path. #{"WARNING!!!" if using_path > 0}
59
+ EOS
64
60
  end
65
61
  end
66
62
  end