rubygems-update 2.4.5 → 2.4.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/History.txt +27 -0
  3. data/Manifest.txt +4 -0
  4. data/lib/rubygems.rb +2 -2
  5. data/lib/rubygems/basic_specification.rb +2 -3
  6. data/lib/rubygems/commands/help_command.rb +2 -2
  7. data/lib/rubygems/commands/open_command.rb +3 -1
  8. data/lib/rubygems/commands/yank_command.rb +1 -1
  9. data/lib/rubygems/compatibility.rb +1 -2
  10. data/lib/rubygems/dependency_installer.rb +11 -1
  11. data/lib/rubygems/installer.rb +1 -1
  12. data/lib/rubygems/package.rb +2 -1
  13. data/lib/rubygems/package/tar_writer.rb +4 -4
  14. data/lib/rubygems/path_support.rb +0 -7
  15. data/lib/rubygems/psych_additions.rb +1 -1
  16. data/lib/rubygems/remote_fetcher.rb +1 -1
  17. data/lib/rubygems/request_set.rb +10 -4
  18. data/lib/rubygems/request_set/gem_dependency_api.rb +4 -4
  19. data/lib/rubygems/request_set/lockfile.rb +52 -464
  20. data/lib/rubygems/request_set/lockfile/parser.rb +334 -0
  21. data/lib/rubygems/request_set/lockfile/tokenizer.rb +108 -0
  22. data/lib/rubygems/requirement.rb +12 -1
  23. data/lib/rubygems/security/signer.rb +1 -1
  24. data/lib/rubygems/specification.rb +12 -12
  25. data/lib/rubygems/test_case.rb +18 -1
  26. data/lib/rubygems/user_interaction.rb +0 -8
  27. data/test/rubygems/test_gem.rb +2 -5
  28. data/test/rubygems/test_gem_commands_open_command.rb +9 -3
  29. data/test/rubygems/test_gem_commands_pristine_command.rb +2 -2
  30. data/test/rubygems/test_gem_commands_unpack_command.rb +2 -2
  31. data/test/rubygems/test_gem_dependency_installer.rb +27 -1
  32. data/test/rubygems/test_gem_ext_cmake_builder.rb +1 -1
  33. data/test/rubygems/test_gem_installer.rb +1 -1
  34. data/test/rubygems/test_gem_package.rb +1 -1
  35. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +30 -11
  36. data/test/rubygems/test_gem_request_set_lockfile.rb +19 -824
  37. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +543 -0
  38. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +305 -0
  39. data/test/rubygems/test_gem_requirement.rb +10 -0
  40. data/test/rubygems/test_gem_specification.rb +7 -1
  41. data/test/rubygems/test_gem_stub_specification.rb +1 -1
  42. data/test/rubygems/test_gem_uninstaller.rb +2 -2
  43. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc0bb2181c07efffa060674fa83f662444173e18
4
- data.tar.gz: 4435d084f527dd663d15ecdba564b8ebe43792a4
3
+ metadata.gz: 0859dfcdadf9be0170afcca83b23b0234426ef27
4
+ data.tar.gz: af835223a2d14abe818b559c1bcb76642dd19259
5
5
  SHA512:
6
- metadata.gz: 0deecdcea9efcdc0e64ec35651c22b0019df5cf41bdd6a8667392d4e36648117ed512d624b44e4f7d3b388c74a494f0ec5d3f845563b8c67c8fc5ec5b252edac
7
- data.tar.gz: e880b4f113c6a6549527c7754307fcf47d501cf7c6876a56ec3ef0cff4a2ade0b47bae7c445edc169778c526af5952ef31bf35606f89fb8e8ac1826b5ce466cf
6
+ metadata.gz: 07313e5435e5a114cdfbcd097bfb0c94ee5f757232c7101407eb1e40628342fa00d54a38f90491101304bfe2a403f57f8f421ca0375fb8e5c43115f291c3ca83
7
+ data.tar.gz: 8a13fa1ff299fd1107aaa79150e7c1fab6a6e9ed686ebd4072dc0694556b59898bc2b5d659454f09623a7047d97c7a64a6c3143ffc42ac68098a4b1f70653669
@@ -1,5 +1,32 @@
1
1
  # coding: UTF-8
2
2
 
