Class: Gem::RequestSet::Lockfile

Inherits:
Object
  • Object
show all
Defined in:
lib/rubygems/request_set/lockfile.rb

Overview

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.

Defined Under Namespace

Classes: ParseError, Parser, Tokenizer

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request_set, gem_deps_file, dependencies) ⇒ Lockfile

Returns a new instance of Lockfile.


76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rubygems/request_set/lockfile.rb', line 76

def initialize(request_set, gem_deps_file, dependencies)
  @set           = request_set
  @dependencies  = dependencies
  @gem_deps_file = File.expand_path(gem_deps_file)
  @gem_deps_dir  = File.dirname(@gem_deps_file)

  if RUBY_VERSION < '2.7'
    @gem_deps_file.untaint unless gem_deps_file.tainted?
  end

  @platforms = []
end

Instance Attribute Details

#platformsObject (readonly)

The platforms for this Lockfile


74
75
76
# File 'lib/rubygems/request_set/lockfile.rb', line 74

def platforms
  @platforms
end

Class Method Details

.build(request_set, gem_deps_file, dependencies = nil) ⇒ Object

Creates a new Lockfile for the given request_set and gem_deps_file location.


46
47
48
49
50
# File 'lib/rubygems/request_set/lockfile.rb', line 46

def self.build(request_set, gem_deps_file, dependencies = nil)
  request_set.resolve
  dependencies ||= requests_to_deps request_set.sorted_requests
  new request_set, gem_deps_file, dependencies
end

.requests_to_deps(requests) ⇒ Object

:nodoc:


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/rubygems/request_set/lockfile.rb', line 52

def self.requests_to_deps(requests) # :nodoc:
  deps = {}

  requests.each do |request|
    spec        = request.spec
    name        = request.name
    requirement = request.request.dependency.requirement

    deps[name] = if [Gem::Resolver::VendorSpecification,
                     Gem::Resolver::GitSpecification].include? spec.class
                   Gem::Requirement.source_set
                 else
                   requirement
                 end
  end

  deps
end

Instance Method Details

#add_DEPENDENCIES(out) ⇒ Object

:nodoc:


89
90
91
92
93
94
95
96
97
# File 'lib/rubygems/request_set/lockfile.rb', line 89

def add_DEPENDENCIES(out) # :nodoc:
  out << "DEPENDENCIES"

  out.concat @dependencies.sort_by { |name,| name }.map { |name, requirement|
    "  #{name}#{requirement.for_lockfile}"
  }

  out << nil
end

#add_GEM(out, spec_groups) ⇒ Object

:nodoc:


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/rubygems/request_set/lockfile.rb', line 99

def add_GEM(out, spec_groups) # :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

#add_GIT(out, git_requests) ⇒ Object


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rubygems/request_set/lockfile.rb', line 129

def add_GIT(out, git_requests)
  return if git_requests.empty?

  by_repository_revision = git_requests.group_by do |request|
    source = request.spec.source
    [source.repository, source.rev_parse]
  end

  by_repository_revision.each do |(repository, revision), requests|
    out << "GIT"
    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
    out << nil
  end
end

#add_PATH(out, path_requests) ⇒ Object

:nodoc:


170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/rubygems/request_set/lockfile.rb', line 170

def add_PATH(out, path_requests) # :nodoc:
  return if path_requests.empty?

  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

#add_PLATFORMS(out) ⇒ Object

:nodoc:


185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/rubygems/request_set/lockfile.rb', line 185

def add_PLATFORMS(out) # :nodoc:
  out << "PLATFORMS"

  platforms = requests.map { |request| request.spec.platform }.uniq

  platforms = platforms.sort_by { |platform| platform.to_s }

  platforms.each do |platform|
    out << "  #{platform}"
  end

  out << nil
end

#relative_path_from(dest, base) ⇒ Object

:nodoc:


155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/rubygems/request_set/lockfile.rb', line 155

def relative_path_from(dest, base) # :nodoc:
  dest = File.expand_path(dest)
  base = File.expand_path(base)

  if dest.index(base) == 0
    offset = dest[base.size + 1..-1]

    return '.' unless offset

    offset
  else
    dest
  end
end

#spec_groupsObject


199
200
201
# File 'lib/rubygems/request_set/lockfile.rb', line 199

def spec_groups
  requests.group_by { |request| request.spec.class }
end

#to_sObject

The contents of the lock file.


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/rubygems/request_set/lockfile.rb', line 206

def to_s
  out = []

  groups = spec_groups

  add_PATH out, groups.delete(Gem::Resolver::VendorSpecification) { [] }

  add_GIT out, groups.delete(Gem::Resolver::GitSpecification) { [] }

  add_GEM out, groups

  add_PLATFORMS out

  add_DEPENDENCIES out

  out.join "\n"
end

#writeObject

Writes the lock file alongside the gem dependencies file


227
228
229
230
231
232
233
# File 'lib/rubygems/request_set/lockfile.rb', line 227

def write
  content = to_s

  File.open "#{@gem_deps_file}.lock", 'w' do |io|
    io.write content
  end
end