dependabot-bundler 0.152.1 → 0.154.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/helpers/v1/build +1 -1
- data/helpers/v1/lib/functions.rb +2 -2
- data/helpers/v1/lib/functions/dependency_source.rb +3 -1
- data/helpers/v1/lib/functions/file_parser.rb +5 -7
- data/helpers/v1/lib/functions/force_updater.rb +2 -0
- data/helpers/v1/lib/functions/lockfile_updater.rb +13 -11
- data/helpers/v1/lib/functions/version_resolver.rb +5 -7
- data/helpers/v1/monkey_patches/git_source_patch.rb +1 -3
- data/helpers/v1/run.rb +3 -3
- data/helpers/v1/spec/functions/dependency_source_spec.rb +8 -8
- data/helpers/v1/spec/functions/file_parser_spec.rb +5 -8
- data/helpers/v1/spec/functions/force_updater_spec.rb +58 -0
- data/helpers/v1/spec/functions/version_resolver_spec.rb +8 -0
- data/helpers/v1/spec/native_spec_helper.rb +1 -3
- data/helpers/v2/build +1 -1
- data/helpers/v2/lib/functions.rb +0 -2
- data/helpers/v2/lib/functions/dependency_source.rb +3 -1
- data/helpers/v2/lib/functions/file_parser.rb +5 -7
- data/helpers/v2/lib/functions/force_updater.rb +2 -0
- data/helpers/v2/lib/functions/lockfile_updater.rb +6 -3
- data/helpers/v2/lib/functions/version_resolver.rb +5 -7
- data/helpers/v2/monkey_patches/git_source_patch.rb +1 -3
- data/helpers/v2/run.rb +4 -2
- data/helpers/v2/spec/functions/dependency_source_spec.rb +8 -8
- data/helpers/v2/spec/functions/file_parser_spec.rb +12 -15
- data/helpers/v2/spec/functions/force_updater_spec.rb +58 -0
- data/helpers/v2/spec/functions/version_resolver_spec.rb +8 -0
- data/helpers/v2/spec/functions_spec.rb +1 -1
- data/helpers/v2/spec/native_spec_helper.rb +2 -5
- data/lib/dependabot/bundler/file_updater/ruby_requirement_setter.rb +3 -3
- data/lib/dependabot/bundler/native_helpers.rb +1 -2
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3018dfbdcf3fea39c0b5fc045057bd6ed3a8ac737ae6b6d401b9167d25fcb4d6
|
4
|
+
data.tar.gz: '016299a100e9fd8508f771c8681531aa7f1eaf04ed2596ad47cef8727fc3dc10'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e9774e9bc9d5ca0c6a24108ba31719183018f4922ba2d33d0b0156284023e3059afb58c7985ea470d3038544dbb127f5d759615d0fa4c5eebd4080fb5b64dcb
|
7
|
+
data.tar.gz: ebc2bab0725f9c4194ac8db332d1ab53ba3e1abb44b062d5bfc28e797cf0bab146f7f0383fe91b23c7198d01545aa34b026f545d4823917b9d570a5bb876dcf9
|
data/helpers/v1/build
CHANGED
@@ -20,6 +20,6 @@ cd "$install_dir"
|
|
20
20
|
|
21
21
|
# NOTE: Sets `BUNDLED WITH` to match the installed v1 version in Gemfile.lock
|
22
22
|
# forcing native helpers to run with the same version
|
23
|
-
BUNDLER_VERSION=
|
23
|
+
BUNDLER_VERSION=1 bundle config set --local path ".bundle"
|
24
24
|
BUNDLER_VERSION=1 bundle config set --local without "test"
|
25
25
|
BUNDLER_VERSION=1 bundle install
|
data/helpers/v1/lib/functions.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "functions/file_parser"
|
2
4
|
require "functions/force_updater"
|
3
5
|
require "functions/lockfile_updater"
|
@@ -124,8 +126,6 @@ module Functions
|
|
124
126
|
).conflicting_dependencies
|
125
127
|
end
|
126
128
|
|
127
|
-
private
|
128
|
-
|
129
129
|
def self.set_bundler_flags_and_credentials(dir:, credentials:)
|
130
130
|
dir = dir ? Pathname.new(dir) : dir
|
131
131
|
Bundler.instance_variable_set(:@root, dir)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Functions
|
2
4
|
class DependencySource
|
3
5
|
attr_reader :gemfile_name, :dependency_name
|
@@ -66,7 +68,7 @@ module Functions
|
|
66
68
|
return @specified_source if defined? @specified_source
|
67
69
|
|
68
70
|
@specified_source = definition.dependencies.
|
69
|
-
|
71
|
+
find { |dep| dep.name == dependency_name }&.source
|
70
72
|
end
|
71
73
|
|
72
74
|
def default_source
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Functions
|
2
4
|
class FileParser
|
3
5
|
def initialize(lockfile_name:)
|
@@ -39,7 +41,7 @@ module Functions
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def source_from_lockfile(dependency_name)
|
42
|
-
parsed_lockfile&.specs
|
44
|
+
parsed_lockfile&.specs&.find { |s| s.name == dependency_name }&.source
|
43
45
|
end
|
44
46
|
|
45
47
|
def source_for(dependency)
|
@@ -54,12 +56,8 @@ module Functions
|
|
54
56
|
return nil if default_rubygems?(source)
|
55
57
|
|
56
58
|
details = { type: source.class.name.split("::").last.downcase }
|
57
|
-
if source.is_a?(Bundler::Source::Git)
|
58
|
-
|
59
|
-
end
|
60
|
-
if source.is_a?(Bundler::Source::Rubygems)
|
61
|
-
details[:url] = source.remotes.first.to_s
|
62
|
-
end
|
59
|
+
details.merge!(git_source_details(source)) if source.is_a?(Bundler::Source::Git)
|
60
|
+
details[:url] = source.remotes.first.to_s if source.is_a?(Bundler::Source::Rubygems)
|
63
61
|
details
|
64
62
|
end
|
65
63
|
|
@@ -1,12 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
1
5
|
module Functions
|
2
6
|
class LockfileUpdater
|
3
7
|
RETRYABLE_ERRORS = [Bundler::HTTPError].freeze
|
4
8
|
GEM_NOT_FOUND_ERROR_REGEX =
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
/
|
10
|
+
locked\sto\s(?<name>[^\s]+)\s\(|
|
11
|
+
not\sfind\s(?<name>[^\s]+)-\d|
|
12
|
+
has\s(?<name>[^\s]+)\slocked\sat
|
13
|
+
/x.freeze
|
10
14
|
|
11
15
|
def initialize(gemfile_name:, lockfile_name:, dependencies:)
|
12
16
|
@gemfile_name = gemfile_name
|
@@ -22,7 +26,7 @@ module Functions
|
|
22
26
|
|
23
27
|
attr_reader :gemfile_name, :lockfile_name, :dependencies
|
24
28
|
|
25
|
-
def generate_lockfile
|
29
|
+
def generate_lockfile # rubocop:disable Metrics/PerceivedComplexity
|
26
30
|
dependencies_to_unlock = dependencies.map { |d| d.fetch("name") }
|
27
31
|
|
28
32
|
begin
|
@@ -135,7 +139,7 @@ module Functions
|
|
135
139
|
raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX)
|
136
140
|
|
137
141
|
gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX).
|
138
|
-
|
142
|
+
named_captures["name"]
|
139
143
|
raise if dependencies_to_unlock.include?(gem_name)
|
140
144
|
|
141
145
|
dependencies_to_unlock << gem_name
|
@@ -161,9 +165,7 @@ module Functions
|
|
161
165
|
end.compact.map(&:name)
|
162
166
|
|
163
167
|
# If there are specific dependencies we can unlock, unlock them
|
164
|
-
if potentials_deps.any?
|
165
|
-
return dependencies_to_unlock.append(*potentials_deps)
|
166
|
-
end
|
168
|
+
return dependencies_to_unlock.append(*potentials_deps) if potentials_deps.any?
|
167
169
|
|
168
170
|
# Fall back to unlocking *all* sub-dependencies. This is required
|
169
171
|
# because Bundler's VersionConflict objects don't include enough
|
@@ -205,7 +207,7 @@ module Functions
|
|
205
207
|
defn_dep.source.is_a?(Bundler::Source::Git)
|
206
208
|
defn_dep.source.unlock!
|
207
209
|
elsif Gem::Version.correct?(dep.fetch("version"))
|
208
|
-
new_req = Gem::Requirement.create("= #{dep.fetch(
|
210
|
+
new_req = Gem::Requirement.create("= #{dep.fetch('version')}")
|
209
211
|
old_reqs[dep.fetch("name")] = defn_dep.requirement
|
210
212
|
defn_dep.instance_variable_set(:@requirement, new_req)
|
211
213
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Functions
|
2
4
|
class VersionResolver
|
3
5
|
GEM_NOT_FOUND_ERROR_REGEX = /locked to (?<name>[^\s]+) \(/.freeze
|
@@ -20,9 +22,7 @@ module Functions
|
|
20
22
|
# included in a gemspec, it's because the Gemfile didn't import
|
21
23
|
# the gemspec. This is unusual, but the correct behaviour if/when
|
22
24
|
# it happens is to behave as if the repo was gemspec-only.
|
23
|
-
if dep.nil? && dependency_requirements.any?
|
24
|
-
return "latest"
|
25
|
-
end
|
25
|
+
return "latest" if dep.nil? && dependency_requirements.any?
|
26
26
|
|
27
27
|
# Otherwise, if the dependency wasn't found it's because it is a
|
28
28
|
# subdependency that was removed when attempting to update it.
|
@@ -38,9 +38,7 @@ module Functions
|
|
38
38
|
ruby_version: ruby_version,
|
39
39
|
fetcher: fetcher_class(dep)
|
40
40
|
}
|
41
|
-
if dep.source.instance_of?(::Bundler::Source::Git)
|
42
|
-
details[:commit_sha] = dep.source.revision
|
43
|
-
end
|
41
|
+
details[:commit_sha] = dep.source.revision if dep.source.instance_of?(::Bundler::Source::Git)
|
44
42
|
details
|
45
43
|
end
|
46
44
|
|
@@ -92,7 +90,7 @@ module Functions
|
|
92
90
|
end
|
93
91
|
|
94
92
|
def build_definition(dependencies_to_unlock)
|
95
|
-
#
|
93
|
+
# NOTE: we lock shared dependencies to avoid any top-level
|
96
94
|
# dependencies getting unlocked (which would happen if they were
|
97
95
|
# also subdependencies of the dependency being unlocked)
|
98
96
|
::Bundler::Definition.build(
|
@@ -41,9 +41,7 @@ module Bundler
|
|
41
41
|
$LOAD_PATH.shift until $LOAD_PATH.empty?
|
42
42
|
reduced_load_paths.each { |p| $LOAD_PATH << p }
|
43
43
|
|
44
|
-
if destination.relative?
|
45
|
-
destination = destination.expand_path(Bundler.root)
|
46
|
-
end
|
44
|
+
destination = destination.expand_path(Bundler.root) if destination.relative?
|
47
45
|
Dir["#{destination}/#{@glob}"].each do |spec_path|
|
48
46
|
# Evaluate gemspecs and cache the result. Gemspecs
|
49
47
|
# in git might require git or other dependencies.
|
data/helpers/v1/run.rb
CHANGED
@@ -13,7 +13,7 @@ require "git_source_patch"
|
|
13
13
|
|
14
14
|
require "functions"
|
15
15
|
|
16
|
-
MAX_BUNDLER_VERSION="2.0.0"
|
16
|
+
MAX_BUNDLER_VERSION = "2.0.0"
|
17
17
|
|
18
18
|
def validate_bundler_version!
|
19
19
|
return true if correct_bundler_version?
|
@@ -38,9 +38,9 @@ begin
|
|
38
38
|
args = request["args"].transform_keys(&:to_sym)
|
39
39
|
|
40
40
|
output({ result: Functions.send(function, **args) })
|
41
|
-
rescue =>
|
41
|
+
rescue StandardError => e
|
42
42
|
output(
|
43
|
-
{ error:
|
43
|
+
{ error: e.message, error_class: e.class, trace: e.backtrace }
|
44
44
|
)
|
45
45
|
exit(1)
|
46
46
|
end
|
@@ -40,10 +40,10 @@ RSpec.describe Functions::DependencySource do
|
|
40
40
|
|
41
41
|
it "returns all versions from the private source" do
|
42
42
|
is_expected.to eq([
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
Gem::Version.new("1.5.0"),
|
44
|
+
Gem::Version.new("1.9.0"),
|
45
|
+
Gem::Version.new("1.10.0.beta")
|
46
|
+
])
|
47
47
|
end
|
48
48
|
|
49
49
|
context "specified as the default source" do
|
@@ -51,10 +51,10 @@ RSpec.describe Functions::DependencySource do
|
|
51
51
|
|
52
52
|
it "returns all versions from the private source" do
|
53
53
|
is_expected.to eq([
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
Gem::Version.new("1.5.0"),
|
55
|
+
Gem::Version.new("1.9.0"),
|
56
|
+
Gem::Version.new("1.10.0.beta")
|
57
|
+
])
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -12,9 +12,9 @@ RSpec.describe Functions::FileParser do
|
|
12
12
|
)
|
13
13
|
end
|
14
14
|
|
15
|
-
let(:project_name) { "gemfile" }
|
16
|
-
|
17
15
|
describe "#parsed_gemfile" do
|
16
|
+
let(:project_name) { "gemfile" }
|
17
|
+
|
18
18
|
subject(:parsed_gemfile) do
|
19
19
|
in_tmp_folder do
|
20
20
|
dependency_source.parsed_gemfile(gemfile_name: "Gemfile")
|
@@ -43,14 +43,11 @@ RSpec.describe Functions::FileParser do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
describe "#parsed_gemspec" do
|
46
|
-
let
|
47
|
-
fixture("ruby", "gemspecs", "exact")
|
48
|
-
end
|
46
|
+
let(:project_name) { "gemfile_exact" }
|
49
47
|
|
50
48
|
subject(:parsed_gemspec) do
|
51
|
-
in_tmp_folder do |
|
52
|
-
|
53
|
-
dependency_source.parsed_gemspec(gemspec_name: "test.gemspec")
|
49
|
+
in_tmp_folder do |_tmp_path|
|
50
|
+
dependency_source.parsed_gemspec(gemspec_name: "example.gemspec")
|
54
51
|
end
|
55
52
|
end
|
56
53
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "native_spec_helper"
|
4
|
+
require "shared_contexts"
|
5
|
+
|
6
|
+
RSpec.describe Functions::ForceUpdater do
|
7
|
+
include_context "in a temporary bundler directory"
|
8
|
+
include_context "stub rubygems compact index"
|
9
|
+
|
10
|
+
let(:force_updater) do
|
11
|
+
described_class.new(
|
12
|
+
dependency_name: dependency_name,
|
13
|
+
target_version: target_version,
|
14
|
+
gemfile_name: gemfile_name,
|
15
|
+
lockfile_name: lockfile_name,
|
16
|
+
update_multiple_dependencies: update_multiple_dependencies
|
17
|
+
)
|
18
|
+
end
|
19
|
+
let(:gemfile_name) { "Gemfile" }
|
20
|
+
let(:lockfile_name) { "Gemfile.lock" }
|
21
|
+
let(:update_multiple_dependencies) { true }
|
22
|
+
|
23
|
+
describe "#run" do
|
24
|
+
subject(:force_update) do
|
25
|
+
in_tmp_folder { force_updater.run }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with a version conflict" do
|
29
|
+
let(:target_version) { "3.6.0" }
|
30
|
+
let(:dependency_name) { "rspec-support" }
|
31
|
+
let(:project_name) { "version_conflict" }
|
32
|
+
|
33
|
+
it "updates the conflicting dependencies" do
|
34
|
+
updated_deps, _specs = force_update
|
35
|
+
expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }])
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when updating a single dependency" do
|
39
|
+
let(:update_multiple_dependencies) { false }
|
40
|
+
|
41
|
+
it { expect { force_update }.to raise_error(Bundler::VersionConflict) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with a version conflict in gems rb" do
|
46
|
+
let(:target_version) { "3.6.0" }
|
47
|
+
let(:dependency_name) { "rspec-support" }
|
48
|
+
let(:project_name) { "version_conflict_gems_rb" }
|
49
|
+
let(:gemfile_name) { "gems.rb" }
|
50
|
+
let(:lockfile_name) { "gems.locked" }
|
51
|
+
|
52
|
+
it "updates the conflicting dependencies" do
|
53
|
+
updated_deps, _specs = force_update
|
54
|
+
expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -92,5 +92,13 @@ RSpec.describe Functions::VersionResolver do
|
|
92
92
|
its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) }
|
93
93
|
its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::Dependency") }
|
94
94
|
end
|
95
|
+
|
96
|
+
context "with no update possible due to a version conflict" do
|
97
|
+
let(:project_name) { "version_conflict_with_listed_subdep" }
|
98
|
+
let(:dependency_name) { "rspec-mocks" }
|
99
|
+
let(:requirement_string) { ">= 0" }
|
100
|
+
|
101
|
+
its([:version]) { is_expected.to eq(Gem::Version.new("3.6.0")) }
|
102
|
+
end
|
95
103
|
end
|
96
104
|
end
|
@@ -36,9 +36,7 @@ def project_dependency_files(project)
|
|
36
36
|
files = files.select { |f| File.file?(f) }
|
37
37
|
files.map do |filename|
|
38
38
|
content = File.read(filename)
|
39
|
-
if filename == "Gemfile.lock"
|
40
|
-
content = content.gsub(LOCKFILE_ENDING, "")
|
41
|
-
end
|
39
|
+
content = content.gsub(LOCKFILE_ENDING, "") if filename == "Gemfile.lock"
|
42
40
|
{
|
43
41
|
name: filename,
|
44
42
|
content: content
|
data/helpers/v2/build
CHANGED
@@ -18,7 +18,7 @@ cp -r \
|
|
18
18
|
|
19
19
|
cd "$install_dir"
|
20
20
|
|
21
|
-
# NOTE: Sets `BUNDLED WITH` to match the installed
|
21
|
+
# NOTE: Sets `BUNDLED WITH` to match the installed v2 version in Gemfile.lock
|
22
22
|
# forcing specs and native helpers to run with the same version
|
23
23
|
BUNDLER_VERSION=2 bundle config set --local path ".bundle"
|
24
24
|
BUNDLER_VERSION=2 bundle config set --local without "test"
|
data/helpers/v2/lib/functions.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Functions
|
2
4
|
class DependencySource
|
3
5
|
attr_reader :gemfile_name, :dependency_name
|
@@ -66,7 +68,7 @@ module Functions
|
|
66
68
|
return @specified_source if defined? @specified_source
|
67
69
|
|
68
70
|
@specified_source = definition.dependencies.
|
69
|
-
|
71
|
+
find { |dep| dep.name == dependency_name }&.source
|
70
72
|
end
|
71
73
|
|
72
74
|
def default_source
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Functions
|
2
4
|
class FileParser
|
3
5
|
def initialize(lockfile_name:)
|
@@ -39,7 +41,7 @@ module Functions
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def source_from_lockfile(dependency_name)
|
42
|
-
parsed_lockfile&.specs
|
44
|
+
parsed_lockfile&.specs&.find { |s| s.name == dependency_name }&.source
|
43
45
|
end
|
44
46
|
|
45
47
|
def source_for(dependency)
|
@@ -54,12 +56,8 @@ module Functions
|
|
54
56
|
return nil if default_rubygems?(source)
|
55
57
|
|
56
58
|
details = { type: source.class.name.split("::").last.downcase }
|
57
|
-
if source.is_a?(Bundler::Source::Git)
|
58
|
-
|
59
|
-
end
|
60
|
-
if source.is_a?(Bundler::Source::Rubygems)
|
61
|
-
details[:url] = source.remotes.first.to_s
|
62
|
-
end
|
59
|
+
details.merge!(git_source_details(source)) if source.is_a?(Bundler::Source::Git)
|
60
|
+
details[:url] = source.remotes.first.to_s if source.is_a?(Bundler::Source::Rubygems)
|
63
61
|
details
|
64
62
|
end
|
65
63
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "fileutils"
|
4
|
+
|
3
5
|
module Functions
|
4
6
|
class LockfileUpdater
|
5
7
|
RETRYABLE_ERRORS = [Bundler::HTTPError].freeze
|
@@ -9,6 +11,7 @@ module Functions
|
|
9
11
|
not\sfind\s(?<name>[^\s]+)-\d|
|
10
12
|
has\s(?<name>[^\s]+)\slocked\sat
|
11
13
|
/x.freeze
|
14
|
+
DEPENDENCY_DROPPED = "_dependency_dropped_"
|
12
15
|
|
13
16
|
def initialize(gemfile_name:, lockfile_name:, dependencies:)
|
14
17
|
@gemfile_name = gemfile_name
|
@@ -24,7 +27,7 @@ module Functions
|
|
24
27
|
|
25
28
|
attr_reader :gemfile_name, :lockfile_name, :dependencies
|
26
29
|
|
27
|
-
def generate_lockfile
|
30
|
+
def generate_lockfile # rubocop:disable Metrics/PerceivedComplexity
|
28
31
|
dependencies_to_unlock = dependencies.map { |d| d.fetch("name") }
|
29
32
|
|
30
33
|
begin
|
@@ -36,7 +39,7 @@ module Functions
|
|
36
39
|
|
37
40
|
old_reqs.each do |dep_name, old_req|
|
38
41
|
d_dep = definition.dependencies.find { |d| d.name == dep_name }
|
39
|
-
if old_req ==
|
42
|
+
if old_req.to_s == DEPENDENCY_DROPPED then definition.dependencies.delete(d_dep)
|
40
43
|
else
|
41
44
|
d_dep.instance_variable_set(:@requirement, old_req)
|
42
45
|
end
|
@@ -200,7 +203,7 @@ module Functions
|
|
200
203
|
if defn_dep.nil?
|
201
204
|
definition.dependencies <<
|
202
205
|
Bundler::Dependency.new(dep.fetch("name"), dep.fetch("version"))
|
203
|
-
old_reqs[dep.fetch("name")] =
|
206
|
+
old_reqs[dep.fetch("name")] = DEPENDENCY_DROPPED
|
204
207
|
elsif git_dependency?(dep) &&
|
205
208
|
defn_dep.source.is_a?(Bundler::Source::Git)
|
206
209
|
defn_dep.source.unlock!
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Functions
|
2
4
|
class VersionResolver
|
3
5
|
GEM_NOT_FOUND_ERROR_REGEX = /locked to (?<name>[^\s]+) \(/.freeze
|
@@ -20,9 +22,7 @@ module Functions
|
|
20
22
|
# included in a gemspec, it's because the Gemfile didn't import
|
21
23
|
# the gemspec. This is unusual, but the correct behaviour if/when
|
22
24
|
# it happens is to behave as if the repo was gemspec-only.
|
23
|
-
if dep.nil? && dependency_requirements.any?
|
24
|
-
return "latest"
|
25
|
-
end
|
25
|
+
return "latest" if dep.nil? && dependency_requirements.any?
|
26
26
|
|
27
27
|
# Otherwise, if the dependency wasn't found it's because it is a
|
28
28
|
# subdependency that was removed when attempting to update it.
|
@@ -38,9 +38,7 @@ module Functions
|
|
38
38
|
ruby_version: ruby_version,
|
39
39
|
fetcher: fetcher_class(dep)
|
40
40
|
}
|
41
|
-
if dep.source.instance_of?(::Bundler::Source::Git)
|
42
|
-
details[:commit_sha] = dep.source.revision
|
43
|
-
end
|
41
|
+
details[:commit_sha] = dep.source.revision if dep.source.instance_of?(::Bundler::Source::Git)
|
44
42
|
details
|
45
43
|
end
|
46
44
|
|
@@ -92,7 +90,7 @@ module Functions
|
|
92
90
|
end
|
93
91
|
|
94
92
|
def build_definition(dependencies_to_unlock)
|
95
|
-
#
|
93
|
+
# NOTE: we lock shared dependencies to avoid any top-level
|
96
94
|
# dependencies getting unlocked (which would happen if they were
|
97
95
|
# also subdependencies of the dependency being unlocked)
|
98
96
|
::Bundler::Definition.build(
|
@@ -40,9 +40,7 @@ module Bundler
|
|
40
40
|
$LOAD_PATH.shift until $LOAD_PATH.empty?
|
41
41
|
reduced_load_paths.each { |p| $LOAD_PATH << p }
|
42
42
|
|
43
|
-
if destination.relative?
|
44
|
-
destination = destination.expand_path(Bundler.root)
|
45
|
-
end
|
43
|
+
destination = destination.expand_path(Bundler.root) if destination.relative?
|
46
44
|
Dir["#{destination}/#{@glob}"].each do |spec_path|
|
47
45
|
# Evaluate gemspecs and cache the result. Gemspecs
|
48
46
|
# in git might require git or other dependencies.
|
data/helpers/v2/run.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "bundler"
|
2
4
|
require "json"
|
3
5
|
|
@@ -36,9 +38,9 @@ begin
|
|
36
38
|
args = request["args"].transform_keys(&:to_sym)
|
37
39
|
|
38
40
|
output({ result: Functions.send(function, **args) })
|
39
|
-
rescue =>
|
41
|
+
rescue StandardError => e
|
40
42
|
output(
|
41
|
-
{ error:
|
43
|
+
{ error: e.message, error_class: e.class, trace: e.backtrace }
|
42
44
|
)
|
43
45
|
exit(1)
|
44
46
|
end
|
@@ -40,10 +40,10 @@ RSpec.describe Functions::DependencySource do
|
|
40
40
|
|
41
41
|
it "returns all versions from the private source" do
|
42
42
|
is_expected.to eq([
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
Gem::Version.new("1.5.0"),
|
44
|
+
Gem::Version.new("1.9.0"),
|
45
|
+
Gem::Version.new("1.10.0.beta")
|
46
|
+
])
|
47
47
|
end
|
48
48
|
|
49
49
|
context "specified as the default source" do
|
@@ -51,10 +51,10 @@ RSpec.describe Functions::DependencySource do
|
|
51
51
|
|
52
52
|
it "returns all versions from the private source" do
|
53
53
|
is_expected.to eq([
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
Gem::Version.new("1.5.0"),
|
55
|
+
Gem::Version.new("1.9.0"),
|
56
|
+
Gem::Version.new("1.10.0.beta")
|
57
|
+
])
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -12,9 +12,9 @@ RSpec.describe Functions::FileParser do
|
|
12
12
|
)
|
13
13
|
end
|
14
14
|
|
15
|
-
let(:project_name) { "gemfile" }
|
16
|
-
|
17
15
|
describe "#parsed_gemfile" do
|
16
|
+
let(:project_name) { "gemfile" }
|
17
|
+
|
18
18
|
subject(:parsed_gemfile) do
|
19
19
|
in_tmp_folder do
|
20
20
|
dependency_source.parsed_gemfile(gemfile_name: "Gemfile")
|
@@ -54,7 +54,7 @@ RSpec.describe Functions::FileParser do
|
|
54
54
|
branch: "master",
|
55
55
|
ref: "a1b78a9",
|
56
56
|
type: "git",
|
57
|
-
url: "git@github.com:
|
57
|
+
url: "git@github.com:dependabot-fixtures/business"
|
58
58
|
},
|
59
59
|
type: :runtime
|
60
60
|
},
|
@@ -68,36 +68,36 @@ RSpec.describe Functions::FileParser do
|
|
68
68
|
{
|
69
69
|
groups: [:default],
|
70
70
|
name: "prius",
|
71
|
-
requirement:
|
71
|
+
requirement: Gem::Requirement.new(">= 0"),
|
72
72
|
source: {
|
73
73
|
branch: "master",
|
74
74
|
ref: "master",
|
75
75
|
type: "git",
|
76
|
-
url: "https://github.com/
|
76
|
+
url: "https://github.com/dependabot-fixtures/prius"
|
77
77
|
},
|
78
78
|
type: :runtime
|
79
79
|
},
|
80
80
|
{
|
81
81
|
groups: [:default],
|
82
82
|
name: "que",
|
83
|
-
requirement:
|
83
|
+
requirement: Gem::Requirement.new(">= 0"),
|
84
84
|
source: {
|
85
85
|
branch: "master",
|
86
86
|
ref: "v0.11.6",
|
87
87
|
type: "git",
|
88
|
-
url: "git@github.com:
|
88
|
+
url: "git@github.com:dependabot-fixtures/que"
|
89
89
|
},
|
90
90
|
type: :runtime
|
91
91
|
},
|
92
92
|
{
|
93
93
|
groups: [:default],
|
94
94
|
name: "uk_phone_numbers",
|
95
|
-
requirement:
|
95
|
+
requirement: Gem::Requirement.new(">= 0"),
|
96
96
|
source: {
|
97
97
|
branch: "master",
|
98
98
|
ref: "master",
|
99
99
|
type: "git",
|
100
|
-
url: "http://github.com/
|
100
|
+
url: "http://github.com/dependabot-fixtures/uk_phone_numbers"
|
101
101
|
},
|
102
102
|
type: :runtime
|
103
103
|
}
|
@@ -108,14 +108,11 @@ RSpec.describe Functions::FileParser do
|
|
108
108
|
end
|
109
109
|
|
110
110
|
describe "#parsed_gemspec" do
|
111
|
-
let
|
112
|
-
fixture("ruby", "gemspecs", "exact")
|
113
|
-
end
|
111
|
+
let(:project_name) { "gemfile_exact" }
|
114
112
|
|
115
113
|
subject(:parsed_gemspec) do
|
116
|
-
in_tmp_folder do |
|
117
|
-
|
118
|
-
dependency_source.parsed_gemspec(gemspec_name: "test.gemspec")
|
114
|
+
in_tmp_folder do |_tmp_path|
|
115
|
+
dependency_source.parsed_gemspec(gemspec_name: "example.gemspec")
|
119
116
|
end
|
120
117
|
end
|
121
118
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "native_spec_helper"
|
4
|
+
require "shared_contexts"
|
5
|
+
|
6
|
+
RSpec.describe Functions::ForceUpdater do
|
7
|
+
include_context "in a temporary bundler directory"
|
8
|
+
include_context "stub rubygems compact index"
|
9
|
+
|
10
|
+
let(:force_updater) do
|
11
|
+
described_class.new(
|
12
|
+
dependency_name: dependency_name,
|
13
|
+
target_version: target_version,
|
14
|
+
gemfile_name: gemfile_name,
|
15
|
+
lockfile_name: lockfile_name,
|
16
|
+
update_multiple_dependencies: update_multiple_dependencies
|
17
|
+
)
|
18
|
+
end
|
19
|
+
let(:gemfile_name) { "Gemfile" }
|
20
|
+
let(:lockfile_name) { "Gemfile.lock" }
|
21
|
+
let(:update_multiple_dependencies) { true }
|
22
|
+
|
23
|
+
describe "#run" do
|
24
|
+
subject(:force_update) do
|
25
|
+
in_tmp_folder { force_updater.run }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with a version conflict" do
|
29
|
+
let(:target_version) { "3.6.0" }
|
30
|
+
let(:dependency_name) { "rspec-support" }
|
31
|
+
let(:project_name) { "version_conflict" }
|
32
|
+
|
33
|
+
it "updates the conflicting dependencies" do
|
34
|
+
updated_deps, _specs = force_update
|
35
|
+
expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }])
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when updating a single dependency" do
|
39
|
+
let(:update_multiple_dependencies) { false }
|
40
|
+
|
41
|
+
it { expect { force_update }.to raise_error(Bundler::VersionConflict) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with a version conflict in gems rb" do
|
46
|
+
let(:target_version) { "3.6.0" }
|
47
|
+
let(:dependency_name) { "rspec-support" }
|
48
|
+
let(:project_name) { "version_conflict_gems_rb" }
|
49
|
+
let(:gemfile_name) { "gems.rb" }
|
50
|
+
let(:lockfile_name) { "gems.locked" }
|
51
|
+
|
52
|
+
it "updates the conflicting dependencies" do
|
53
|
+
updated_deps, _specs = force_update
|
54
|
+
expect(updated_deps).to eq([{ name: "rspec-support" }, { name: "rspec-mocks" }])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -92,5 +92,13 @@ RSpec.describe Functions::VersionResolver do
|
|
92
92
|
its([:version]) { is_expected.to eq(Gem::Version.new("1.4.0")) }
|
93
93
|
its([:fetcher]) { is_expected.to eq("Bundler::Fetcher::Dependency") }
|
94
94
|
end
|
95
|
+
|
96
|
+
context "with no update possible due to a version conflict" do
|
97
|
+
let(:project_name) { "version_conflict_with_listed_subdep" }
|
98
|
+
let(:dependency_name) { "rspec-mocks" }
|
99
|
+
let(:requirement_string) { ">= 0" }
|
100
|
+
|
101
|
+
its([:version]) { is_expected.to eq(Gem::Version.new("3.6.0")) }
|
102
|
+
end
|
95
103
|
end
|
96
104
|
end
|
@@ -26,8 +26,7 @@ end
|
|
26
26
|
LOCKFILE_ENDING = /(?<ending>\s*(?:RUBY VERSION|BUNDLED WITH).*)/m.freeze
|
27
27
|
|
28
28
|
def project_dependency_files(project)
|
29
|
-
|
30
|
-
project_path = File.expand_path(File.join("../../spec/fixtures/projects/bundler1", project))
|
29
|
+
project_path = File.expand_path(File.join("../../spec/fixtures/projects/bundler2", project))
|
31
30
|
|
32
31
|
raise "Fixture does not exist for project: '#{project}'" unless Dir.exist?(project_path)
|
33
32
|
|
@@ -37,9 +36,7 @@ def project_dependency_files(project)
|
|
37
36
|
files = files.select { |f| File.file?(f) }
|
38
37
|
files.map do |filename|
|
39
38
|
content = File.read(filename)
|
40
|
-
if filename == "Gemfile.lock"
|
41
|
-
content = content.gsub(LOCKFILE_ENDING, "")
|
42
|
-
end
|
39
|
+
content = content.gsub(LOCKFILE_ENDING, "") if filename == "Gemfile.lock"
|
43
40
|
{
|
44
41
|
name: filename,
|
45
42
|
content: content
|
@@ -50,10 +50,10 @@ module Dependabot
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def ruby_version
|
53
|
-
requirement = if
|
54
|
-
Dependabot::Bundler::Requirement.new(ruby_requirement)
|
55
|
-
else
|
53
|
+
requirement = if ruby_requirement.is_a?(Gem::Requirement)
|
56
54
|
ruby_requirement
|
55
|
+
else
|
56
|
+
Dependabot::Bundler::Requirement.new(ruby_requirement)
|
57
57
|
end
|
58
58
|
|
59
59
|
ruby_version =
|
@@ -17,7 +17,6 @@ module Dependabot
|
|
17
17
|
# Bundler will pick the matching installed major version
|
18
18
|
"BUNDLER_VERSION" => bundler_version,
|
19
19
|
"BUNDLE_GEMFILE" => File.join(versioned_helper_path(bundler_version: bundler_version), "Gemfile"),
|
20
|
-
"BUNDLE_PATH" => File.join(versioned_helper_path(bundler_version: bundler_version), ".bundle"),
|
21
20
|
# Prevent the GEM_HOME from being set to a folder owned by root
|
22
21
|
"GEM_HOME" => File.join(versioned_helper_path(bundler_version: bundler_version), ".bundle")
|
23
22
|
}
|
@@ -36,7 +35,7 @@ module Dependabot
|
|
36
35
|
end
|
37
36
|
|
38
37
|
def self.helper_path(bundler_version:)
|
39
|
-
"ruby #{File.join(versioned_helper_path(bundler_version: bundler_version), 'run.rb')}"
|
38
|
+
"bundle exec ruby #{File.join(versioned_helper_path(bundler_version: bundler_version), 'run.rb')}"
|
40
39
|
end
|
41
40
|
|
42
41
|
def self.native_helpers_root
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-bundler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.154.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dependabot-common
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.154.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.154.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: byebug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -202,6 +202,7 @@ files:
|
|
202
202
|
- helpers/v1/spec/functions/conflicting_dependency_resolver_spec.rb
|
203
203
|
- helpers/v1/spec/functions/dependency_source_spec.rb
|
204
204
|
- helpers/v1/spec/functions/file_parser_spec.rb
|
205
|
+
- helpers/v1/spec/functions/force_updater_spec.rb
|
205
206
|
- helpers/v1/spec/functions/version_resolver_spec.rb
|
206
207
|
- helpers/v1/spec/native_spec_helper.rb
|
207
208
|
- helpers/v1/spec/shared_contexts.rb
|
@@ -222,6 +223,7 @@ files:
|
|
222
223
|
- helpers/v2/spec/functions/conflicting_dependency_resolver_spec.rb
|
223
224
|
- helpers/v2/spec/functions/dependency_source_spec.rb
|
224
225
|
- helpers/v2/spec/functions/file_parser_spec.rb
|
226
|
+
- helpers/v2/spec/functions/force_updater_spec.rb
|
225
227
|
- helpers/v2/spec/functions/version_resolver_spec.rb
|
226
228
|
- helpers/v2/spec/functions_spec.rb
|
227
229
|
- helpers/v2/spec/native_spec_helper.rb
|