3
+ === 2.4.6 / 2014-02-05
4
+
5
+ Bug fixes:
6
+
7
+ * Fixed resolving gems with both upper and lower requirement boundaries.
8
+ Issue #1141 by Jakub Jirutka.
9
+ * Moved extension directory after require_paths to fix missing constant bugs
10
+ in some gems with C extensions. Issue #784 by André Arko, pull request
11
+ #1137 by Barry Allard.
12
+ * Use Gem::Dependency#requirement when adding a dependency to an existing
13
+ dependency instance. Pull request #1101 by Josh Cheek.
14
+ * Fixed warning of shadowed local variable in Gem::Specification. Pull request
15
+ #1109 by Rohit Arondekar
16
+ * Gem::Requirement should always sort requirements before coercion to Hash.
17
+ Pull request #1139 by Eito Katagiri.
18
+ * The `gem open` command should change the current working directory before
19
+ opening the editor. Pull request #1142 by Alex Wood.
20
+ * Ensure quotes are stripped from the Windows launcher script used to install
21
+ gems. Pull request #1115 by Youngjun Song.
22
+ * Fixed errors when writing to NFS to to 0444 files. Issue #1161 by Emmanuel
23
+ Hadoux.
24
+ * Removed dead code in Gem::StreamUI. Pull request #1117 by mediaslave24.
25
+ * Fixed typos. Pull request #1096 by hakeda.
26
+ * Relaxed CMake dependency for RHEL 6 and CentOS 6. Pull request #1124 by Vít
27
+ Ondruch.
28
+ * Relaxed Psych dependency. Pull request #1128 by Vít Ondruch.
29
+
3
30
  === 2.4.5 / 2014-12-03
4
31
 
5
32
  Bug fixes:
@@ -107,6 +107,8 @@ lib/rubygems/request/https_pool.rb
107
107
  lib/rubygems/request_set.rb
108
108
  lib/rubygems/request_set/gem_dependency_api.rb
109
109
  lib/rubygems/request_set/lockfile.rb
110
+ lib/rubygems/request_set/lockfile/parser.rb
111
+ lib/rubygems/request_set/lockfile/tokenizer.rb
110
112
  lib/rubygems/requirement.rb
111
113
  lib/rubygems/resolver.rb
112
114
  lib/rubygems/resolver/activation_request.rb
@@ -295,6 +297,8 @@ test/rubygems/test_gem_request_connection_pools.rb
295
297
  test/rubygems/test_gem_request_set.rb
296
298
  test/rubygems/test_gem_request_set_gem_dependency_api.rb
297
299
  test/rubygems/test_gem_request_set_lockfile.rb
300
+ test/rubygems/test_gem_request_set_lockfile_parser.rb
301
+ test/rubygems/test_gem_request_set_lockfile_tokenizer.rb
298
302
  test/rubygems/test_gem_requirement.rb
299
303
  test/rubygems/test_gem_resolver.rb
300
304
  test/rubygems/test_gem_resolver_activation_request.rb
@@ -9,7 +9,7 @@ require 'rbconfig'
9
9
  require 'thread'
10
10
 
11
11
  module Gem
12
- VERSION = '2.4.5'
12
+ VERSION = '2.4.6'
13
13
  end
14
14
 
15
15
  # Must be first since it unloads the prelude from 1.9.2
@@ -598,7 +598,7 @@ module Gem
598
598
 
599
599
  unless test_syck
600
600
  begin
601
- gem 'psych', '~> 1.2', '>= 1.2.1'
601
+ gem 'psych', '>= 1.2.1'
602
602
  rescue Gem::LoadError
603
603
  # It's OK if the user does not have the psych gem installed. We will
604
604
  # attempt to require the stdlib version
@@ -61,8 +61,7 @@ class Gem::BasicSpecification
61
61
  @contains_requirable_file ||= {}
62
62
  @contains_requirable_file[file] ||=
63
63
  begin
64
- if instance_variable_defined?(:@ignored) or
65
- instance_variable_defined?('@ignored') then
64
+ if instance_variable_defined?(:@ignored) then
66
65
  return false
67
66
  elsif missing_extensions? then
68
67
  @ignored = true
@@ -145,7 +144,7 @@ class Gem::BasicSpecification
145
144
  File.join full_gem_path, path
146
145
  end
147
146
 
148
- full_paths.unshift extension_dir unless @extensions.nil? || @extensions.empty?
147
+ full_paths << extension_dir unless @extensions.nil? || @extensions.empty?
149
148
 
150
149
  full_paths
151
150
  end
@@ -176,7 +176,7 @@ dependencies file.:
176
176
  Ruby Version and Engine Dependency
177
177
  ==================================
178
178
 
179
- You can specifiy the version, engine and engine version of ruby to use with
179
+ You can specify the version, engine and engine version of ruby to use with
180
180
  your gem dependencies file. If you are not running the specified version
