Class: Bundler::LockfileParser

Inherits:
Object
  • Object
show all
Defined in:
lib/bundler/lockfile_parser.rb

Constant Summary

BUNDLED =
"BUNDLED WITH".freeze
DEPENDENCIES =
"DEPENDENCIES".freeze
PLATFORMS =
"PLATFORMS".freeze
RUBY =
"RUBY VERSION".freeze
GIT =
"GIT".freeze
GEM =
"GEM".freeze
PATH =
"PATH".freeze
PLUGIN =
"PLUGIN SOURCE".freeze
SPECS =
"  specs:".freeze
OPTIONS =
/^  ([a-z]+): (.*)$/i
SOURCE =
[GIT, GEM, PATH, PLUGIN].freeze
SECTIONS_BY_VERSION_INTRODUCED =
{
  # The strings have to be dup'ed for old RG on Ruby 2.3+
  # TODO: remove dup in Bundler 2.0
  Gem::Version.create("1.0".dup) => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
  Gem::Version.create("1.10".dup) => [BUNDLED].freeze,
  Gem::Version.create("1.12".dup) => [RUBY].freeze,
  Gem::Version.create("1.13".dup) => [PLUGIN].freeze,
}.freeze
KNOWN_SECTIONS =
SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze
ENVIRONMENT_VERSION_SECTIONS =
[BUNDLED, RUBY].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lockfile) ⇒ LockfileParser



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/bundler/lockfile_parser.rb', line 62

def initialize(lockfile)
  @platforms    = []
  @sources      = []
  @dependencies = []
  @state        = nil
  @specs        = {}

  @rubygems_aggregate = Source::Rubygems.new

  if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
    raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \
      "Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock."
  end

  lockfile.split(/(?:\r?\n)+/).each do |line|
    if SOURCE.include?(line)
      @state = :source
      parse_source(line)
    elsif line == DEPENDENCIES
      @state = :dependency
    elsif line == PLATFORMS
      @state = :platform
    elsif line == RUBY
      @state = :ruby
    elsif line == BUNDLED
      @state = :bundled_with
    elsif line =~ /^[^\s]/
      @state = nil
    elsif @state
      send("parse_#{@state}", line)
    end
  end
  @sources << @rubygems_aggregate
  @specs = @specs.values
  warn_for_outdated_bundler_version
rescue ArgumentError => e
  Bundler.ui.debug(e)
  raise LockfileError, "Your lockfile is unreadable. Run `rm #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \
    "and then `bundle install` to generate a new lockfile."
end

Instance Attribute Details

#bundler_versionObject (readonly)

Returns the value of attribute bundler_version



16
17
18
# File 'lib/bundler/lockfile_parser.rb', line 16

def bundler_version
  @bundler_version
end

#dependenciesObject (readonly)

Returns the value of attribute dependencies



16
17
18
# File 'lib/bundler/lockfile_parser.rb', line 16

def dependencies
  @dependencies
end

#platformsObject (readonly)

Returns the value of attribute platforms



16
17
18
# File 'lib/bundler/lockfile_parser.rb', line 16

def platforms
  @platforms
end

#ruby_versionObject (readonly)

Returns the value of attribute ruby_version



16
17
18
# File 'lib/bundler/lockfile_parser.rb', line 16

def ruby_version
  @ruby_version
end

#sourcesObject (readonly)

Returns the value of attribute sources



16
17
18
# File 'lib/bundler/lockfile_parser.rb', line 16

def sources
  @sources
end

#specsObject (readonly)

Returns the value of attribute specs



16
17
18
# File 'lib/bundler/lockfile_parser.rb', line 16

def specs
  @specs
end

Class Method Details

.sections_in_lockfile(lockfile_contents) ⇒ Object



43
44
45
# File 'lib/bundler/lockfile_parser.rb', line 43

def self.sections_in_lockfile(lockfile_contents)
  lockfile_contents.scan(/^\w[\w ]*$/).uniq
end

.sections_to_ignore(base_version = nil) ⇒ Object



51
52
53
54
55
56
57
58
59
60
# File 'lib/bundler/lockfile_parser.rb', line 51

def self.sections_to_ignore(base_version = nil)
  base_version &&= base_version.release
  base_version ||= Gem::Version.create("1.0".dup)
  attributes = []
  SECTIONS_BY_VERSION_INTRODUCED.each do |version, introduced|
    next if version <= base_version
    attributes += introduced
  end
  attributes
end

.unknown_sections_in_lockfile(lockfile_contents) ⇒ Object



47
48
49
# File 'lib/bundler/lockfile_parser.rb', line 47

def self.unknown_sections_in_lockfile(lockfile_contents)
  sections_in_lockfile(lockfile_contents) - KNOWN_SECTIONS
end

Instance Method Details

#warn_for_outdated_bundler_versionObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/bundler/lockfile_parser.rb', line 103

def warn_for_outdated_bundler_version
  return unless bundler_version
  prerelease_text = bundler_version.prerelease? ? " --pre" : ""
  current_version = Gem::Version.create(Bundler::VERSION)
  case current_version.segments.first <=> bundler_version.segments.first
  when -1
    raise LockfileError, "You must use Bundler #{bundler_version.segments.first} or greater with this lockfile."
  when 0
    if current_version < bundler_version
      Bundler.ui.warn "Warning: the running version of Bundler (#{current_version}) is older " \
           "than the version that created the lockfile (#{bundler_version}). We suggest you " \
           "upgrade to the latest version of Bundler by running `gem " \
           "install bundler#{prerelease_text}`.\n"
    end
  end
end