[前][次][番号順一覧][スレッド一覧]

ruby-changes:37430

From: hsbt <ko1@a...>
Date: Thu, 5 Feb 2015 22:43:02 +0900 (JST)
Subject: [ruby-changes:37430] hsbt:r49511 (trunk): * lib/rubygems: Update to RubyGems HEAD(5c3b6f3).

hsbt	2015-02-05 22:42:45 +0900 (Thu, 05 Feb 2015)

  New Revision: 49511

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=49511

  Log:
    * lib/rubygems:  Update to RubyGems HEAD(5c3b6f3).
      Fixed #1156, #1142, #1115, #1142, #1139 on rubygems/rubygems
    * test/rubygems:  ditto.

  Added directories:
    trunk/lib/rubygems/request_set/lockfile/
  Added files:
    trunk/lib/rubygems/request_set/lockfile/parser.rb
    trunk/lib/rubygems/request_set/lockfile/tokenizer.rb
    trunk/test/rubygems/test_gem_request_set_lockfile_parser.rb
    trunk/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb
  Modified files:
    trunk/ChangeLog
    trunk/lib/rubygems/basic_specification.rb
    trunk/lib/rubygems/commands/open_command.rb
    trunk/lib/rubygems/installer.rb
    trunk/lib/rubygems/request_set/lockfile.rb
    trunk/lib/rubygems/request_set.rb
    trunk/lib/rubygems/requirement.rb
    trunk/lib/rubygems/specification.rb
    trunk/lib/rubygems/test_case.rb
    trunk/lib/rubygems/user_interaction.rb
    trunk/test/rubygems/test_gem_commands_open_command.rb
    trunk/test/rubygems/test_gem_request_set_gem_dependency_api.rb
    trunk/test/rubygems/test_gem_request_set_lockfile.rb
    trunk/test/rubygems/test_gem_requirement.rb
    trunk/test/rubygems/test_gem_specification.rb
    trunk/test/rubygems/test_gem_stub_specification.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 49510)
+++ ChangeLog	(revision 49511)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Feb  5 22:42:34 2015  SHIBATA Hiroshi  <shibata.hiroshi@g...>
+
+	* lib/rubygems:  Update to RubyGems HEAD(5c3b6f3).
+	  Fixed #1156, #1142, #1115, #1142, #1139 on rubygems/rubygems
+	* test/rubygems:  ditto.
+
 Thu Feb  5 13:41:01 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* vm_eval.c (send_internal), vm_insnhelper.c (vm_call_opt_send):
Index: lib/rubygems/basic_specification.rb
===================================================================
--- lib/rubygems/basic_specification.rb	(revision 49510)
+++ lib/rubygems/basic_specification.rb	(revision 49511)
@@ -144,7 +144,7 @@ class Gem::BasicSpecification https://github.com/ruby/ruby/blob/trunk/lib/rubygems/basic_specification.rb#L144
         File.join full_gem_path, path
       end
 
-      full_paths.unshift extension_dir unless @extensions.nil? || @extensions.empty?
+      full_paths << extension_dir unless @extensions.nil? || @extensions.empty?
 
       full_paths
     end
Index: lib/rubygems/request_set.rb
===================================================================
--- lib/rubygems/request_set.rb	(revision 49510)
+++ lib/rubygems/request_set.rb	(revision 49511)
@@ -116,7 +116,7 @@ class Gem::RequestSet https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set.rb#L116
     if dep = @dependency_names[name] then
       dep.requirement.concat reqs
     else
-      dep = Gem::Dependency.new name, reqs
+      dep = Gem::Dependency.new name, *reqs
       @dependency_names[name] = dep
       @dependencies << dep
     end
@@ -275,8 +275,13 @@ class Gem::RequestSet https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set.rb#L275
 
     @git_set.root_dir = @install_dir
 
-    lockfile = Gem::RequestSet::Lockfile.new self, path
-    lockfile.parse
+    lock_file = "#{File.expand_path(path)}.lock"
+    begin
+      tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file lock_file
+      parser = tokenizer.make_parser self, []
+      parser.parse
+    rescue Errno::ENOENT
+    end
 
     gf = Gem::RequestSet::GemDependencyAPI.new self, path
     gf.installing = installing
@@ -411,3 +416,4 @@ end https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set.rb#L416
 
 require 'rubygems/request_set/gem_dependency_api'
 require 'rubygems/request_set/lockfile'