181
181
  RubyGems will raise an exception.
182
182
 
@@ -223,7 +223,7 @@ The #group method can also be used to place gems in groups:
223
223
  The #group method allows multiple groups.
224
224
 
225
225
  The #gemspec development dependencies are placed in the :development group by
226
- default. This may be overriden with the :development_group option:
226
+ default. This may be overridden with the :development_group option:
227
227
 
228
228
  gemspec development_group: :other
229
229
 
@@ -61,7 +61,9 @@ class Gem::Commands::OpenCommand < Gem::Command
61
61
  end
62
62
 
63
63
  def open_editor path
64
- system(*@editor.split(/\s+/) + [path])
64
+ Dir.chdir(path) do
65
+ system(*@editor.split(/\s+/) + [path])
66
+ end
65
67
  end
66
68
 
67
69
  def spec_for name
@@ -21,7 +21,7 @@ via the webhooks. If you accidentally pushed passwords or other sensitive
21
21
  data you will need to change them immediately and yank your gem.
22
22
 
23
23
  If you are yanking a gem due to intellectual property reasons contact
24
- http://help.rubygems.org for permanant removal. Be sure to mention this
24
+ http://help.rubygems.org for permanent removal. Be sure to mention this
25
25
  as the reason for the removal request.
26
26
  EOF
27
27
  end
@@ -20,8 +20,7 @@ if Gem::GEM_PRELUDE_SUCKAGE and defined?(Gem::QuickLoader) then
20
20
 
21
21
  $LOADED_FEATURES.delete Gem::QuickLoader.path_to_full_rubygems_library
22
22
 
23
- if $LOADED_FEATURES.any? do |path| path.end_with? '/rubygems.rb' end then
24
- # TODO path does not exist here
23
+ if path = $LOADED_FEATURES.find {|n| n.end_with? '/rubygems.rb'} then
25
24
  raise LoadError, "another rubygems is already loaded from #{path}"
26
25
  end
27
26
 
@@ -218,7 +218,17 @@ class Gem::DependencyInstaller
218
218
  tuples, errors = Gem::SpecFetcher.fetcher.search_for_dependency dep
219
219
 
220
220
  if best_only && !tuples.empty?
221
- tuples.sort! { |a,b| b[0].version <=> a[0].version }
221
+ tuples.sort! do |a,b|
222
+ if b[0].version == a[0].version
223
+ if b[0].platform != Gem::Platform::RUBY
224
+ 1
225
+ else
226
+ -1
227
+ end
228
+ else
229
+ b[0].version <=> a[0].version
230
+ end
231
+ end
222
232
  tuples = [tuples.first]
223
233
  end
224
234
 
@@ -681,7 +681,7 @@ TEXT
681
681
  # return the stub script text used to launch the true Ruby script
682
682
 
683
683
  def windows_stub_script(bindir, bin_file_name)
