bundler-multilock 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bundler/multilock/check.rb +33 -35
- data/lib/bundler/multilock/version.rb +1 -1
- data/lib/bundler/multilock.rb +21 -23
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c84016021b1c7595a4e796a80de94d7df2160f016c4bdc286f1616c61bb09170
|
4
|
+
data.tar.gz: 8b8ed6c345db6beb1fdf681e603ffee395d39459fc5a81982f1457876bea4037
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4eb1334a6a9860cea9fbb7ece25741bc35f9dd3e44ab6a17bbf041998116445acf53173a7372f6c1f19dedf1538f1bccc0db859123493b5addae86d134f81146
|
7
|
+
data.tar.gz: 6bc840a4f41344443609f00447e87c95a89eab942446b5dd2598e55bcd15a79a7fcdb3952a4e417ce7664e50316073defdb627bba2da1b886323c0d92292d345
|
@@ -58,7 +58,7 @@ module Bundler
|
|
58
58
|
|
59
59
|
# this is mostly equivalent to the built in checks in `bundle check`, but even
|
60
60
|
# more conservative, and returns false instead of exiting on failure
|
61
|
-
def base_check(lockfile_definition, log_missing: false, return_missing: false)
|
61
|
+
def base_check(lockfile_definition, log_missing: false, return_missing: false, check_missing_deps: false)
|
62
62
|
return return_missing ? [] : false unless lockfile_definition[:lockfile].file?
|
63
63
|
|
64
64
|
Multilock.prepare_block = lockfile_definition[:prepare]
|
@@ -83,14 +83,17 @@ module Bundler
|
|
83
83
|
|
84
84
|
return not_installed if return_missing
|
85
85
|
|
86
|
-
not_installed.empty? && definition.no_resolve_needed?
|
86
|
+
return false unless not_installed.empty? && definition.no_resolve_needed?
|
87
|
+
return true unless check_missing_deps
|
88
|
+
|
89
|
+
(definition.locked_gems.dependencies.values - definition.dependencies).empty?
|
87
90
|
ensure
|
88
91
|
Multilock.prepare_block = nil
|
89
92
|
end
|
90
93
|
|
91
94
|
# this checks for mismatches between the parent lockfile and the given lockfile,
|
92
95
|
# and for pinned dependencies in lockfiles requiring them
|
93
|
-
def check(lockfile_definition
|
96
|
+
def check(lockfile_definition)
|
94
97
|
success = true
|
95
98
|
proven_pinned = Set.new
|
96
99
|
needs_pin_check = []
|
@@ -109,36 +112,8 @@ module Bundler
|
|
109
112
|
success = false
|
110
113
|
end
|
111
114
|
|
112
|
-
|
113
|
-
|
114
|
-
allow_mismatched_dependencies = lockfile_definition[:allow_mismatched_dependencies]
|
115
|
-
end
|
116
|
-
|
117
|
-
# build list of top-level dependencies that differ from the parent lockfile,
|
118
|
-
# and all _their_ transitive dependencies
|
119
|
-
if allow_mismatched_dependencies
|
120
|
-
transitive_dependencies = Set.new
|
121
|
-
# only dependencies that differ from the parent lockfile
|
122
|
-
pending_transitive_dependencies = lockfile.dependencies.reject do |name, dep|
|
123
|
-
parent_lockfile.dependencies[name] == dep
|
124
|
-
end.map(&:first)
|
125
|
-
|
126
|
-
until pending_transitive_dependencies.empty?
|
127
|
-
dep = pending_transitive_dependencies.shift
|
128
|
-
next if transitive_dependencies.include?(dep)
|
129
|
-
|
130
|
-
transitive_dependencies << dep
|
131
|
-
platform_specs = specs[dep]
|
132
|
-
unless platform_specs
|
133
|
-
# should only be bundler that's missing a spec
|
134
|
-
raise "Could not find spec for dependency #{dep}" unless dep == "bundler"
|
135
|
-
|
136
|
-
next
|
137
|
-
end
|
138
|
-
|
139
|
-
pending_transitive_dependencies.concat(platform_specs.flat_map(&:dependencies).map(&:name).uniq)
|
140
|
-
end
|
141
|
-
end
|
115
|
+
reverse_dependencies = cache_reverse_dependencies(lockfile)
|
116
|
+
parent_reverse_dependencies = cache_reverse_dependencies(parent_lockfile)
|
142
117
|
|
143
118
|
# look through top-level explicit dependencies for pinned requirements
|
144
119
|
if lockfile_definition[:enforce_pinned_additional_dependencies]
|
@@ -146,7 +121,7 @@ module Bundler
|
|
146
121
|
end
|
147
122
|
|
148
123
|
# check for conflicting requirements (and build list of pins, in the same loop)
|
149
|
-
specs.
|
124
|
+
lockfile.specs.each do |spec|
|
150
125
|
parent_spec = lockfile_specs[parent][[spec.name, spec.platform]]
|
151
126
|
|
152
127
|
if lockfile_definition[:enforce_pinned_additional_dependencies]
|
@@ -170,7 +145,15 @@ module Bundler
|
|
170
145
|
end
|
171
146
|
|
172
147
|
next if parent_spec.version == spec.version && same_source
|
173
|
-
|
148
|
+
|
149
|
+
# the version in the parent lockfile cannot possibly satisfy the requirements
|
150
|
+
# in this lockfile, and vice versa, so we assume it's intentional and allow it
|
151
|
+
unless reverse_dependencies[spec.name].satisfied_by?(parent_spec.version) ||
|
152
|
+
parent_reverse_dependencies[spec.name].satisfied_by?(spec.version)
|
153
|
+
# we're allowing it to differ from the parent, so pin check requirement comes into play
|
154
|
+
needs_pin_check << spec if lockfile_definition[:enforce_pinned_additional_dependencies]
|
155
|
+
next
|
156
|
+
end
|
174
157
|
|
175
158
|
Bundler.ui.error("#{spec}#{spec.git_version} in #{lockfile_path} " \
|
176
159
|
"does not match the parent lockfile's version " \
|
@@ -206,6 +189,21 @@ module Bundler
|
|
206
189
|
|
207
190
|
private
|
208
191
|
|
192
|
+
def cache_reverse_dependencies(lockfile)
|
193
|
+
reverse_dependencies = Hash.new { |h, k| h[k] = Gem::Requirement.default_prerelease }
|
194
|
+
|
195
|
+
lockfile.dependencies.each_value do |spec|
|
196
|
+
reverse_dependencies[spec.name].requirements.concat(spec.requirement.requirements)
|
197
|
+
end
|
198
|
+
lockfile.specs.each do |spec|
|
199
|
+
spec.dependencies.each do |dependency|
|
200
|
+
reverse_dependencies[dependency.name].requirements.concat(dependency.requirement.requirements)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
reverse_dependencies
|
205
|
+
end
|
206
|
+
|
209
207
|
def find_pinned_dependencies(proven_pinned, dependencies)
|
210
208
|
dependencies.each do |dependency|
|
211
209
|
dependency.requirement.requirements.each do |requirement|
|
data/lib/bundler/multilock.rb
CHANGED
@@ -27,11 +27,6 @@ module Bundler
|
|
27
27
|
# BUNDLE_LOCKFILE will still override a lockfile tagged as active
|
28
28
|
# @param parent [String] The parent lockfile to sync dependencies from.
|
29
29
|
# Also used for comparing enforce_pinned_additional_dependencies against.
|
30
|
-
# @param allow_mismatched_dependencies [true, false]
|
31
|
-
# Allows version differences in dependencies between this lockfile and
|
32
|
-
# the default lockfile. Note that even with this option, only top-level
|
33
|
-
# dependencies that differ from the default lockfile, and their transitive
|
34
|
-
# depedencies, are allowed to mismatch.
|
35
30
|
# @param enforce_pinned_additional_dependencies [true, false]
|
36
31
|
# If dependencies are present in this lockfile that are not present in the
|
37
32
|
# default lockfile, enforce that they are pinned.
|
@@ -44,12 +39,15 @@ module Bundler
|
|
44
39
|
active: nil,
|
45
40
|
default: nil,
|
46
41
|
parent: nil,
|
47
|
-
allow_mismatched_dependencies:
|
42
|
+
allow_mismatched_dependencies: nil,
|
48
43
|
enforce_pinned_additional_dependencies: false,
|
49
44
|
&block)
|
50
45
|
# backcompat
|
51
46
|
active = default if active.nil?
|
52
47
|
Bundler.ui.warn("lockfile(default:) is deprecated. Use lockfile(active:) instead.") if default
|
48
|
+
unless allow_mismatched_dependencies.nil?
|
49
|
+
Bundler.ui.warn("lockfile(allow_mismatched_dependencies:) is deprecated.")
|
50
|
+
end
|
53
51
|
|
54
52
|
active = true if active.nil? && lockfile_definitions.empty? && lockfile.nil? && gemfile.nil?
|
55
53
|
|
@@ -62,14 +60,8 @@ module Bundler
|
|
62
60
|
raise ArgumentError, "Lockfile #{lockfile} is already defined"
|
63
61
|
end
|
64
62
|
|
65
|
-
env_lockfile = ENV["BUNDLE_LOCKFILE"]
|
66
|
-
if env_lockfile
|
67
|
-
unless env_lockfile.include?("/") || env_lockfile.end_with?(".lock")
|
68
|
-
env_lockfile = "Gemfile.#{env_lockfile}.lock"
|
69
|
-
end
|
70
|
-
env_lockfile = Bundler.root.join(env_lockfile).expand_path
|
71
|
-
active = env_lockfile == lockfile
|
72
|
-
end
|
63
|
+
env_lockfile = ENV["BUNDLE_LOCKFILE"]&.then { |l| expand_lockfile(l) }
|
64
|
+
active = env_lockfile == lockfile if env_lockfile
|
73
65
|
|
74
66
|
if active && (old_active = lockfile_definitions.find { |definition| definition[:active] })
|
75
67
|
raise ArgumentError, "Only one lockfile (#{old_active[:lockfile]}) can be flagged as the default"
|
@@ -87,7 +79,6 @@ module Bundler
|
|
87
79
|
active: active,
|
88
80
|
prepare: block,
|
89
81
|
parent: parent,
|
90
|
-
allow_mismatched_dependencies: allow_mismatched_dependencies,
|
91
82
|
enforce_pinned_additional_dependencies: enforce_pinned_additional_dependencies
|
92
83
|
})
|
93
84
|
|
@@ -155,7 +146,6 @@ module Bundler
|
|
155
146
|
require_relative "multilock/lockfile_generator"
|
156
147
|
|
157
148
|
Bundler.ui.debug("Syncing to alternate lockfiles")
|
158
|
-
Bundler.ui.info ""
|
159
149
|
|
160
150
|
attempts = 1
|
161
151
|
|
@@ -177,8 +167,8 @@ module Bundler
|
|
177
167
|
up_to_date = false
|
178
168
|
Bundler.settings.temporary(frozen: true) do
|
179
169
|
Bundler.ui.silence do
|
180
|
-
up_to_date = checker.base_check(lockfile_definition) &&
|
181
|
-
checker.check(lockfile_definition
|
170
|
+
up_to_date = checker.base_check(lockfile_definition, check_missing_deps: true) &&
|
171
|
+
checker.check(lockfile_definition)
|
182
172
|
end
|
183
173
|
end
|
184
174
|
if up_to_date
|
@@ -310,16 +300,17 @@ module Bundler
|
|
310
300
|
|
311
301
|
return unless lockfile_definitions.none? { |definition| definition[:active] }
|
312
302
|
|
313
|
-
|
314
|
-
|
315
|
-
definition[:lockfile] == Bundler.default_lockfile(force_original: true)
|
316
|
-
end
|
317
|
-
if ENV["BUNDLE_LOCKFILE"] == Bundler.default_lockfile(force_original: true) && default_lockfile_definition
|
303
|
+
if ENV["BUNDLE_LOCKFILE"]&.then { |l| expand_lockfile(l) } ==
|
304
|
+
Bundler.default_lockfile(force_original: true)
|
318
305
|
return
|
319
306
|
end
|
320
307
|
|
321
308
|
raise GemfileNotFound, "Could not locate lockfile #{ENV["BUNDLE_LOCKFILE"].inspect}" if ENV["BUNDLE_LOCKFILE"]
|
322
309
|
|
310
|
+
# Gemfile.lock isn't explicitly specified, otherwise it would be active
|
311
|
+
default_lockfile_definition = lockfile_definitions.find do |definition|
|
312
|
+
definition[:lockfile] == Bundler.default_lockfile(force_original: true)
|
313
|
+
end
|
323
314
|
return unless default_lockfile_definition && default_lockfile_definition[:active] == false
|
324
315
|
|
325
316
|
raise GemfileEvalError, "No lockfiles marked as default"
|
@@ -431,9 +422,16 @@ module Bundler
|
|
431
422
|
|
432
423
|
orig_definition = definition.dup # we might need it twice
|
433
424
|
|
425
|
+
# install gems for the exact current version of the lockfile
|
426
|
+
# this ensures it doesn't re-resolve with only (different)
|
427
|
+
# local gems after you've pulled down an update to the lockfile
|
428
|
+
# from someone else
|
434
429
|
if current_lockfile.exist? && install
|
435
430
|
Bundler.settings.temporary(frozen: true) do
|
436
431
|
current_definition = builder.to_definition(current_lockfile, {})
|
432
|
+
# if something has changed, we skip this step; it's unlocking anyway
|
433
|
+
next unless current_definition.no_resolve_needed?
|
434
|
+
|
437
435
|
current_definition.resolve_with_cache!
|
438
436
|
if current_definition.missing_specs.any?
|
439
437
|
Bundler.with_default_lockfile(current_lockfile) do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundler-multilock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Instructure
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|