dependabot-core 0.94.13 → 0.95.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. metadata +13 -337
  3. data/CHANGELOG.md +0 -7079
  4. data/LICENSE +0 -39
  5. data/README.md +0 -114
  6. data/helpers/test/run.rb +0 -18
  7. data/helpers/utils/git-credential-store-immutable +0 -10
  8. data/lib/dependabot/clients/bitbucket.rb +0 -105
  9. data/lib/dependabot/clients/github_with_retries.rb +0 -121
  10. data/lib/dependabot/clients/gitlab.rb +0 -72
  11. data/lib/dependabot/dependency.rb +0 -115
  12. data/lib/dependabot/dependency_file.rb +0 -60
  13. data/lib/dependabot/errors.rb +0 -179
  14. data/lib/dependabot/file_fetchers/README.md +0 -65
  15. data/lib/dependabot/file_fetchers/base.rb +0 -368
  16. data/lib/dependabot/file_fetchers.rb +0 -18
  17. data/lib/dependabot/file_parsers/README.md +0 -45
  18. data/lib/dependabot/file_parsers/base/dependency_set.rb +0 -77
  19. data/lib/dependabot/file_parsers/base.rb +0 -31
  20. data/lib/dependabot/file_parsers.rb +0 -18
  21. data/lib/dependabot/file_updaters/README.md +0 -58
  22. data/lib/dependabot/file_updaters/base.rb +0 -52
  23. data/lib/dependabot/file_updaters.rb +0 -18
  24. data/lib/dependabot/git_commit_checker.rb +0 -412
  25. data/lib/dependabot/metadata_finders/README.md +0 -53
  26. data/lib/dependabot/metadata_finders/base/changelog_finder.rb +0 -321
  27. data/lib/dependabot/metadata_finders/base/changelog_pruner.rb +0 -177
  28. data/lib/dependabot/metadata_finders/base/commits_finder.rb +0 -221
  29. data/lib/dependabot/metadata_finders/base/release_finder.rb +0 -255
  30. data/lib/dependabot/metadata_finders/base.rb +0 -117
  31. data/lib/dependabot/metadata_finders.rb +0 -18
  32. data/lib/dependabot/pull_request_creator/branch_namer.rb +0 -170
  33. data/lib/dependabot/pull_request_creator/commit_signer.rb +0 -63
  34. data/lib/dependabot/pull_request_creator/github.rb +0 -277
  35. data/lib/dependabot/pull_request_creator/gitlab.rb +0 -136
  36. data/lib/dependabot/pull_request_creator/labeler.rb +0 -373
  37. data/lib/dependabot/pull_request_creator/message_builder.rb +0 -906
  38. data/lib/dependabot/pull_request_creator.rb +0 -153
  39. data/lib/dependabot/pull_request_updater/github.rb +0 -165
  40. data/lib/dependabot/pull_request_updater.rb +0 -43
  41. data/lib/dependabot/shared_helpers.rb +0 -224
  42. data/lib/dependabot/source.rb +0 -120
  43. data/lib/dependabot/update_checkers/README.md +0 -67
  44. data/lib/dependabot/update_checkers/base.rb +0 -220
  45. data/lib/dependabot/update_checkers.rb +0 -18
  46. data/lib/dependabot/utils.rb +0 -33
  47. data/lib/dependabot/version.rb +0 -5
  48. data/lib/dependabot.rb +0 -4
  49. data/lib/rubygems_version_patch.rb +0 -14
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/metadata_finders"
4
- require "dependabot/pull_request_creator"
5
-
6
- module Dependabot
7
- class PullRequestCreator
8
- class BranchNamer
9
- attr_reader :dependencies, :files, :target_branch, :separator
10
-
11
- def initialize(dependencies:, files:, target_branch:, separator: "/")
12
- @dependencies = dependencies
13
- @files = files
14
- @target_branch = target_branch
15
- @separator = separator
16
- end
17
-
18
- # rubocop:disable Metrics/AbcSize
19
- # rubocop:disable Metrics/PerceivedComplexity
20
- # rubocop:disable Metrics/CyclomaticComplexity
21
- def new_branch_name
22
- @name ||=
23
- if dependencies.count > 1 && updating_a_property?
24
- property_name
25
- elsif dependencies.count > 1 && updating_a_dependency_set?
26
- dependency_set.fetch(:group)
27
- elsif dependencies.count > 1
28
- dependencies.map(&:name).join("-and-").tr(":", "-")
29
- elsif library? && ref_changed?(dependencies.first)
30
- dep = dependencies.first
31
- "#{dep.name.tr(':', '-')}-#{new_ref(dep)}"
32
- elsif library?
33
- dep = dependencies.first
34
- "#{dep.name.tr(':', '-')}-#{sanitized_requirement(dep)}"
35
- else
36
- dep = dependencies.first
37
- "#{dep.name.tr(':', '-')}-#{new_version(dep)}"
38
- end
39
-
40
- branch_name = File.join(prefixes, @name).gsub(%r{/\.}, "/dot-")
41
-
42
- # Some users need branch names without slashes
43
- branch_name.gsub("/", separator)
44
- end
45
- # rubocop:enable Metrics/AbcSize
46
- # rubocop:enable Metrics/PerceivedComplexity
47
- # rubocop:enable Metrics/CyclomaticComplexity
48
-
49
- private
50
-
51
- def prefixes
52
- [
53
- "dependabot",
54
- package_manager,
55
- files.first.directory.tr(" ", "-"),
56
- target_branch
57
- ].compact
58
- end
59
-
60
- def package_manager
61
- dependencies.first.package_manager
62
- end
63
-
64
- def updating_a_property?
65
- dependencies.first.
66
- requirements.
67
- any? { |r| r.dig(:metadata, :property_name) }
68
- end
69
-
70
- def updating_a_dependency_set?
71
- dependencies.first.
72
- requirements.
73
- any? { |r| r.dig(:metadata, :dependency_set) }
74
- end
75
-
76
- def property_name
77
- @property_name ||= dependencies.first.requirements.
78
- find { |r| r.dig(:metadata, :property_name) }&.
79
- dig(:metadata, :property_name)
80
-
81
- raise "No property name!" unless @property_name
82
-
83
- @property_name
84
- end
85
-
86
- def dependency_set
87
- @dependency_set ||= dependencies.first.requirements.
88
- find { |r| r.dig(:metadata, :dependency_set) }&.
89
- dig(:metadata, :dependency_set)
90
-
91
- raise "No dependency set!" unless @dependency_set
92
-
93
- @dependency_set
94
- end
95
-
96
- def sanitized_requirement(dependency)
97
- new_library_requirement(dependency).
98
- delete(" ").
99
- gsub("!=", "neq-").
100
- gsub(">=", "gte-").
101
- gsub("<=", "lte-").
102
- gsub("~>", "tw-").
103
- gsub("^", "tw-").
104
- gsub("||", "or-").
105
- gsub("~", "approx-").
106
- gsub("~=", "tw-").
107
- gsub(/==*/, "eq-").
108
- gsub(">", "gt-").
109
- gsub("<", "lt-").
110
- gsub("*", "star").
111
- gsub(",", "-and-")
112
- end
113
-
114
- def new_version(dependency)
115
- if dependency.version.match?(/^[0-9a-f]{40}$/)
116
- return new_ref(dependency) if ref_changed?(dependency)
117
-
118
- dependency.version[0..6]
119
- elsif dependency.version == dependency.previous_version &&
120
- package_manager == "docker"
121
- dependency.requirements.
122
- map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }.
123
- compact.first.split(":").last[0..6]
124
- else
125
- dependency.version
126
- end
127
- end
128
-
129
- def previous_ref(dependency)
130
- dependency.previous_requirements.map do |r|
131
- r.dig(:source, "ref") || r.dig(:source, :ref)
132
- end.compact.first
133
- end
134
-
135
- def new_ref(dependency)
136
- dependency.requirements.map do |r|
137
- r.dig(:source, "ref") || r.dig(:source, :ref)
138
- end.compact.first
139
- end
140
-
141
- def ref_changed?(dependency)
142
- previous_ref(dependency) && new_ref(dependency) &&
143
- previous_ref(dependency) != new_ref(dependency)
144
- end
145
-
146
- def new_library_requirement(dependency)
147
- updated_reqs =
148
- dependency.requirements - dependency.previous_requirements
149
-
150
- gemspec =
151
- updated_reqs.find { |r| r[:file].match?(%r{^[^/]*\.gemspec$}) }
152
- return gemspec[:requirement] if gemspec
153
-
154
- updated_reqs.first[:requirement]
155
- end
156
-
157
- def library?
158
- if files.map(&:name).any? { |name| name.end_with?(".gemspec") }
159
- return true
160
- end
161
-
162
- dependencies.none?(&:appears_in_lockfile?)
163
- end
164
-
165
- def requirements_changed?(dependency)
166
- (dependency.requirements - dependency.previous_requirements).any?
167
- end
168
- end
169
- end
170
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "time"
4
- require "gpgme"
5
- require "tmpdir"
6
- require "dependabot/pull_request_creator"
7
-
8
- module Dependabot
9
- class PullRequestCreator
10
- class CommitSigner
11
- attr_reader :author_details, :commit_message, :tree_sha, :parent_sha,
12
- :signature_key
13
-
14
- def initialize(author_details:, commit_message:, tree_sha:, parent_sha:,
15
- signature_key:)
16
- @author_details = author_details
17
- @commit_message = commit_message
18
- @tree_sha = tree_sha
19
- @parent_sha = parent_sha
20
- @signature_key = signature_key
21
- end
22
-
23
- def signature
24
- email = author_details[:email]
25
-
26
- dir = Dir.mktmpdir
27
-
28
- GPGME::Engine.home_dir = dir
29
- GPGME::Key.import(signature_key)
30
-
31
- crypto = GPGME::Crypto.new(armor: true)
32
- opts = { mode: GPGME::SIG_MODE_DETACH, signer: email }
33
- crypto.sign(commit_object, opts).to_s
34
- rescue Errno::ENOTEMPTY
35
- FileUtils.remove_entry(dir, true)
36
- # This appears to be a Ruby bug which occurs very rarely
37
- raise if @retrying
38
-
39
- @retrying = true
40
- retry
41
- ensure
42
- FileUtils.remove_entry(dir, true)
43
- end
44
-
45
- private
46
-
47
- def commit_object
48
- time_str = Time.parse(author_details[:date]).strftime("%s %z")
49
- name = author_details[:name]
50
- email = author_details[:email]
51
-
52
- [
53
- "tree #{tree_sha}",
54
- "parent #{parent_sha}",
55
- "author #{name} <#{email}> #{time_str}",
56
- "committer #{name} <#{email}> #{time_str}",
57
- "",
58
- commit_message
59
- ].join("\n")
60
- end
61
- end
62
- end
63
- end
@@ -1,277 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "octokit"
4
- require "securerandom"
5
- require "dependabot/clients/github_with_retries"
6
- require "dependabot/pull_request_creator"
7
- require "dependabot/pull_request_creator/commit_signer"
8
-
9
- module Dependabot
10
- class PullRequestCreator
11
- class Github
12
- attr_reader :source, :branch_name, :base_commit, :credentials,
13
- :files, :pr_description, :pr_name, :commit_message,
14
- :author_details, :signature_key,
15
- :labeler, :reviewers, :assignees, :milestone
16
-
17
- def initialize(source:, branch_name:, base_commit:, credentials:,
18
- files:, commit_message:, pr_description:, pr_name:,
19
- author_details:, signature_key:,
20
- labeler:, reviewers:, assignees:, milestone:)
21
- @source = source
22
- @branch_name = branch_name
23
- @base_commit = base_commit
24
- @credentials = credentials
25
- @files = files
26
- @commit_message = commit_message
27
- @pr_description = pr_description
28
- @pr_name = pr_name
29
- @author_details = author_details
30
- @signature_key = signature_key
31
- @labeler = labeler
32
- @reviewers = reviewers
33
- @assignees = assignees
34
- @milestone = milestone
35
- end
36
-
37
- def create
38
- return if branch_exists? && pull_request_exists?
39
-
40
- commit = create_commit
41
- branch = create_or_update_branch(commit)
42
- return unless branch
43
-
44
- pull_request = create_pull_request
45
- return unless pull_request
46
-
47
- annotate_pull_request(pull_request)
48
-
49
- pull_request
50
- rescue Octokit::Error => error
51
- handle_error(error)
52
- end
53
-
54
- private
55
-
56
- def github_client_for_source
57
- @github_client_for_source ||=
58
- Dependabot::Clients::GithubWithRetries.for_source(
59
- source: source,
60
- credentials: credentials
61
- )
62
- end
63
-
64
- def branch_exists?
65
- @branch_ref ||=
66
- github_client_for_source.ref(source.repo, "heads/#{branch_name}")
67
- if @branch_ref.is_a?(Array)
68
- @branch_ref.any? { |r| r.ref == "refs/heads/#{branch_name}" }
69
- else
70
- @branch_ref.ref == "refs/heads/#{branch_name}"
71
- end
72
- rescue Octokit::NotFound
73
- false
74
- end
75
-
76
- def pull_request_exists?
77
- github_client_for_source.pull_requests(
78
- source.repo,
79
- head: "#{source.repo.split('/').first}:#{branch_name}",
80
- state: "all"
81
- ).any?
82
- rescue Octokit::InternalServerError
83
- # A GitHub bug sometimes means adding `state: all` causes problems.
84
- # In that case, fall back to making two separate requests.
85
- open_prs = github_client_for_source.pull_requests(
86
- source.repo,
87
- head: "#{source.repo.split('/').first}:#{branch_name}",
88
- state: "open"
89
- )
90
-
91
- closed_prs = github_client_for_source.pull_requests(
92
- source.repo,
93
- head: "#{source.repo.split('/').first}:#{branch_name}",
94
- state: "closed"
95
- )
96
-
97
- [*open_prs, *closed_prs].any?
98
- end
99
-
100
- def repo_exists?
101
- github_client_for_source.repo(source.repo)
102
- true
103
- rescue Octokit::NotFound
104
- false
105
- end
106
-
107
- def create_commit
108
- tree = create_tree
109
-
110
- options = author_details&.any? ? { author: author_details } : {}
111
-
112
- if options[:author]&.any? && signature_key
113
- options[:author][:date] = Time.now.utc.iso8601
114
- options[:signature] = commit_signature(tree, options[:author])
115
- end
116
-
117
- github_client_for_source.create_commit(
118
- source.repo,
119
- commit_message,
120
- tree.sha,
121
- base_commit,
122
- options
123
- )
124
- end
125
-
126
- def create_tree
127
- file_trees = files.map do |file|
128
- if file.type == "submodule"
129
- {
130
- path: file.path.sub(%r{^/}, ""),
131
- mode: "160000",
132
- type: "commit",
133
- sha: file.content
134
- }
135
- else
136
- {
137
- path: file.path.sub(%r{^/}, ""),
138
- mode: "100644",
139
- type: "blob",
140
- content: file.content
141
- }
142
- end
143
- end
144
-
145
- github_client_for_source.create_tree(
146
- source.repo,
147
- file_trees,
148
- base_tree: base_commit
149
- )
150
- end
151
-
152
- def create_or_update_branch(commit)
153
- branch_exists? ? update_branch(commit) : create_branch(commit)
154
- rescue Octokit::UnprocessableEntity
155
- # A race condition may cause GitHub to fail here, in which case we retry
156
- retry_count ||= 0
157
- retry_count += 1
158
- retry unless retry_count >= 2
159
- end
160
-
161
- def create_branch(commit)
162
- github_client_for_source.create_ref(
163
- source.repo,
164
- "heads/#{branch_name}",
165
- commit.sha
166
- )
167
- rescue Octokit::UnprocessableEntity => error
168
- # Return quietly in the case of a race
169
- return nil if error.message.match?(/Reference already exists/i)
170
- raise if @retrying_branch_creation
171
-
172
- @retrying_branch_creation = true
173
-
174
- # Branch creation will fail if a branch called `dependabot` already
175
- # exists, since git won't be able to create a folder with the same name
176
- @branch_name = SecureRandom.hex[0..3] + @branch_name
177
- retry
178
- end
179
-
180
- def update_branch(commit)
181
- github_client_for_source.update_ref(
182
- source.repo,
183
- "heads/#{branch_name}",
184
- commit.sha,
185
- true
186
- )
187
- end
188
-
189
- def annotate_pull_request(pull_request)
190
- labeler.label_pull_request(pull_request.number)
191
- add_reviewers_to_pull_request(pull_request) if reviewers&.any?
192
- add_assignees_to_pull_request(pull_request) if assignees&.any?
193
- add_milestone_to_pull_request(pull_request) if milestone
194
- end
195
-
196
- def add_reviewers_to_pull_request(pull_request)
197
- reviewers_hash =
198
- Hash[reviewers.keys.map { |k| [k.to_sym, reviewers[k]] }]
199
-
200
- github_client_for_source.request_pull_request_review(
201
- source.repo,
202
- pull_request.number,
203
- reviewers: reviewers_hash[:reviewers] || [],
204
- team_reviewers: reviewers_hash[:team_reviewers] || []
205
- )
206
- rescue Octokit::UnprocessableEntity => error
207
- return if error.message.include?("not a collaborator")
208
- return if error.message.include?("Could not resolve to a node")
209
-
210
- raise
211
- end
212
-
213
- def add_assignees_to_pull_request(pull_request)
214
- github_client_for_source.add_assignees(
215
- source.repo,
216
- pull_request.number,
217
- assignees
218
- )
219
- end
220
-
221
- def add_milestone_to_pull_request(pull_request)
222
- github_client_for_source.update_issue(
223
- source.repo,
224
- pull_request.number,
225
- milestone: milestone
226
- )
227
- end
228
-
229
- def create_pull_request
230
- github_client_for_source.create_pull_request(
231
- source.repo,
232
- source.branch || default_branch,
233
- branch_name,
234
- pr_name,
235
- pr_description
236
- )
237
- rescue Octokit::UnprocessableEntity => error
238
- # Ignore races that we lose
239
- raise unless error.message.include?("pull request already exists")
240
- end
241
-
242
- def default_branch
243
- @default_branch ||=
244
- github_client_for_source.repository(source.repo).default_branch
245
- end
246
-
247
- def commit_signature(tree, author_details_with_date)
248
- CommitSigner.new(
249
- author_details: author_details_with_date,
250
- commit_message: commit_message,
251
- tree_sha: tree.sha,
252
- parent_sha: base_commit,
253
- signature_key: signature_key
254
- ).signature
255
- end
256
-
257
- def handle_error(error)
258
- case error
259
- when Octokit::Forbidden
260
- raise error unless error.message.include?("Repository was archived")
261
-
262
- raise RepoArchived, error.message
263
- when Octokit::NotFound
264
- raise error if repo_exists?
265
-
266
- raise RepoNotFound, error.message
267
- when Octokit::UnprocessableEntity
268
- raise error unless error.message.include?("no history in common")
269
-
270
- raise NoHistoryInCommon, error.message
271
- else
272
- raise error
273
- end
274
- end
275
- end
276
- end
277
- end
@@ -1,136 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/clients/gitlab"
4
- require "dependabot/pull_request_creator"
5
- require "gitlab"
6
-
7
- module Dependabot
8
- class PullRequestCreator
9
- class Gitlab
10
- attr_reader :source, :branch_name, :base_commit, :credentials,
11
- :files, :pr_description, :pr_name, :commit_message,
12
- :author_details, :labeler, :assignee
13
-
14
- def initialize(source:, branch_name:, base_commit:, credentials:,
15
- files:, commit_message:, pr_description:, pr_name:,
16
- author_details:, labeler:, assignee:)
17
- @source = source
18
- @branch_name = branch_name
19
- @base_commit = base_commit
20
- @credentials = credentials
21
- @files = files
22
- @commit_message = commit_message
23
- @pr_description = pr_description
24
- @pr_name = pr_name
25
- @author_details = author_details
26
- @labeler = labeler
27
- @assignee = assignee
28
- end
29
-
30
- def create
31
- return if branch_exists? && merge_request_exists?
32
-
33
- if branch_exists?
34
- create_commit unless commit_exists?
35
- else
36
- create_branch
37
- create_commit
38
- end
39
-
40
- labeler.create_default_labels_if_required
41
- create_merge_request
42
- end
43
-
44
- private
45
-
46
- def gitlab_client_for_source
47
- @gitlab_client_for_source ||= Dependabot::Clients::Gitlab.for_source(
48
- source: source,
49
- credentials: credentials
50
- )
51
- end
52
-
53
- def branch_exists?
54
- @branch_ref ||=
55
- gitlab_client_for_source.branch(source.repo, branch_name)
56
- true
57
- rescue ::Gitlab::Error::NotFound
58
- false
59
- end
60
-
61
- def commit_exists?
62
- @commits ||=
63
- gitlab_client_for_source.commits(source.repo, ref_name: branch_name)
64
- @commits.first.message == commit_message
65
- end
66
-
67
- def merge_request_exists?
68
- gitlab_client_for_source.merge_requests(
69
- source.repo,
70
- source_branch: branch_name,
71
- target_branch: source.branch || default_branch,
72
- state: "all"
73
- ).any?
74
- end
75
-
76
- def create_branch
77
- gitlab_client_for_source.create_branch(
78
- source.repo,
79
- branch_name,
80
- base_commit
81
- )
82
- end
83
-
84
- def create_commit
85
- if files.count == 1 && files.first.type == "submodule"
86
- return create_submodule_update_commit
87
- end
88
-
89
- actions = files.map do |file|
90
- {
91
- action: "update",
92
- file_path: file.path,
93
- content: file.content
94
- }
95
- end
96
-
97
- gitlab_client_for_source.create_commit(
98
- source.repo,
99
- branch_name,
100
- commit_message,
101
- actions
102
- )
103
- end
104
-
105
- def create_submodule_update_commit
106
- file = files.first
107
-
108
- gitlab_client_for_source.edit_submodule(
109
- source.repo,
110
- file.path.gsub(%r{^/}, ""),
111
- branch: branch_name,
112
- commit_sha: file.content,
113
- commit_message: commit_message
114
- )
115
- end
116
-
117
- def create_merge_request
118
- gitlab_client_for_source.create_merge_request(
119
- source.repo,
120
- pr_name,
121
- source_branch: branch_name,
122
- target_branch: source.branch || default_branch,
123
- description: pr_description,
124
- remove_source_branch: true,
125
- assignee_id: assignee,
126
- labels: labeler.labels_for_pr.join(",")
127
- )
128
- end
129
-
130
- def default_branch
131
- @default_branch ||=
132
- gitlab_client_for_source.project(source.repo).default_branch
133
- end
134
- end
135
- end
136
- end