684
- ruby = Gem.ruby.chomp('"').tr(File::SEPARATOR, "\\")
684
+ ruby = Gem.ruby.gsub(/^\"|\"$/, "").tr(File::SEPARATOR, "\\")
685
685
  return <<-TEXT
686
686
  @ECHO OFF
687
687
  IF NOT "%~f0" == "~f0" GOTO :WinNT
@@ -366,8 +366,9 @@ EOM
366
366
 
367
367
  FileUtils.mkdir_p mkdir, mkdir_options
368
368
 
369
- open destination, 'wb', entry.header.mode do |out|
369
+ open destination, 'wb' do |out|
370
370
  out.write entry.read
371
+ FileUtils.chmod entry.header.mode, destination
371
372
  end if entry.file?
372
373
 
373
374
  verbose destination
@@ -291,7 +291,7 @@ class Gem::Package::TarWriter
291
291
 
292
292
  def split_name(name) # :nodoc:
293
293
  if name.bytesize > 256
294
- raise Gem::Package::TooLongFileName.new("File \"#{name}\" has a too long path (should be 256 or less)")
294
+ raise Gem::Package::TooLongFileName.new("File \"#{name}\" has a too long path (should be 256 or less)")
295
295
  end
296
296
 
297
297
  if name.bytesize <= 100 then
@@ -311,11 +311,11 @@ class Gem::Package::TarWriter
311
311
  name = newname
312
312
 
313
313
  if name.bytesize > 100
314
- raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long name (should be 100 or less)")
314
+ raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long name (should be 100 or less)")
315
315
  end
316
-
316
+
317
317
  if prefix.bytesize > 155 then
318
- raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long base path (should be 155 or less)")
318
+ raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long base path (should be 155 or less)")
319
319
  end
320
320
  end
321
321
 
@@ -42,13 +42,6 @@ class Gem::PathSupport
42
42
 
43
43
  private
44
44
 
45
- ##
46
- # Set the Gem home directory (as reported by Gem.dir).
47
-
48
- def home=(home)
49
- @home = home.to_s
50
- end
51
-
52
45
  ##
53
46
  # Set the Gem search path (as reported by Gem.path).
54
47
 
@@ -1,4 +1,4 @@
1
- # This exists just to satify bugs in marshal'd gemspecs that
1
+ # This exists just to satisfy bugs in marshal'd gemspecs that
2
2
  # contain a reference to YAML::PrivateType. We prune these out
3
3
  # in Specification._load, but if we don't have the constant, Marshal
4
4
  # blows up.
@@ -103,7 +103,7 @@ class Gem::RemoteFetcher
103
103
  # filename. Returns nil if the gem cannot be located.
104
104
  #--
105
105
  # Should probably be integrated with #download below, but that will be a
106
- # larger, more emcompassing effort. -erikh
106
+ # larger, more encompassing effort. -erikh
107
107
 
108
108
  def download_to_cache dependency
109
109
  found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency
@@ -116,7 +116,7 @@ class Gem::RequestSet
116
116
  if dep = @dependency_names[name] then
117
117
  dep.requirement.concat reqs
118
118
  else
119
- dep = Gem::Dependency.new name, reqs
119
+ dep = Gem::Dependency.new name, *reqs
120
120
  @dependency_names[name] = dep
121
121
  @dependencies << dep
122
122
  end
@@ -223,7 +223,7 @@ class Gem::RequestSet
223
223
 
224
224
  if options.fetch :lock, true then
225
225
  lockfile =
226
- Gem::RequestSet::Lockfile.new self, gemdeps, gem_deps_api.dependencies
226
+ Gem::RequestSet::Lockfile.build self, gemdeps, gem_deps_api.dependencies
227
227
  lockfile.write
228
228
  end
229
229
 
@@ -275,8 +275,13 @@ class Gem::RequestSet
275
275
 
276
276
  @git_set.root_dir = @install_dir
277
277
 
278
- lockfile = Gem::RequestSet::Lockfile.new self, path
279
- lockfile.parse
278
+ lock_file = "#{File.expand_path(path)}.lock".untaint
279
+ begin
280
+ tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file lock_file
281
+ parser = tokenizer.make_parser self, []
282
+ parser.parse
283
+ rescue Errno::ENOENT
284
+ end
280
285
 
281
286
  gf = Gem::RequestSet::GemDependencyAPI.new self, path
282
287
  gf.installing = installing
@@ -411,3 +416,4 @@ end
411
416
 
412
417
  require 'rubygems/request_set/gem_dependency_api'
413
418
  require 'rubygems/request_set/lockfile'
419
+ require 'rubygems/request_set/lockfile/tokenizer'
@@ -367,11 +367,11 @@ class Gem::RequestSet::GemDependencyAPI
367
367
 
368
368
  @dependencies[name] =
369
369
  if requirements.empty? and not source_set then
370
- nil
370
+ Gem::Requirement.default
371
371
  elsif source_set then
372
- '!'
372
+ Gem::Requirement.source_set
373
373
  else
374
- requirements
374
+ Gem::Requirement.create requirements
375
375
  end
376
376
 
377
377
  return unless gem_platforms options
@@ -601,7 +601,7 @@ Gem dependencies file #{@path} requires #{name} more than once.
601
601
  add_dependencies groups, [self_dep]
602
602
  add_dependencies groups, spec.runtime_dependencies
603
603
 
604
- @dependencies[spec.name] = '!'
604
+ @dependencies[spec.name] = Gem::Requirement.source_set
605
605
 
606
606
  spec.dependencies.each do |dep|
607
607
  @dependencies[dep.name] = dep.requirement
@@ -1,12 +1,9 @@
1
- require 'strscan'
2
-
3
1
  ##
4
2
  # Parses a gem.deps.rb.lock file and constructs a LockSet containing the
5
3
  # dependencies found inside. If the lock file is missing no LockSet is
6
4
  # constructed.
7
5
 
8
6
  class Gem::RequestSet::Lockfile
9
-
10
7
  ##
11
8
  # Raised when a lockfile cannot be parsed
12
9
 
@@ -37,7 +34,35 @@ class Gem::RequestSet::Lockfile
37
34
  @path = path
38
35
  super "#{message} (at line #{line} column #{column})"
39
36
  end
37
+ end
38
+
39
+ ##
40
+ # Creates a new Lockfile for the given +request_set+ and +gem_deps_file+
41
+ # location.
42
+
43
+ def self.build request_set, gem_deps_file, dependencies = nil
44
+ request_set.resolve
45
+ dependencies ||= requests_to_deps request_set.sorted_requests
46
+ new request_set, gem_deps_file, dependencies
47
+ end
48
+
49
+ def self.requests_to_deps requests # :nodoc:
50
+ deps = {}
51
+
52
+ requests.each do |request|
53
+ spec = request.spec
54
+ name = request.name
55
+ requirement = request.request.dependency.requirement
56
+
57
+ deps[name] = if [Gem::Resolver::VendorSpecification,
58
+ Gem::Resolver::GitSpecification].include? spec.class then
59
+ Gem::Requirement.source_set
60
+ else
61
+ requirement
62
+ end
63
+ end
40
64
 
65
+ deps
41
66
  end
42
67
 
43
68
  ##
@@ -45,11 +70,7 @@ class Gem::RequestSet::Lockfile
45
70
 
46
71
  attr_reader :platforms
47
72
 
48
- ##
49
- # Creates a new Lockfile for the given +request_set+ and +gem_deps_file+
50
- # location.
51
-
52
- def initialize request_set, gem_deps_file, dependencies = nil
73
+ def initialize request_set, gem_deps_file, dependencies
53
74
  @set = request_set
54
75
  @dependencies = dependencies
55
76
  @gem_deps_file = File.expand_path(gem_deps_file)
@@ -57,59 +78,23 @@ class Gem::RequestSet::Lockfile
57
78
 
58
79
  @gem_deps_file.untaint unless gem_deps_file.tainted?
59
80
 
60
- @current_token = nil
61
- @line = 0
62
- @line_pos = 0
63
81
  @platforms = []
64
- @tokens = []
65
82
  end
66
83
 
67
84
  def add_DEPENDENCIES out # :nodoc:
68
85
  out << "DEPENDENCIES"
69
86
 
70
- dependencies =
71
- if @dependencies then
72
- @dependencies.sort_by { |name,| name }.map do |name, requirement|
73
- requirement_string =
74
- if '!' == requirement then
75
- requirement
76
- else
77
- Gem::Requirement.new(requirement).for_lockfile
78
- end
79
-
80
- [name, requirement_string]
81
- end
82
- else
83
- @requests.sort_by { |r| r.name }.map do |request|
84
- spec = request.spec
85
- name = request.name
86
- requirement = request.request.dependency.requirement
87
-
88
- requirement_string =
89
- if [Gem::Resolver::VendorSpecification,
90
- Gem::Resolver::GitSpecification].include? spec.class then
91
- "!"
92
- else
93
- requirement.for_lockfile
94
- end
95
-
96
- [name, requirement_string]
97
- end
98
- end
99
-
100
- dependencies = dependencies.map do |name, requirement_string|
101
- " #{name}#{requirement_string}"
102
- end
103
-
104
- out.concat dependencies
87
+ out.concat @dependencies.sort_by { |name,| name }.map { |name, requirement|
88
+ " #{name}#{requirement.for_lockfile}"
89
+ }
105
90
 
106
91
  out << nil
107
92
  end
108
93
 
109
- def add_GEM out # :nodoc:
110
- return if @spec_groups.empty?
94
+ def add_GEM out, spec_groups # :nodoc:
95
+ return if spec_groups.empty?
111
96
 
112
- source_groups = @spec_groups.values.flatten.group_by do |request|
97
+ source_groups = spec_groups.values.flatten.group_by do |request|
113
98
  request.spec.source.uri
114
99
  end
115
100
 
@@ -136,9 +121,8 @@ class Gem::RequestSet::Lockfile
136
121
  end
137
122
  end
138
123
 
139
- def add_GIT out
140
- return unless git_requests =
141
- @spec_groups.delete(Gem::Resolver::GitSpecification)
124
+ def add_GIT out, git_requests
125
+ return if git_requests.empty?
142
126
 
143
127
  by_repository_revision = git_requests.group_by do |request|
144
128
  source = request.spec.source
@@ -179,9 +163,8 @@ class Gem::RequestSet::Lockfile
179
163
  end
180
164
  end
181
165
 
182
- def add_PATH out # :nodoc:
183
- return unless path_requests =
184
- @spec_groups.delete(Gem::Resolver::VendorSpecification)
166
+ def add_PATH out, path_requests # :nodoc:
167
+ return if path_requests.empty?
185
168
 
186
169
  out << "PATH"
187
170
  path_requests.each do |request|
@@ -198,7 +181,7 @@ class Gem::RequestSet::Lockfile
198
181
  def add_PLATFORMS out # :nodoc:
199
182
  out << "PLATFORMS"
200
183
 
201
- platforms = @requests.map { |request| request.spec.platform }.uniq
184
+ platforms = requests.map { |request| request.spec.platform }.uniq
202
185
 
203
186
  platforms = platforms.sort_by { |platform| platform.to_s }
204
187
 
@@ -209,340 +192,23 @@ class Gem::RequestSet::Lockfile
209
192
  out << nil
210
193
  end
211
194
 
212
- ##
213
- # Gets the next token for a Lockfile
214
-
215
- def get expected_types = nil, expected_value = nil # :nodoc:
216
- @current_token = @tokens.shift
217
-
218
- type, value, column, line = @current_token
219
-
220
- if expected_types and not Array(expected_types).include? type then
221
- unget
222
-
223
- message = "unexpected token [#{type.inspect}, #{value.inspect}], " +
224
- "expected #{expected_types.inspect}"
225
-
226
- raise ParseError.new message, column, line, "#{@gem_deps_file}.lock"
227
- end
228
-
229
- if expected_value and expected_value != value then
230
- unget
231
-
232
- message = "unexpected token [#{type.inspect}, #{value.inspect}], " +
233
- "expected [#{expected_types.inspect}, " +
234
- "#{expected_value.inspect}]"
235
-
236
- raise ParseError.new message, column, line, "#{@gem_deps_file}.lock"
237
- end
238
-
239
- @current_token
240
- end
241
-
242
- def parse # :nodoc:
243
- tokenize
244
-
245
- until @tokens.empty? do
246
- type, data, column, line = get
247
-
248
- case type
249
- when :section then
250
- skip :newline
251
-
252
- case data
253
- when 'DEPENDENCIES' then
254
- parse_DEPENDENCIES
255
- when 'GIT' then
256
- parse_GIT
257
- when 'GEM' then
258
- parse_GEM
259
- when 'PATH' then
260
- parse_PATH
261
- when 'PLATFORMS' then
262
- parse_PLATFORMS
263
- else
264
- type, = get until @tokens.empty? or peek.first == :section
265
- end
266
- else
267
- raise "BUG: unhandled token #{type} (#{data.inspect}) at line #{line} column #{column}"
268
- end
269
- end
270
- end
271
-
272
- def parse_DEPENDENCIES # :nodoc:
273
- while not @tokens.empty? and :text == peek.first do
274
- _, name, = get :text
275
-
276
- requirements = []
277
-
278
- case peek[0]
279
- when :bang then
280
- get :bang
281
-
282
- requirements << pinned_requirement(name)
283
- when :l_paren then
284
- get :l_paren
285
-
286
- loop do
287
- _, op, = get :requirement
288
- _, version, = get :text
289
-
290
- requirements << "#{op} #{version}"
291
-
292
- break unless peek[0] == :comma
293
-
294
- get :comma
295
- end
296
-
297
- get :r_paren
298
-
299
- if peek[0] == :bang then
300
- requirements.clear
301
- requirements << pinned_requirement(name)
302
-
303
- get :bang
304
- end
305
- end
306
-
307
- @set.gem name, *requirements
308
-
309
- skip :newline
310
- end
311
- end
312
-
313
- def parse_GEM # :nodoc:
314
- sources = []
315
-
316
- while [:entry, 'remote'] == peek.first(2) do
317
- get :entry, 'remote'
318
- _, data, = get :text
319
- skip :newline
320
-
321
- sources << Gem::Source.new(data)
322
- end
323
-
324
- sources << Gem::Source.new(Gem::DEFAULT_HOST) if sources.empty?
325
-
326
- get :entry, 'specs'
327
-
328
- skip :newline
329
-
330
- set = Gem::Resolver::LockSet.new sources
331
- last_specs = nil
332
-
333
- while not @tokens.empty? and :text == peek.first do
334
- _, name, column, = get :text
335
-
336
- case peek[0]
337
- when :newline then
338
- last_specs.each do |spec|
339
- spec.add_dependency Gem::Dependency.new name if column == 6
340
- end
341
- when :l_paren then
342
- get :l_paren
343
-
344
- type, data, = get [:text, :requirement]
345
-
346
- if type == :text and column == 4 then
347
- version, platform = data.split '-', 2
348
-
349
- platform =
350
- platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
351
-
352
- last_specs = set.add name, version, platform
353
- else
354
- dependency = parse_dependency name, data
355
-
356
- last_specs.each do |spec|
357
- spec.add_dependency dependency
358
- end
359
- end
360
-
361
- get :r_paren
362
- else
363
- raise "BUG: unknown token #{peek}"
364
- end
365
-
366
- skip :newline
367
- end
368
-
369
- @set.sets << set
370
- end
371
-
372
- def parse_GIT # :nodoc:
373
- get :entry, 'remote'
374
- _, repository, = get :text
375
-
376
- skip :newline
377
-
378
- get :entry, 'revision'
379
- _, revision, = get :text
380
-
381
- skip :newline
382
-
383
- type, value = peek.first 2
384
- if type == :entry and %w[branch ref tag].include? value then
385
- get
386
- get :text
387
-
388
- skip :newline
389
- end
390
-
391
- get :entry, 'specs'
392
-
393
- skip :newline
394
-
395
- set = Gem::Resolver::GitSet.new
396
- set.root_dir = @set.install_dir
397
-
398
- last_spec = nil
399
-
400
- while not @tokens.empty? and :text == peek.first do
401
- _, name, column, = get :text
402
-
403
- case peek[0]
404
- when :newline then
405
- last_spec.add_dependency Gem::Dependency.new name if column == 6
406
- when :l_paren then
407
- get :l_paren
408
-
409
- type, data, = get [:text, :requirement]
410
-
411
- if type == :text and column == 4 then
412
- last_spec = set.add_git_spec name, data, repository, revision, true
413
- else
414
- dependency = parse_dependency name, data
415
-
416
- last_spec.add_dependency dependency
417
- end
418
-
419
- get :r_paren
420
- else
421
- raise "BUG: unknown token #{peek}"
422
- end
423
-
424
- skip :newline
425
- end
426
-
427
- @set.sets << set
428
- end
429
-
430
- def parse_PATH # :nodoc:
431
- get :entry, 'remote'
432
- _, directory, = get :text
433
-
434
- skip :newline
435
-
436
- get :entry, 'specs'
437
-
438
- skip :newline
439
-
440
- set = Gem::Resolver::VendorSet.new
441
- last_spec = nil
442
-
443
- while not @tokens.empty? and :text == peek.first do
444
- _, name, column, = get :text
445
-
446
- case peek[0]
447
- when :newline then
448
- last_spec.add_dependency Gem::Dependency.new name if column == 6
449
- when :l_paren then
450
- get :l_paren
451
-
452
- type, data, = get [:text, :requirement]
453
-
454
- if type == :text and column == 4 then
455
- last_spec = set.add_vendor_gem name, directory
456
- else
457
- dependency = parse_dependency name, data
458
-
459
- last_spec.dependencies << dependency
460
- end
461
-
462
- get :r_paren
463
- else
464
- raise "BUG: unknown token #{peek}"
465
- end
466
-
467
- skip :newline
468
- end
469
-
470
- @set.sets << set
471
- end
472
-
473
- def parse_PLATFORMS # :nodoc:
474
- while not @tokens.empty? and :text == peek.first do
475
- _, name, = get :text
476
-
477
- @platforms << name
478
-
479
- skip :newline
480
- end
481
- end
482
-
483
- ##
484
- # Parses the requirements following the dependency +name+ and the +op+ for
485
- # the first token of the requirements and returns a Gem::Dependency object.
486
-
487
- def parse_dependency name, op # :nodoc:
488
- return Gem::Dependency.new name, op unless peek[0] == :text
489
-
490
- _, version, = get :text
491
-
492
- requirements = ["#{op} #{version}"]
493
-
494
- while peek[0] == :comma do
495
- get :comma
496
- _, op, = get :requirement
497
- _, version, = get :text
498
-
499
- requirements << "#{op} #{version}"
500
- end
501
-
502
- Gem::Dependency.new name, requirements
503
- end
504
-
505
- ##
506
- # Peeks at the next token for Lockfile
507
-
508
- def peek # :nodoc:
509
- @tokens.first || [:EOF]
510
- end
511
-
512
- def pinned_requirement name # :nodoc:
513
- spec = @set.sets.select { |set|
514
- Gem::Resolver::GitSet === set or
515
- Gem::Resolver::VendorSet === set
516
- }.map { |set|
517
- set.specs[name]
518
- }.compact.first
519
-
520
- spec.version
521
- end
522
-
523
- def skip type # :nodoc:
524
- get while not @tokens.empty? and peek.first == type
195
+ def spec_groups
196
+ requests.group_by { |request| request.spec.class }
525
197
  end
526
198
 
527
199
  ##
528
200
  # The contents of the lock file.
529
201
 
530
202
  def to_s
531
- @set.resolve
532
-
533
203
  out = []
534
204
 
535
- @requests = @set.sorted_requests
536
-
537
- @spec_groups = @requests.group_by do |request|
538
- request.spec.class
539
- end
205
+ groups = spec_groups
540
206
 
541
- add_PATH out
207
+ add_PATH out, groups.delete(Gem::Resolver::VendorSpecification) { [] }
542
208
 
543
- add_GIT out
209
+ add_GIT out, groups.delete(Gem::Resolver::GitSpecification) { [] }
544
210
 
545
- add_GEM out
211
+ add_GEM out, groups
546
212
 
547
213
  add_PLATFORMS out
548
214
 
@@ -551,90 +217,6 @@ class Gem::RequestSet::Lockfile
551
217
  out.join "\n"
552
218
  end
553
219
 
554
- ##
555
- # Calculates the column (by byte) and the line of the current token based on
556
- # +byte_offset+.
557
-
558
- def token_pos byte_offset # :nodoc:
559
- [byte_offset - @line_pos, @line]
560
- end
561
-
562
- ##
563
- # Converts a lock file into an Array of tokens. If the lock file is missing
564
- # an empty Array is returned.
565
-
566
- def tokenize # :nodoc:
567
- @line = 0
568
- @line_pos = 0
569
-
570
- @platforms = []
571
- @tokens = []
572
- @current_token = nil
573
-
574
- lock_file = "#{@gem_deps_file}.lock"
575
-
576
- @input = File.read lock_file
577
- s = StringScanner.new @input
578
-
579
- until s.eos? do
580
- pos = s.pos
581
-
582
- pos = s.pos if leading_whitespace = s.scan(/ +/)
583
-
584
- if s.scan(/[<|=>]{7}/) then
585
- message = "your #{lock_file} contains merge conflict markers"
586
- column, line = token_pos pos
587
-
588
- raise ParseError.new message, column, line, lock_file
589
- end
590
-
591
- @tokens <<
592
- case
593
- when s.scan(/\r?\n/) then
594
- token = [:newline, nil, *token_pos(pos)]
595
- @line_pos = s.pos
596
- @line += 1
597
- token
598
- when s.scan(/[A-Z]+/) then
599
- if leading_whitespace then
600
- text = s.matched
601
- text += s.scan(/[^\s)]*/).to_s # in case of no match
602
- [:text, text, *token_pos(pos)]
603
- else
604
- [:section, s.matched, *token_pos(pos)]
605
- end
606
- when s.scan(/([a-z]+):\s/) then
607
- s.pos -= 1 # rewind for possible newline
608
- [:entry, s[1], *token_pos(pos)]
609
- when s.scan(/\(/) then
610
- [:l_paren, nil, *token_pos(pos)]
611
- when s.scan(/\)/) then
612
- [:r_paren, nil, *token_pos(pos)]
613
- when s.scan(/<=|>=|=|~>|<|>|!=/) then
614
- [:requirement, s.matched, *token_pos(pos)]
615
- when s.scan(/,/) then
616
- [:comma, nil, *token_pos(pos)]
617
- when s.scan(/!/) then
618
- [:bang, nil, *token_pos(pos)]
619
- when s.scan(/[^\s),!]*/) then
620
- [:text, s.matched, *token_pos(pos)]
621
- else
622
- raise "BUG: can't create token for: #{s.string[s.pos..-1].inspect}"
623
- end
624
- end
625
-
626
- @tokens
627
- rescue Errno::ENOENT
628
- @tokens
629
- end
630
-
631
- ##
632
- # Ungets the last token retrieved by #get
633
-
634
- def unget # :nodoc:
635
- @tokens.unshift @current_token
636
- end
637
-
638
220
  ##
639
221
  # Writes the lock file alongside the gem dependencies file
640
222
 
@@ -646,5 +228,11 @@ class Gem::RequestSet::Lockfile
646
228
  end
647
229
  end
648
230
 
231
+ private
232
+
233
+ def requests
234
+ @set.sorted_requests
235
+ end
649
236
  end
650
237
 
238
+ require 'rubygems/request_set/lockfile/tokenizer'