bundler-multilock 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|