diff options
Diffstat (limited to 'ruby_2_2/lib/rubygems/request_set/lockfile.rb')
-rw-r--r-- | ruby_2_2/lib/rubygems/request_set/lockfile.rb | 650 |
1 files changed, 0 insertions, 650 deletions
diff --git a/ruby_2_2/lib/rubygems/request_set/lockfile.rb b/ruby_2_2/lib/rubygems/request_set/lockfile.rb deleted file mode 100644 index 4f2fa0933f..0000000000 --- a/ruby_2_2/lib/rubygems/request_set/lockfile.rb +++ /dev/null @@ -1,650 +0,0 @@ -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 - - class ParseError < Gem::Exception - - ## - # The column where the error was encountered - - attr_reader :column - - ## - # The line where the error was encountered - - attr_reader :line - - ## - # The location of the lock file - - attr_reader :path - - ## - # Raises a ParseError with the given +message+ which was encountered at a - # +line+ and +column+ while parsing. - - def initialize message, column, line, path - @line = line - @column = column - @path = path - super "#{message} (at line #{line} column #{column})" - end - - end - - ## - # The platforms for this Lockfile - - attr_reader :platforms - - ## - # Creates a new Lockfile for the given +request_set+ and +gem_deps_file+ - # location. - - def initialize request_set, gem_deps_file, dependencies = nil - @set = request_set - @dependencies = dependencies - @gem_deps_file = File.expand_path(gem_deps_file) - @gem_deps_dir = File.dirname(@gem_deps_file) - - @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: - out << "DEPENDENCIES" - - dependencies = - if @dependencies then - @dependencies.sort_by { |name,| name }.map do |name, requirement| - requirement_string = - if '!' == requirement then - requirement - else - Gem::Requirement.new(requirement).for_lockfile - end - - [name, requirement_string] - end - else - @requests.sort_by { |r| r.name }.map do |request| - spec = request.spec - name = request.name - requirement = request.request.dependency.requirement - - requirement_string = - if [Gem::Resolver::VendorSpecification, - Gem::Resolver::GitSpecification].include? spec.class then - "!" - else - requirement.for_lockfile - end - - [name, requirement_string] - end - end - - dependencies = dependencies.map do |name, requirement_string| - " #{name}#{requirement_string}" - end - - out.concat dependencies - - out << nil - end - - def add_GEM out # :nodoc: - return if @spec_groups.empty? - - source_groups = @spec_groups.values.flatten.group_by do |request| - request.spec.source.uri - end - - source_groups.sort_by { |group,| group.to_s }.map do |group, requests| - out << "GEM" - out << " remote: #{group}" - out << " specs:" - - requests.sort_by { |request| request.name }.each do |request| - next if request.spec.name == 'bundler' - platform = "-#{request.spec.platform}" unless - Gem::Platform::RUBY == request.spec.platform - - out << " #{request.name} (#{request.version}#{platform})" - - request.full_spec.dependencies.sort.each do |dependency| - next if dependency.type == :development - - requirement = dependency.requirement - out << " #{dependency.name}#{requirement.for_lockfile}" - end - end - out << nil - end - end - - def add_GIT out - return unless git_requests = - @spec_groups.delete(Gem::Resolver::GitSpecification) - - by_repository_revision = git_requests.group_by do |request| - source = request.spec.source - [source.repository, source.rev_parse] - end - - out << "GIT" - by_repository_revision.each do |(repository, revision), requests| - out << " remote: #{repository}" - out << " revision: #{revision}" - out << " specs:" - - requests.sort_by { |request| request.name }.each do |request| - out << " #{request.name} (#{request.version})" - - dependencies = request.spec.dependencies.sort_by { |dep| dep.name } - dependencies.each do |dep| - out << " #{dep.name}#{dep.requirement.for_lockfile}" - end - end - end - - out << nil - end - - def relative_path_from dest, base # :nodoc: - dest = File.expand_path(dest) - base = File.expand_path(base) - - if dest.index(base) == 0 then - offset = dest[base.size+1..-1] - - return '.' unless offset - - offset - else - dest - end - end - - def add_PATH out # :nodoc: - return unless path_requests = - @spec_groups.delete(Gem::Resolver::VendorSpecification) - - out << "PATH" - path_requests.each do |request| - directory = File.expand_path(request.spec.source.uri) - - out << " remote: #{relative_path_from directory, @gem_deps_dir}" - out << " specs:" - out << " #{request.name} (#{request.version})" - end - - out << nil - end - - def add_PLATFORMS out # :nodoc: - out << "PLATFORMS" - - platforms = @requests.map { |request| request.spec.platform }.uniq - - platforms = platforms.sort_by { |platform| platform.to_s } - - platforms.sort.each do |platform| - out << " #{platform}" - end - - out << nil - 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 - - message = "unexpected token [#{type.inspect}, #{value.inspect}], " + - "expected #{expected_types.inspect}" - - raise ParseError.new message, column, line, "#{@gem_deps_file}.lock" - end - - if expected_value and expected_value != value then - unget - - message = "unexpected token [#{type.inspect}, #{value.inspect}], " + - "expected [#{expected_types.inspect}, " + - "#{expected_value.inspect}]" - - raise ParseError.new message, column, line, "#{@gem_deps_file}.lock" - end - - @current_token - end - - def parse # :nodoc: - tokenize - - until @tokens.empty? do - type, data, column, line = get - - case type - when :section then - 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 - - 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 - - ## - # Peeks at the next token for Lockfile - - def peek # :nodoc: - @tokens.first || [:EOF] - 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 - - def skip type # :nodoc: - get while not @tokens.empty? and peek.first == type - end - - ## - # The contents of the lock file. - - def to_s - @set.resolve - - out = [] - - @requests = @set.sorted_requests - - @spec_groups = @requests.group_by do |request| - request.spec.class - end - - add_PATH out - - add_GIT out - - add_GEM out - - add_PLATFORMS out - - add_DEPENDENCIES out - - out.join "\n" - 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 - - ## - # Converts a lock file into an Array of tokens. If the lock file is missing - # an empty Array is returned. - - def tokenize # :nodoc: - @line = 0 - @line_pos = 0 - - @platforms = [] - @tokens = [] - @current_token = nil - - lock_file = "#{@gem_deps_file}.lock" - - @input = File.read lock_file - 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 #{lock_file} contains merge conflict markers" - column, line = token_pos pos - - raise ParseError.new message, column, line, lock_file - 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 - rescue Errno::ENOENT - @tokens - end - - ## - # Ungets the last token retrieved by #get - - def unget # :nodoc: - @tokens.unshift @current_token - end - - ## - # Writes the lock file alongside the gem dependencies file - - def write - content = to_s - - open "#{@gem_deps_file}.lock", 'w' do |io| - io.write content - end - end - -end - |