dependabot-dep 0.90.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 +7 -0
- data/helpers/Makefile +9 -0
- data/helpers/build +26 -0
- data/helpers/go.mod +8 -0
- data/helpers/go.sum +2 -0
- data/helpers/importresolver/go.mod +1 -0
- data/helpers/importresolver/main.go +34 -0
- data/helpers/main.go +67 -0
- data/lib/dependabot/dep.rb +11 -0
- data/lib/dependabot/dep/file_fetcher.rb +70 -0
- data/lib/dependabot/dep/file_parser.rb +189 -0
- data/lib/dependabot/dep/file_updater.rb +78 -0
- data/lib/dependabot/dep/file_updater/lockfile_updater.rb +220 -0
- data/lib/dependabot/dep/file_updater/manifest_updater.rb +151 -0
- data/lib/dependabot/dep/metadata_finder.rb +57 -0
- data/lib/dependabot/dep/native_helpers.rb +20 -0
- data/lib/dependabot/dep/path_converter.rb +72 -0
- data/lib/dependabot/dep/requirement.rb +152 -0
- data/lib/dependabot/dep/update_checker.rb +312 -0
- data/lib/dependabot/dep/update_checker/file_preparer.rb +219 -0
- data/lib/dependabot/dep/update_checker/latest_version_finder.rb +167 -0
- data/lib/dependabot/dep/update_checker/requirements_updater.rb +221 -0
- data/lib/dependabot/dep/update_checker/version_resolver.rb +166 -0
- data/lib/dependabot/dep/version.rb +43 -0
- metadata +192 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "excon"
|
|
4
|
+
require "nokogiri"
|
|
5
|
+
|
|
6
|
+
require "dependabot/shared_helpers"
|
|
7
|
+
require "dependabot/source"
|
|
8
|
+
require "dependabot/dep/native_helpers"
|
|
9
|
+
|
|
10
|
+
module Dependabot
|
|
11
|
+
module Dep
|
|
12
|
+
module PathConverter
|
|
13
|
+
def self.git_url_for_path(path)
|
|
14
|
+
# Save a query by manually converting golang.org/x names
|
|
15
|
+
import_path = path.gsub(%r{^golang\.org/x}, "github.com/golang")
|
|
16
|
+
|
|
17
|
+
SharedHelpers.run_helper_subprocess(
|
|
18
|
+
command: NativeHelpers.helper_path,
|
|
19
|
+
function: "getVcsRemoteForImport",
|
|
20
|
+
args: { import: import_path }
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Used in dependabot-backend, which doesn't have access to any Go
|
|
25
|
+
# helpers.
|
|
26
|
+
# TODO: remove the need for this.
|
|
27
|
+
def self.git_url_for_path_without_go_helper(path)
|
|
28
|
+
# Save a query by manually converting golang.org/x names
|
|
29
|
+
tmp_path = path.gsub(%r{^golang\.org/x}, "github.com/golang")
|
|
30
|
+
|
|
31
|
+
# Currently, Dependabot::Source.new will return `nil` if it can't
|
|
32
|
+
# find a git SCH associated with a path. If it is ever extended to
|
|
33
|
+
# handle non-git sources we'll need to add an additional check here.
|
|
34
|
+
return Source.from_url(tmp_path).url if Source.from_url(tmp_path)
|
|
35
|
+
return "https://#{tmp_path}" if tmp_path.end_with?(".git")
|
|
36
|
+
return unless (metadata_response = fetch_path_metadata(path))
|
|
37
|
+
|
|
38
|
+
# Look for a GitHub, Bitbucket or GitLab URL in the response
|
|
39
|
+
metadata_response.scan(Dependabot::Source::SOURCE_REGEX) do
|
|
40
|
+
source_url = Regexp.last_match.to_s
|
|
41
|
+
return Source.from_url(source_url).url
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# If none are found, parse the response and return the go-import path
|
|
45
|
+
doc = Nokogiri::XML(metadata_response)
|
|
46
|
+
doc.remove_namespaces!
|
|
47
|
+
import_details =
|
|
48
|
+
doc.xpath("//meta").
|
|
49
|
+
find { |n| n.attributes["name"]&.value == "go-import" }&.
|
|
50
|
+
attributes&.fetch("content")&.value&.split(/\s+/)
|
|
51
|
+
return unless import_details && import_details[1] == "git"
|
|
52
|
+
|
|
53
|
+
import_details[2]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.fetch_path_metadata(path)
|
|
57
|
+
# TODO: This is not robust! Instead, we should shell out to Go and
|
|
58
|
+
# use https://github.com/Masterminds/vcs.
|
|
59
|
+
response = Excon.get(
|
|
60
|
+
"https://#{path}?go-get=1",
|
|
61
|
+
idempotent: true,
|
|
62
|
+
**SharedHelpers.excon_defaults
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return unless response.status == 200
|
|
66
|
+
|
|
67
|
+
response.body
|
|
68
|
+
end
|
|
69
|
+
private_class_method :fetch_path_metadata
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
################################################################################
|
|
4
|
+
# For more details on Go version constraints, see: #
|
|
5
|
+
# - https://github.com/Masterminds/semver #
|
|
6
|
+
# - https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md #
|
|
7
|
+
################################################################################
|
|
8
|
+
|
|
9
|
+
require "dependabot/dep/version"
|
|
10
|
+
require "dependabot/utils"
|
|
11
|
+
|
|
12
|
+
module Dependabot
|
|
13
|
+
module Dep
|
|
14
|
+
class Requirement < Gem::Requirement
|
|
15
|
+
WILDCARD_REGEX = /(?:\.|^)[xX*]/.freeze
|
|
16
|
+
OR_SEPARATOR = /(?<=[a-zA-Z0-9*])\s*\|{2}/.freeze
|
|
17
|
+
|
|
18
|
+
# Override the version pattern to allow a 'v' prefix
|
|
19
|
+
quoted = OPS.keys.map { |k| Regexp.quote(k) }.join("|")
|
|
20
|
+
version_pattern = "v?#{Dep::Version::VERSION_PATTERN}"
|
|
21
|
+
|
|
22
|
+
PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{version_pattern})\\s*"
|
|
23
|
+
PATTERN = /\A#{PATTERN_RAW}\z/.freeze
|
|
24
|
+
|
|
25
|
+
# Use Dep::Version rather than Gem::Version to ensure that
|
|
26
|
+
# pre-release versions aren't transformed.
|
|
27
|
+
def self.parse(obj)
|
|
28
|
+
return ["=", Dep::Version.new(obj.to_s)] if obj.is_a?(Gem::Version)
|
|
29
|
+
|
|
30
|
+
unless (matches = PATTERN.match(obj.to_s))
|
|
31
|
+
msg = "Illformed requirement [#{obj.inspect}]"
|
|
32
|
+
raise BadRequirementError, msg
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
return DefaultRequirement if matches[1] == ">=" && matches[2] == "0"
|
|
36
|
+
|
|
37
|
+
[matches[1] || "=", Dep::Version.new(matches[2])]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns an array of requirements. At least one requirement from the
|
|
41
|
+
# returned array must be satisfied for a version to be valid.
|
|
42
|
+
def self.requirements_array(requirement_string)
|
|
43
|
+
return [new(nil)] if requirement_string.nil?
|
|
44
|
+
|
|
45
|
+
requirement_string.strip.split(OR_SEPARATOR).map do |req_string|
|
|
46
|
+
new(req_string)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def initialize(*requirements)
|
|
51
|
+
requirements = requirements.flatten.flat_map do |req_string|
|
|
52
|
+
req_string.split(",").map do |r|
|
|
53
|
+
convert_go_constraint_to_ruby_constraint(r.strip)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
super(requirements)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def convert_go_constraint_to_ruby_constraint(req_string)
|
|
63
|
+
req_string = req_string
|
|
64
|
+
req_string = convert_wildcard_characters(req_string)
|
|
65
|
+
|
|
66
|
+
if req_string.match?(WILDCARD_REGEX)
|
|
67
|
+
ruby_range(req_string.gsub(WILDCARD_REGEX, "").gsub(/^[^\d]/, ""))
|
|
68
|
+
elsif req_string.match?(/^~[^>]/) then convert_tilde_req(req_string)
|
|
69
|
+
elsif req_string.include?(" - ") then convert_hyphen_req(req_string)
|
|
70
|
+
elsif req_string.match?(/^[\dv^]/) then convert_caret_req(req_string)
|
|
71
|
+
elsif req_string.match?(/[<=>]/) then req_string
|
|
72
|
+
else ruby_range(req_string)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def convert_wildcard_characters(req_string)
|
|
77
|
+
if req_string.match?(/^[\dv^>~]/)
|
|
78
|
+
replace_wildcard_in_lower_bound(req_string)
|
|
79
|
+
elsif req_string.start_with?("<")
|
|
80
|
+
parts = req_string.split(".")
|
|
81
|
+
parts.map.with_index do |part, index|
|
|
82
|
+
next "0" if part.match?(WILDCARD_REGEX)
|
|
83
|
+
next part.to_i + 1 if parts[index + 1]&.match?(WILDCARD_REGEX)
|
|
84
|
+
|
|
85
|
+
part
|
|
86
|
+
end.join(".")
|
|
87
|
+
else
|
|
88
|
+
req_string
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def replace_wildcard_in_lower_bound(req_string)
|
|
93
|
+
after_wildcard = false
|
|
94
|
+
|
|
95
|
+
if req_string.start_with?("~")
|
|
96
|
+
req_string = req_string.gsub(/(?:(?:\.|^)[xX*])(\.[xX*])+/, "")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
req_string.split(".").
|
|
100
|
+
map do |part|
|
|
101
|
+
part.split("-").map.with_index do |p, i|
|
|
102
|
+
# Before we hit a wildcard we just return the existing part
|
|
103
|
+
next p unless p.match?(WILDCARD_REGEX) || after_wildcard
|
|
104
|
+
|
|
105
|
+
# On or after a wildcard we replace the version part with zero
|
|
106
|
+
after_wildcard = true
|
|
107
|
+
i.zero? ? "0" : "a"
|
|
108
|
+
end.join("-")
|
|
109
|
+
end.join(".")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def convert_tilde_req(req_string)
|
|
113
|
+
version = req_string.gsub(/^~/, "")
|
|
114
|
+
parts = version.split(".")
|
|
115
|
+
parts << "0" if parts.count < 3
|
|
116
|
+
"~> #{parts.join('.')}"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def convert_hyphen_req(req_string)
|
|
120
|
+
lower_bound, upper_bound = req_string.split(/\s+-\s+/)
|
|
121
|
+
[">= #{lower_bound}", "<= #{upper_bound}"]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def ruby_range(req_string)
|
|
125
|
+
parts = req_string.split(".")
|
|
126
|
+
|
|
127
|
+
# If we have three or more parts then this is an exact match
|
|
128
|
+
return req_string if parts.count >= 3
|
|
129
|
+
|
|
130
|
+
# If we have no parts then the version is completely unlocked
|
|
131
|
+
return ">= 0" if parts.count.zero?
|
|
132
|
+
|
|
133
|
+
# If we have fewer than three parts we do a partial match
|
|
134
|
+
parts << "0"
|
|
135
|
+
"~> #{parts.join('.')}"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Note: Dep's caret notation implementation doesn't distinguish between
|
|
139
|
+
# pre and post-1.0.0 requirements (unlike in JS)
|
|
140
|
+
def convert_caret_req(req_string)
|
|
141
|
+
version = req_string.gsub(/^\^?v?/, "")
|
|
142
|
+
parts = version.split(".")
|
|
143
|
+
upper_bound = [parts.first.to_i + 1, 0, 0, "a"].map(&:to_s).join(".")
|
|
144
|
+
|
|
145
|
+
[">= #{version}", "< #{upper_bound}"]
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
Dependabot::Utils.
|
|
152
|
+
register_requirement_class("dep", Dependabot::Dep::Requirement)
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "toml-rb"
|
|
4
|
+
require "dependabot/update_checkers"
|
|
5
|
+
require "dependabot/update_checkers/base"
|
|
6
|
+
|
|
7
|
+
module Dependabot
|
|
8
|
+
module Dep
|
|
9
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
|
10
|
+
require_relative "update_checker/file_preparer"
|
|
11
|
+
require_relative "update_checker/latest_version_finder"
|
|
12
|
+
require_relative "update_checker/requirements_updater"
|
|
13
|
+
require_relative "update_checker/version_resolver"
|
|
14
|
+
|
|
15
|
+
def latest_version
|
|
16
|
+
@latest_version ||=
|
|
17
|
+
LatestVersionFinder.new(
|
|
18
|
+
dependency: dependency,
|
|
19
|
+
dependency_files: dependency_files,
|
|
20
|
+
credentials: credentials,
|
|
21
|
+
ignored_versions: ignored_versions
|
|
22
|
+
).latest_version
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def latest_resolvable_version
|
|
26
|
+
@latest_resolvable_version ||=
|
|
27
|
+
if modules_dependency?
|
|
28
|
+
latest_version
|
|
29
|
+
elsif git_dependency?
|
|
30
|
+
latest_resolvable_version_for_git_dependency
|
|
31
|
+
else
|
|
32
|
+
latest_resolvable_released_version(unlock_requirement: true)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def latest_resolvable_version_with_no_unlock
|
|
37
|
+
@latest_resolvable_version_with_no_unlock ||=
|
|
38
|
+
if git_dependency?
|
|
39
|
+
latest_resolvable_commit_with_unchanged_git_source
|
|
40
|
+
else
|
|
41
|
+
latest_resolvable_released_version(unlock_requirement: false)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def updated_requirements
|
|
46
|
+
@updated_requirements ||=
|
|
47
|
+
RequirementsUpdater.new(
|
|
48
|
+
requirements: dependency.requirements,
|
|
49
|
+
updated_source: updated_source,
|
|
50
|
+
update_strategy: requirements_update_strategy,
|
|
51
|
+
latest_version: latest_version&.to_s,
|
|
52
|
+
latest_resolvable_version: latest_resolvable_version&.to_s
|
|
53
|
+
).updated_requirements
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def requirements_update_strategy
|
|
57
|
+
# If passed in as an option (in the base class) honour that option
|
|
58
|
+
if @requirements_update_strategy
|
|
59
|
+
return @requirements_update_strategy.to_sym
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Otherwise, widen ranges for libraries and bump versions for apps
|
|
63
|
+
library? ? :widen_ranges : :bump_versions
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def latest_version_resolvable_with_full_unlock?
|
|
69
|
+
# Full unlock checks aren't implemented for Go (yet)
|
|
70
|
+
false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def updated_dependencies_after_full_unlock
|
|
74
|
+
raise NotImplementedError
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Override the base class's check for whether this is a git dependency,
|
|
78
|
+
# since not all dep git dependencies have a SHA version (sometimes their
|
|
79
|
+
# version is the tag)
|
|
80
|
+
def existing_version_is_sha?
|
|
81
|
+
git_dependency?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def library?
|
|
85
|
+
dependency_files.none? { |f| f.type == "package_main" }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
89
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
90
|
+
def latest_resolvable_version_for_git_dependency
|
|
91
|
+
return latest_version if modules_dependency?
|
|
92
|
+
|
|
93
|
+
latest_release =
|
|
94
|
+
begin
|
|
95
|
+
latest_resolvable_released_version(unlock_requirement: true)
|
|
96
|
+
rescue SharedHelpers::HelperSubprocessFailed => error
|
|
97
|
+
raise unless error.message.include?("Solving failure")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# If there's a resolvable release that includes the current pinned
|
|
101
|
+
# ref or that the current branch is behind, we switch to that release.
|
|
102
|
+
return latest_release if git_branch_or_ref_in_release?(latest_release)
|
|
103
|
+
|
|
104
|
+
# Otherwise, if the gem isn't pinned, the latest version is just the
|
|
105
|
+
# latest commit for the specified branch.
|
|
106
|
+
unless git_commit_checker.pinned?
|
|
107
|
+
return latest_resolvable_commit_with_unchanged_git_source
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# If the dependency is pinned to a tag that looks like a version then
|
|
111
|
+
# we want to update that tag.
|
|
112
|
+
if git_commit_checker.pinned_ref_looks_like_version? &&
|
|
113
|
+
latest_git_tag_is_resolvable?
|
|
114
|
+
new_tag = git_commit_checker.local_tag_for_latest_version
|
|
115
|
+
return version_from_tag(new_tag)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# If the dependency is pinned to a tag that doesn't look like a
|
|
119
|
+
# version then there's nothing we can do.
|
|
120
|
+
nil
|
|
121
|
+
end
|
|
122
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
123
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
124
|
+
|
|
125
|
+
def version_from_tag(tag)
|
|
126
|
+
# To compare with the current version we either use the commit SHA
|
|
127
|
+
# (if that's what the parser picked up) of the tag name.
|
|
128
|
+
if dependency.version&.match?(/^[0-9a-f]{40}$/)
|
|
129
|
+
return tag&.fetch(:commit_sha)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
tag&.fetch(:tag)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def latest_resolvable_commit_with_unchanged_git_source
|
|
136
|
+
if @commit_lookup_attempted
|
|
137
|
+
return @latest_resolvable_commit_with_unchanged_git_source
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
@commit_lookup_attempted = true
|
|
141
|
+
@latest_resolvable_commit_with_unchanged_git_source ||=
|
|
142
|
+
begin
|
|
143
|
+
prepared_files = FilePreparer.new(
|
|
144
|
+
dependency_files: dependency_files,
|
|
145
|
+
dependency: dependency,
|
|
146
|
+
unlock_requirement: false,
|
|
147
|
+
remove_git_source: false,
|
|
148
|
+
latest_allowable_version: latest_version
|
|
149
|
+
).prepared_dependency_files
|
|
150
|
+
|
|
151
|
+
VersionResolver.new(
|
|
152
|
+
dependency: dependency,
|
|
153
|
+
dependency_files: prepared_files,
|
|
154
|
+
credentials: credentials
|
|
155
|
+
).latest_resolvable_version
|
|
156
|
+
end
|
|
157
|
+
rescue SharedHelpers::HelperSubprocessFailed => error
|
|
158
|
+
# This should rescue resolvability errors in future
|
|
159
|
+
raise unless error.message.include?("Solving failure")
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def latest_resolvable_released_version(unlock_requirement:)
|
|
163
|
+
@latest_resolvable_released_version ||= {}
|
|
164
|
+
@latest_resolvable_released_version[unlock_requirement] ||=
|
|
165
|
+
begin
|
|
166
|
+
prepared_files = FilePreparer.new(
|
|
167
|
+
dependency_files: dependency_files,
|
|
168
|
+
dependency: dependency,
|
|
169
|
+
unlock_requirement: unlock_requirement,
|
|
170
|
+
remove_git_source: git_dependency?,
|
|
171
|
+
latest_allowable_version: latest_version
|
|
172
|
+
).prepared_dependency_files
|
|
173
|
+
|
|
174
|
+
VersionResolver.new(
|
|
175
|
+
dependency: dependency,
|
|
176
|
+
dependency_files: prepared_files,
|
|
177
|
+
credentials: credentials
|
|
178
|
+
).latest_resolvable_version
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def latest_git_tag_is_resolvable?
|
|
183
|
+
return @git_tag_resolvable if @latest_git_tag_is_resolvable_checked
|
|
184
|
+
|
|
185
|
+
@latest_git_tag_is_resolvable_checked = true
|
|
186
|
+
|
|
187
|
+
return false if git_commit_checker.local_tag_for_latest_version.nil?
|
|
188
|
+
|
|
189
|
+
replacement_tag = git_commit_checker.local_tag_for_latest_version
|
|
190
|
+
|
|
191
|
+
prepared_files = FilePreparer.new(
|
|
192
|
+
dependency: dependency,
|
|
193
|
+
dependency_files: dependency_files,
|
|
194
|
+
unlock_requirement: false,
|
|
195
|
+
remove_git_source: false,
|
|
196
|
+
replacement_git_pin: replacement_tag.fetch(:tag)
|
|
197
|
+
).prepared_dependency_files
|
|
198
|
+
|
|
199
|
+
VersionResolver.new(
|
|
200
|
+
dependency: dependency,
|
|
201
|
+
dependency_files: prepared_files,
|
|
202
|
+
credentials: credentials
|
|
203
|
+
).latest_resolvable_version
|
|
204
|
+
|
|
205
|
+
@git_tag_resolvable = true
|
|
206
|
+
rescue SharedHelpers::HelperSubprocessFailed => error
|
|
207
|
+
# This should rescue resolvability errors in future
|
|
208
|
+
raise unless error.message.include?("Solving failure")
|
|
209
|
+
|
|
210
|
+
@git_tag_resolvable = false
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def updated_source
|
|
214
|
+
# Never need to update source, unless a git_dependency
|
|
215
|
+
return dependency_source_details unless git_dependency?
|
|
216
|
+
|
|
217
|
+
# Source becomes `nil` if switching to default rubygems
|
|
218
|
+
return default_source if should_switch_source_from_ref_to_release?
|
|
219
|
+
|
|
220
|
+
# Update the git tag if updating a pinned version
|
|
221
|
+
if git_commit_checker.pinned_ref_looks_like_version? &&
|
|
222
|
+
latest_git_tag_is_resolvable?
|
|
223
|
+
new_tag = git_commit_checker.local_tag_for_latest_version
|
|
224
|
+
return dependency_source_details.merge(ref: new_tag.fetch(:tag))
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Otherwise return the original source
|
|
228
|
+
dependency_source_details
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def dependency_source_details
|
|
232
|
+
sources =
|
|
233
|
+
dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact
|
|
234
|
+
|
|
235
|
+
raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
|
|
236
|
+
|
|
237
|
+
sources.first
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def should_switch_source_from_ref_to_release?
|
|
241
|
+
return false unless git_dependency?
|
|
242
|
+
return false if latest_resolvable_version_for_git_dependency.nil?
|
|
243
|
+
|
|
244
|
+
Gem::Version.correct?(latest_resolvable_version_for_git_dependency)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def modules_dependency?
|
|
248
|
+
# If dep is being used then we use that to determine the latest
|
|
249
|
+
# version we can update to (since it will have resolvability
|
|
250
|
+
# requirements, whereas Go modules won't)
|
|
251
|
+
!dependency_in_gopkg_lock?
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def dependency_in_gopkg_lock?
|
|
255
|
+
lockfile = dependency_files.find { |f| f.name == "Gopkg.lock" }
|
|
256
|
+
return false unless lockfile
|
|
257
|
+
|
|
258
|
+
parsed_file(lockfile).fetch("projects", []).any? do |details|
|
|
259
|
+
details.fetch("name") == dependency.name
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def git_dependency?
|
|
264
|
+
git_commit_checker.git_dependency?
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def default_source
|
|
268
|
+
if modules_dependency?
|
|
269
|
+
return { type: "default", source: dependency.name }
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
original_declaration =
|
|
273
|
+
parsed_file(manifest).
|
|
274
|
+
values_at(*Dep::FileParser::REQUIREMENT_TYPES).
|
|
275
|
+
flatten.compact.
|
|
276
|
+
find { |d| d["name"] == dependency.name }
|
|
277
|
+
|
|
278
|
+
{
|
|
279
|
+
type: "default",
|
|
280
|
+
source:
|
|
281
|
+
original_declaration&.fetch("source", nil) || dependency.name
|
|
282
|
+
}
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def git_branch_or_ref_in_release?(release)
|
|
286
|
+
return false unless release
|
|
287
|
+
|
|
288
|
+
git_commit_checker.branch_or_ref_in_release?(release)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def parsed_file(file)
|
|
292
|
+
@parsed_file ||= {}
|
|
293
|
+
@parsed_file[file.name] ||= TomlRB.parse(file.content)
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def manifest
|
|
297
|
+
@manifest ||= dependency_files.find { |f| f.name == "Gopkg.toml" }
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def git_commit_checker
|
|
301
|
+
@git_commit_checker ||=
|
|
302
|
+
GitCommitChecker.new(
|
|
303
|
+
dependency: dependency,
|
|
304
|
+
credentials: credentials,
|
|
305
|
+
ignored_versions: ignored_versions
|
|
306
|
+
)
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
Dependabot::UpdateCheckers.register("dep", Dependabot::Dep::UpdateChecker)
|