+require 'rubygems/request_set/lockfile/tokenizer'
Index: lib/rubygems/specification.rb
===================================================================
--- lib/rubygems/specification.rb	(revision 49510)
+++ lib/rubygems/specification.rb	(revision 49511)
@@ -1028,8 +1028,8 @@ class Gem::Specification < Gem::BasicSpe https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L1028
     file = file.dup.untaint
     return unless File.file?(file)
 
-    spec = LOAD_CACHE[file]
-    return spec if spec
+    _spec = LOAD_CACHE[file]
+    return _spec if _spec
 
     code = if defined? Encoding
              File.read file, :mode => 'r:UTF-8:-'
@@ -1040,15 +1040,15 @@ class Gem::Specification < Gem::BasicSpe https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L1040
     code.untaint
 
     begin
-      spec = eval code, binding, file
+      _spec = eval code, binding, file
 
-      if Gem::Specification === spec
-        spec.loaded_from = File.expand_path file.to_s
-        LOAD_CACHE[file] = spec
-        return spec
+      if Gem::Specification === _spec
+        _spec.loaded_from = File.expand_path file.to_s
+        LOAD_CACHE[file] = _spec
+        return _spec
       end
 
-      warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)."
+      warn "[#{file}] isn't a Gem::Specification (#{_spec.class} instead)."
     rescue SignalException, SystemExit
       raise
     rescue SyntaxError, Exception => e
@@ -1350,7 +1350,7 @@ class Gem::Specification < Gem::BasicSpe https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L1350
                    end
 
     unless dependency.respond_to?(:name) &&
-           dependency.respond_to?(:version_requirements)
+           dependency.respond_to?(:requirement)
       dependency = Gem::Dependency.new(dependency.to_s, requirements, type)
     end
 
Index: lib/rubygems/commands/open_command.rb
===================================================================
--- lib/rubygems/commands/open_command.rb	(revision 49510)
+++ lib/rubygems/commands/open_command.rb	(revision 49511)
@@ -61,7 +61,9 @@ class Gem::Commands::OpenCommand < Gem:: https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/open_command.rb#L61
   end
 
   def open_editor path
-    system(*@editor.split(/\s+/) + [path])
+    Dir.chdir(path) do
+      system(*@editor.split(/\s+/) + [path])
+    end
   end
 
   def spec_for name
Index: lib/rubygems/requirement.rb
===================================================================
--- lib/rubygems/requirement.rb	(revision 49510)
+++ lib/rubygems/requirement.rb	(revision 49511)
@@ -171,7 +171,7 @@ class Gem::Requirement https://github.com/ruby/ruby/blob/trunk/lib/rubygems/requirement.rb#L171
   end
 
   def hash # :nodoc:
-    requirements.hash
+    requirements.sort.hash
   end
 
   def marshal_dump # :nodoc:
Index: lib/rubygems/user_interaction.rb
===================================================================
--- lib/rubygems/user_interaction.rb	(revision 49510)
+++ lib/rubygems/user_interaction.rb	(revision 49511)
@@ -396,10 +396,6 @@ class Gem::StreamUI https://github.com/ruby/ruby/blob/trunk/lib/rubygems/user_interaction.rb#L396
   # Return a progress reporter object chosen from the current verbosity.
 
   def progress_reporter(*args)
-    if self.kind_of?(Gem::SilentUI)
-      return SilentProgressReporter.new(@outs, *args)
-    end
-
     case Gem.configuration.verbose
     when nil, false
       SilentProgressReporter.new(@outs, *args)
@@ -533,10 +529,6 @@ class Gem::StreamUI https://github.com/ruby/ruby/blob/trunk/lib/rubygems/user_interaction.rb#L529
   # Return a download reporter object chosen from the current verbosity
 
   def download_reporter(*args)
-    if self.kind_of?(Gem::SilentUI)
-      return SilentDownloadReporter.new(@outs, *args)
-    end
-
     case Gem.configuration.verbose
     when nil, false
       SilentDownloadReporter.new(@outs, *args)
Index: lib/rubygems/request_set/lockfile/tokenizer.rb
===================================================================
--- lib/rubygems/request_set/lockfile/tokenizer.rb	(revision 0)
+++ lib/rubygems/request_set/lockfile/tokenizer.rb	(revision 49511)
@@ -0,0 +1,108 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile/tokenizer.rb#L1
+require 'strscan'
+require 'rubygems/request_set/lockfile/parser'
+
+class Gem::RequestSet::Lockfile::Tokenizer
+  def self.from_file file
+    new File.read(file), file
+  end
+
+  def initialize input, filename = nil, line = 0, pos = 0
+    @line     = line
+    @line_pos = pos
+    @tokens   = []
+    @filename = filename
+    tokenize input
+  end
+
+  def make_parser set, platforms
+    Gem::RequestSet::Lockfile::Parser.new self, set, platforms, @filename
+  end
+
+  def to_a
+    @tokens
+  end
+
+  def skip type
+    @tokens.shift while not @tokens.empty? and peek.first == type
+  end
+
+  ##
+  # Calculates the column (by byte) and the line of the current token based on
+  # +byte_offset+.
+
+  def token_pos byte_offset # :nodoc:
+    [byte_offset - @line_pos, @line]
+  end
+
+  def empty?
+    @tokens.empty?
+  end
+
+  def unshift token
+    @tokens.unshift token
+  end
+
+  def next_token
+    @tokens.shift
+  end
+  alias :shift :next_token
+
+  def peek
+    @tokens.first || [:EOF]
+  end
+
+  private
+
+  def tokenize input
+    s = StringScanner.new input
+
+    until s.eos? do
+      pos = s.pos
+
+      pos = s.pos if leading_whitespace = s.scan(/ +/)
+
+      if s.scan(/[<|=>]{7}/) then
+        message = "your #{@filename} contains merge conflict markers"
+        column, line = token_pos pos
+
+        raise Gem::RequestSet::Lockfile::ParseError.new message, column, line, @filename
+      end
+
+      @tokens <<
+        case
+        when s.scan(/\r?\n/) then
+          token = [:newline, nil, *token_pos(pos)]
+          @line_pos = s.pos
+          @line += 1
+          token
+        when s.scan(/[A-Z]+/) then
+          if leading_whitespace then
+            text = s.matched
+            text += s.scan(/[^\s)]*/).to_s # in case of no match
+            [:text, text, *token_pos(pos)]
+          else
+            [:section, s.matched, *token_pos(pos)]
+          end
+        when s.scan(/([a-z]+):\s/) then
+          s.pos -= 1 # rewind for possible newline
+          [:entry, s[1], *token_pos(pos)]
+        when s.scan(/\(/) then
+          [:l_paren, nil, *token_pos(pos)]
+        when s.scan(/\)/) then
+          [:r_paren, nil, *token_pos(pos)]
+        when s.scan(/<=|>=|=|~>|<|>|!=/) then
+          [:requirement, s.matched, *token_pos(pos)]
+        when s.scan(/,/) then
+          [:comma, nil, *token_pos(pos)]
+        when s.scan(/!/) then
+          [:bang, nil, *token_pos(pos)]
+        when s.scan(/[^\s),!]*/) then
+          [:text, s.matched, *token_pos(pos)]
+        else
+          raise "BUG: can't create token for: #{s.string[s.pos..-1].inspect}"
+        end
+    end
+
+    @tokens
+  end
+end
Index: lib/rubygems/request_set/lockfile/parser.rb
===================================================================
--- lib/rubygems/request_set/lockfile/parser.rb	(revision 0)
+++ lib/rubygems/request_set/lockfile/parser.rb	(revision 49511)
@@ -0,0 +1,334 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile/parser.rb#L1
+class Gem::RequestSet::Lockfile::Parser
+  ###
+  # Parses lockfiles
+
+  def initialize tokenizer, set, platforms, filename = nil
+    @tokens    = tokenizer
+    @filename  = filename
+    @set       = set
+    @platforms = platforms
+  end
+
+  def parse
+    until @tokens.empty? do
+      type, data, column, line = get
+
+      case type
+      when :section then
+        @tokens.skip :newline
+
+        case data
+        when 'DEPENDENCIES' then
+          parse_DEPENDENCIES
+        when 'GIT' then
+          parse_GIT
+        when 'GEM' then
+          parse_GEM
+        when 'PATH' then
+          parse_PATH
+        when 'PLATFORMS' then
+          parse_PLATFORMS
+        else
+          type, = get until @tokens.empty? or peek.first == :section
+        end
+      else
+        raise "BUG: unhandled token #{type} (#{data.inspect}) at line #{line} column #{column}"
+      end
+    end
+  end
+
+  ##
+  # Gets the next token for a Lockfile
+
+  def get expected_types = nil, expected_value = nil # :nodoc:
+    current_token = @tokens.shift
+
+    type, value, column, line = current_token
+
+    if expected_types and not Array(expected_types).include? type then
+      unget current_token
+
+      message = "unexpected token [#{type.inspect}, #{value.inspect}], " +
+                "expected #{expected_types.inspect}"
+
+      raise Gem::RequestSet::Lockfile::ParseError.new message, column, line, @filename
+    end
+
+    if expected_value and expected_value != value then
+      unget current_token
+
+      message = "unexpected token [#{type.inspect}, #{value.inspect}], " +
+                "expected [#{expected_types.inspect}, " +
+                "#{expected_value.inspect}]"
+
+      raise Gem::RequestSet::Lockfile::ParseError.new message, column, line, @filename
+    end
+
+    current_token
+  end
+
+  def parse_DEPENDENCIES # :nodoc:
+    while not @tokens.empty? and :text == peek.first do
+      _, name, = get :text
+
+      requirements = []
+
+      case peek[0]
+      when :bang then
+        get :bang
+
+        requirements << pinned_requirement(name)
+      when :l_paren then
+        get :l_paren
+
+        loop do
+          _, op,      = get :requirement
+          _, version, = get :text
+
+          requirements << "#{op} #{version}"
+
+          break unless peek[0] == :comma
+
+          get :comma
+        end
+
+        get :r_paren
+
+        if peek[0] == :bang then
+          requirements.clear
+          requirements << pinned_requirement(name)
+
+          get :bang
+        end
+      end
+
+      @set.gem name, *requirements
+
+      skip :newline
+    end
+  end
+
+  def parse_GEM # :nodoc:
+    sources = []
+
+    while [:entry, 'remote'] == peek.first(2) do
+      get :entry, 'remote'
+      _, data, = get :text
+      skip :newline
+
+      sources << Gem::Source.new(data)
+    end
+
+    sources << Gem::Source.new(Gem::DEFAULT_HOST) if sources.empty?
+
+    get :entry, 'specs'
+
+    skip :newline
+
+    set = Gem::Resolver::LockSet.new sources
+    last_specs = nil
+
+    while not @tokens.empty? and :text == peek.first do
+      _, name, column, = get :text
+
+      case peek[0]
+      when :newline then
+        last_specs.each do |spec|
+          spec.add_dependency Gem::Dependency.new name if column == 6
+        end
+      when :l_paren then
+        get :l_paren
+
+        type, data, = get [:text, :requirement]
+
+        if type == :text and column == 4 then
+          version, platform = data.split '-', 2
+
+          platform =
+            platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
+
+          last_specs = set.add name, version, platform
+        else
+          dependency = parse_dependency name, data
+
+          last_specs.each do |spec|
+            spec.add_dependency dependency
+          end
+        end
+
+        get :r_paren
+      else
+        raise "BUG: unknown token #{peek}"
+      end
+
+      skip :newline
+    end
+
+    @set.sets << set
+  end
+
+  def parse_GIT # :nodoc:
+    get :entry, 'remote'
+    _, repository, = get :text
+
+    skip :newline
+
+    get :entry, 'revision'
+    _, revision, = get :text
+
+    skip :newline
+
+    type, value = peek.first 2
+    if type == :entry and %w[branch ref tag].include? value then
+      get
+      get :text
+
+      skip :newline
+    end
+
+    get :entry, 'specs'
+
+    skip :newline
+
+    set = Gem::Resolver::GitSet.new
+    set.root_dir = @set.install_dir
+
+    last_spec = nil
+
+    while not @tokens.empty? and :text == peek.first do
+      _, name, column, = get :text
+
+      case peek[0]
+      when :newline then
+        last_spec.add_dependency Gem::Dependency.new name if column == 6
+      when :l_paren then
+        get :l_paren
+
+        type, data, = get [:text, :requirement]
+
+        if type == :text and column == 4 then
+          last_spec = set.add_git_spec name, data, repository, revision, true
+        else
+          dependency = parse_dependency name, data
+
+          last_spec.add_dependency dependency
+        end
+
+        get :r_paren
+      else
+        raise "BUG: unknown token #{peek}"
+      end
+
+      skip :newline
+    end
+
+    @set.sets << set
+  end
+
+  def parse_PATH # :nodoc:
+    get :entry, 'remote'
+    _, directory, = get :text
+
+    skip :newline
+
+    get :entry, 'specs'
+
+    skip :newline
+
+    set = Gem::Resolver::VendorSet.new
+    last_spec = nil
+
+    while not @tokens.empty? and :text == peek.first do
+      _, name, column, = get :text
+
+      case peek[0]
+      when :newline then
+        last_spec.add_dependency Gem::Dependency.new name if column == 6
+      when :l_paren then
+        get :l_paren
+
+        type, data, = get [:text, :requirement]
+
+        if type == :text and column == 4 then
+          last_spec = set.add_vendor_gem name, directory
+        else
+          dependency = parse_dependency name, data
+
+          last_spec.dependencies << dependency
+        end
+
+        get :r_paren
+      else
+        raise "BUG: unknown token #{peek}"
+      end
+
+      skip :newline
+    end
+
+    @set.sets << set
+  end
+
+  def parse_PLATFORMS # :nodoc:
+    while not @tokens.empty? and :text == peek.first do
+      _, name, = get :text
+
+      @platforms << name
+
+      skip :newline
+    end
+  end
+
+  ##
+  # Parses the requirements following the dependency +name+ and the +op+ for
+  # the first token of the requirements and returns a Gem::Dependency object.
+
+  def parse_dependency name, op # :nodoc:
+    return Gem::Dependency.new name, op unless peek[0] == :text
+
+    _, version, = get :text
+
+    requirements = ["#{op} #{version}"]
+
+    while peek[0] == :comma do
+      get :comma
+      _, op,      = get :requirement
+      _, version, = get :text
+
+      requirements << "#{op} #{version}"
+    end
+
+    Gem::Dependency.new name, requirements
+  end
+
+  private
+
+  def skip type # :nodoc:
+    @tokens.skip type
+  end
+
+  ##
+  # Peeks at the next token for Lockfile
+
+  def peek # :nodoc:
+    @tokens.peek
+  end
+
+  def pinned_requirement name # :nodoc:
+    spec = @set.sets.select { |set|
+      Gem::Resolver::GitSet    === set or
+        Gem::Resolver::VendorSet === set
+    }.map { |set|
+      set.specs[name]
+    }.compact.first
+
+    spec.version
+  end
+
+  ##
+  # Ungets the last token retrieved by #get
+
+  def unget token # :nodoc:
+    @tokens.unshift token
+  end
+end
+
Index: lib/rubygems/request_set/lockfile.rb
===================================================================
--- lib/rubygems/request_set/lockfile.rb	(revision 49510)
+++ lib/rubygems/request_set/lockfile.rb	(revision 49511)
@@ -1,12 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile.rb#L1
-require 'strscan'
-
 ##
 # Parses a gem.deps.rb.lock file and constructs a LockSet containing the
 # dependencies found inside.  If the lock file is missing no LockSet is
 # constructed.
 
 class Gem::RequestSet::Lockfile
-
   ##
   # Raised when a lockfile cannot be parsed
 
@@ -37,7 +34,6 @@ class Gem::RequestSet::Lockfile https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile.rb#L34
       @path   = path
       super "#{message} (at line #{line} column #{column})"
     end
-
   end
 
   ##
@@ -57,11 +53,7 @@ class Gem::RequestSet::Lockfile https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile.rb#L53
 
     @gem_deps_file.untaint unless gem_deps_file.tainted?
 
-    @current_token  = nil
-    @line           = 0
-    @line_pos       = 0
     @platforms      = []
-    @tokens         = []
   end
 
   def add_DEPENDENCIES out # :nodoc:
@@ -80,7 +72,7 @@ class Gem::RequestSet::Lockfile https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile.rb#L72
           [name, requirement_string]
         end
       else
-        @requests.sort_by { |r| r.name }.map do |request|
+        requests.sort_by { |r| r.name }.map do |request|
           spec        = request.spec
           name        = request.name
           requirement = request.request.dependency.requirement
@@ -106,10 +98,10 @@ class Gem::RequestSet::Lockfile https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile.rb#L98
     out << nil
   end
 
-  def add_GEM out # :nodoc:
-    return if @spec_groups.empty?
+  def add_GEM out, spec_groups # :nodoc:
+    return if spec_groups.empty?
 
-    source_groups = @spec_groups.values.flatten.group_by do |request|
+    source_groups = spec_groups.values.flatten.group_by do |request|
       request.spec.source.uri
     end
 
@@ -136,9 +128,8 @@ class Gem::RequestSet::Lockfile https://github.com/ruby/ruby/blob/trunk/lib/rubygems/request_set/lockfile.rb#L128
     end
   end
 
-  def add_GIT out
-    return unless git_requests =
-      @spec_groups.delete(Gem::Resolver::GitSpecification)
+  def add_GIT out, git_requests
+    return if git_requests.empty?
 
     by_repository_revision = git_requests.group_by do |request|
       source = request.spec.source
@@ -179,9 +170,8 @@ class Gem::RequestSet::Lockfile https://github.com/ruby/ruby/blob/trun (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]