dependabot-core 0.78.0 → 0.79.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/helpers/npm/lib/updater.js +11 -5
  4. data/helpers/npm/package.json +2 -2
  5. data/helpers/npm/yarn.lock +26 -28
  6. data/helpers/yarn/lib/replace-lockfile-declaration.js +15 -3
  7. data/helpers/yarn/lib/updater.js +17 -5
  8. data/helpers/yarn/package.json +2 -2
  9. data/helpers/yarn/yarn.lock +24 -31
  10. data/lib/dependabot/file_fetchers.rb +0 -2
  11. data/lib/dependabot/file_parsers.rb +0 -2
  12. data/lib/dependabot/file_updaters.rb +0 -2
  13. data/lib/dependabot/metadata_finders.rb +0 -2
  14. data/lib/dependabot/update_checkers.rb +0 -2
  15. data/lib/dependabot/utils.rb +0 -4
  16. data/lib/dependabot/version.rb +1 -1
  17. metadata +3 -34
  18. data/helpers/python/lib/__init__.py +0 -0
  19. data/helpers/python/lib/hasher.py +0 -23
  20. data/helpers/python/lib/parser.py +0 -130
  21. data/helpers/python/requirements.txt +0 -9
  22. data/helpers/python/run.py +0 -18
  23. data/lib/dependabot/file_fetchers/python/pip.rb +0 -305
  24. data/lib/dependabot/file_parsers/python/pip.rb +0 -223
  25. data/lib/dependabot/file_parsers/python/pip/pipfile_files_parser.rb +0 -154
  26. data/lib/dependabot/file_parsers/python/pip/poetry_files_parser.rb +0 -141
  27. data/lib/dependabot/file_parsers/python/pip/setup_file_parser.rb +0 -164
  28. data/lib/dependabot/file_updaters/python/pip.rb +0 -147
  29. data/lib/dependabot/file_updaters/python/pip/pip_compile_file_updater.rb +0 -363
  30. data/lib/dependabot/file_updaters/python/pip/pipfile_file_updater.rb +0 -397
  31. data/lib/dependabot/file_updaters/python/pip/pipfile_preparer.rb +0 -125
  32. data/lib/dependabot/file_updaters/python/pip/poetry_file_updater.rb +0 -289
  33. data/lib/dependabot/file_updaters/python/pip/pyproject_preparer.rb +0 -105
  34. data/lib/dependabot/file_updaters/python/pip/requirement_file_updater.rb +0 -166
  35. data/lib/dependabot/file_updaters/python/pip/requirement_replacer.rb +0 -95
  36. data/lib/dependabot/file_updaters/python/pip/setup_file_sanitizer.rb +0 -91
  37. data/lib/dependabot/file_updaters/ruby/.DS_Store +0 -0
  38. data/lib/dependabot/metadata_finders/python/pip.rb +0 -120
  39. data/lib/dependabot/update_checkers/python/pip.rb +0 -227
  40. data/lib/dependabot/update_checkers/python/pip/latest_version_finder.rb +0 -252
  41. data/lib/dependabot/update_checkers/python/pip/pip_compile_version_resolver.rb +0 -380
  42. data/lib/dependabot/update_checkers/python/pip/pipfile_version_resolver.rb +0 -559
  43. data/lib/dependabot/update_checkers/python/pip/poetry_version_resolver.rb +0 -300
  44. data/lib/dependabot/update_checkers/python/pip/requirements_updater.rb +0 -367
  45. data/lib/dependabot/utils/python/requirement.rb +0 -130
  46. data/lib/dependabot/utils/python/version.rb +0 -88
  47. data/lib/python_requirement_parser.rb +0 -33
  48. data/lib/python_versions.rb +0 -21
@@ -1,223 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "toml-rb"
4
-
5
- require "dependabot/dependency"
6
- require "dependabot/file_parsers/base"
7
- require "dependabot/file_parsers/base/dependency_set"
8
- require "dependabot/shared_helpers"
9
- require "dependabot/utils/python/requirement"
10
- require "dependabot/errors"
11
-
12
- module Dependabot
13
- module FileParsers
14
- module Python
15
- class Pip < Dependabot::FileParsers::Base
16
- require_relative "pip/pipfile_files_parser"
17
- require_relative "pip/poetry_files_parser"
18
- require_relative "pip/setup_file_parser"
19
-
20
- POETRY_DEPENDENCY_TYPES =
21
- %w(tool.poetry.dependencies tool.poetry.dev-dependencies).freeze
22
- DEPENDENCY_GROUP_KEYS = [
23
- {
24
- pipfile: "packages",
25
- lockfile: "default"
26
- },
27
- {
28
- pipfile: "dev-packages",
29
- lockfile: "develop"
30
- }
31
- ].freeze
32
- REQUIREMENT_FILE_EVALUATION_ERRORS = %w(
33
- InstallationError RequirementsFileParseError InvalidMarker
34
- InvalidRequirement
35
- ).freeze
36
-
37
- def parse
38
- dependency_set = DependencySet.new
39
-
40
- dependency_set += pipenv_dependencies if pipfile
41
- dependency_set += poetry_dependencies if using_poetry?
42
- dependency_set += requirement_dependencies if requirement_files.any?
43
- dependency_set += setup_file_dependencies if setup_file
44
-
45
- dependency_set.dependencies
46
- end
47
-
48
- private
49
-
50
- def requirement_files
51
- dependency_files.select { |f| f.name.end_with?(".txt", ".in") }
52
- end
53
-
54
- def pipenv_dependencies
55
- @pipenv_dependencies ||=
56
- PipfileFilesParser.
57
- new(dependency_files: dependency_files).
58
- dependency_set
59
- end
60
-
61
- def poetry_dependencies
62
- @poetry_dependencies ||=
63
- PoetryFilesParser.
64
- new(dependency_files: dependency_files).
65
- dependency_set
66
- end
67
-
68
- def requirement_dependencies
69
- dependencies = DependencySet.new
70
- parsed_requirement_files.each do |dep|
71
- # This isn't ideal, but currently the FileUpdater won't update
72
- # deps that appear in a requirements.txt and Pipfile / Pipfile.lock
73
- # and *aren't* a straight lockfile for the Pipfile
74
- next if included_in_pipenv_deps?(normalised_name(dep["name"]))
75
-
76
- # If a requirement has a `<` or `<=` marker then updating it is
77
- # probably blocked. Ignore it.
78
- next if dep["markers"].include?("<")
79
-
80
- requirements =
81
- if lockfile_for_pip_compile_file?(dep["file"]) then []
82
- else
83
- [{
84
- requirement: dep["requirement"],
85
- file: Pathname.new(dep["file"]).cleanpath.to_path,
86
- source: nil,
87
- groups: []
88
- }]
89
- end
90
-
91
- dependencies <<
92
- Dependency.new(
93
- name: normalised_name(dep["name"]),
94
- version: dep["version"]&.include?("*") ? nil : dep["version"],
95
- requirements: requirements,
96
- package_manager: "pip"
97
- )
98
- end
99
- dependencies
100
- end
101
-
102
- def included_in_pipenv_deps?(dep_name)
103
- return false unless pipfile
104
-
105
- pipenv_dependencies.dependencies.map(&:name).include?(dep_name)
106
- end
107
-
108
- def setup_file_dependencies
109
- @setup_file_dependencies ||=
110
- SetupFileParser.
111
- new(dependency_files: dependency_files).
112
- dependency_set
113
- end
114
-
115
- def lockfile_for_pip_compile_file?(filename)
116
- return false unless pip_compile_files.any?
117
- return false unless filename.end_with?(".txt")
118
-
119
- basename = filename.gsub(/\.txt$/, "")
120
- pip_compile_files.any? { |f| f.name == basename + ".in" }
121
- end
122
-
123
- def parsed_requirement_files
124
- SharedHelpers.in_a_temporary_directory do
125
- write_temporary_dependency_files
126
-
127
- requirements = SharedHelpers.run_helper_subprocess(
128
- command: "pyenv exec python #{python_helper_path}",
129
- function: "parse_requirements",
130
- args: [Dir.pwd]
131
- )
132
-
133
- check_requirements(requirements)
134
- requirements
135
- end
136
- rescue SharedHelpers::HelperSubprocessFailed => error
137
- evaluation_errors = REQUIREMENT_FILE_EVALUATION_ERRORS
138
- raise unless error.message.start_with?(*evaluation_errors)
139
-
140
- raise Dependabot::DependencyFileNotEvaluatable, error.message
141
- end
142
-
143
- def check_requirements(requirements)
144
- requirements.each do |dep|
145
- next unless dep["requirement"]
146
-
147
- Utils::Python::Requirement.new(dep["requirement"].split(","))
148
- rescue Gem::Requirement::BadRequirementError => error
149
- raise Dependabot::DependencyFileNotEvaluatable, error.message
150
- end
151
- end
152
-
153
- def write_temporary_dependency_files
154
- dependency_files.
155
- reject { |f| f.name == ".python-version" }.
156
- each do |file|
157
- path = file.name
158
- FileUtils.mkdir_p(Pathname.new(path).dirname)
159
- File.write(path, file.content)
160
- end
161
- end
162
-
163
- def python_helper_path
164
- project_root = File.join(File.dirname(__FILE__), "../../../..")
165
- File.join(project_root, "helpers/python/run.py")
166
- end
167
-
168
- # See https://www.python.org/dev/peps/pep-0503/#normalized-names
169
- def normalised_name(name)
170
- name.downcase.gsub(/[-_.]+/, "-")
171
- end
172
-
173
- def check_required_files
174
- filenames = dependency_files.map(&:name)
175
- return if filenames.any? { |name| name.end_with?(".txt", ".in") }
176
- return if pipfile
177
- return if pyproject
178
- return if setup_file
179
-
180
- raise "No requirements.txt or setup.py!"
181
- end
182
-
183
- def pipfile
184
- @pipfile ||= get_original_file("Pipfile")
185
- end
186
-
187
- def pipfile_lock
188
- @pipfile_lock ||= get_original_file("Pipfile.lock")
189
- end
190
-
191
- def using_poetry?
192
- return false unless pyproject
193
- return true if poetry_lock || pyproject_lock
194
-
195
- !TomlRB.parse(pyproject.content).dig("tool", "poetry").nil?
196
- rescue TomlRB::ParseError
197
- raise Dependabot::DependencyFileNotParseable, pyproject.path
198
- end
199
-
200
- def pyproject
201
- @pyproject ||= get_original_file("pyproject.toml")
202
- end
203
-
204
- def pyproject_lock
205
- @pyproject_lock ||= get_original_file("pyproject.lock")
206
- end
207
-
208
- def poetry_lock
209
- @poetry_lock ||= get_original_file("poetry.lock")
210
- end
211
-
212
- def setup_file
213
- @setup_file ||= get_original_file("setup.py")
214
- end
215
-
216
- def pip_compile_files
217
- @pip_compile_files ||=
218
- dependency_files.select { |f| f.name.end_with?(".in") }
219
- end
220
- end
221
- end
222
- end
223
- end
@@ -1,154 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "toml-rb"
4
-
5
- require "dependabot/dependency"
6
- require "dependabot/file_parsers/base/dependency_set"
7
- require "dependabot/file_parsers/python/pip"
8
- require "dependabot/errors"
9
-
10
- module Dependabot
11
- module FileParsers
12
- module Python
13
- class Pip
14
- class PipfileFilesParser
15
- DEPENDENCY_GROUP_KEYS = [
16
- {
17
- pipfile: "packages",
18
- lockfile: "default"
19
- },
20
- {
21
- pipfile: "dev-packages",
22
- lockfile: "develop"
23
- }
24
- ].freeze
25
-
26
- def initialize(dependency_files:)
27
- @dependency_files = dependency_files
28
- end
29
-
30
- def dependency_set
31
- dependency_set = Dependabot::FileParsers::Base::DependencySet.new
32
-
33
- dependency_set += pipfile_dependencies
34
- dependency_set += pipfile_lock_dependencies
35
-
36
- dependency_set
37
- end
38
-
39
- private
40
-
41
- attr_reader :dependency_files
42
-
43
- def pipfile_dependencies
44
- dependencies = Dependabot::FileParsers::Base::DependencySet.new
45
-
46
- DEPENDENCY_GROUP_KEYS.each do |keys|
47
- next unless parsed_pipfile[keys[:pipfile]]
48
-
49
- parsed_pipfile[keys[:pipfile]].map do |dep_name, req|
50
- group = keys[:lockfile]
51
- next unless req.is_a?(String) || req["version"]
52
- if pipfile_lock && !dependency_version(dep_name, req, group)
53
- next
54
- end
55
-
56
- dependencies <<
57
- Dependency.new(
58
- name: normalised_name(dep_name),
59
- version: dependency_version(dep_name, req, group),
60
- requirements: [{
61
- requirement: req.is_a?(String) ? req : req["version"],
62
- file: pipfile.name,
63
- source: nil,
64
- groups: [group]
65
- }],
66
- package_manager: "pip"
67
- )
68
- end
69
- end
70
-
71
- dependencies
72
- end
73
-
74
- # Create a DependencySet where each element has no requirement. Any
75
- # requirements will be added when combining the DependencySet with
76
- # other DependencySets.
77
- def pipfile_lock_dependencies
78
- dependencies = Dependabot::FileParsers::Base::DependencySet.new
79
- return dependencies unless pipfile_lock
80
-
81
- DEPENDENCY_GROUP_KEYS.map { |h| h.fetch(:lockfile) }.each do |key|
82
- next unless parsed_pipfile_lock[key]
83
-
84
- parsed_pipfile_lock[key].each do |dep_name, details|
85
- version = case details
86
- when String then details
87
- when Hash then details["version"]
88
- end
89
- next unless version
90
-
91
- dependencies <<
92
- Dependency.new(
93
- name: dep_name,
94
- version: version&.gsub(/^===?/, ""),
95
- requirements: [],
96
- package_manager: "pip"
97
- )
98
- end
99
- end
100
-
101
- dependencies
102
- end
103
-
104
- def dependency_version(dep_name, requirement, group)
105
- req = version_from_hash_or_string(requirement)
106
-
107
- if pipfile_lock
108
- details = parsed_pipfile_lock.
109
- dig(group, normalised_name(dep_name))
110
-
111
- version = version_from_hash_or_string(details)
112
- version&.gsub(/^===?/, "")
113
- elsif req.start_with?("==") && !req.include?("*")
114
- req.strip.gsub(/^===?/, "")
115
- end
116
- end
117
-
118
- def version_from_hash_or_string(obj)
119
- case obj
120
- when String then obj.strip
121
- when Hash then obj["version"]
122
- end
123
- end
124
-
125
- # See https://www.python.org/dev/peps/pep-0503/#normalized-names
126
- def normalised_name(name)
127
- name.downcase.gsub(/[-_.]+/, "-")
128
- end
129
-
130
- def parsed_pipfile
131
- @parsed_pipfile ||= TomlRB.parse(pipfile.content)
132
- rescue TomlRB::ParseError
133
- raise Dependabot::DependencyFileNotParseable, pipfile.path
134
- end
135
-
136
- def parsed_pipfile_lock
137
- @parsed_pipfile_lock ||= JSON.parse(pipfile_lock.content)
138
- rescue JSON::ParserError
139
- raise Dependabot::DependencyFileNotParseable, pipfile_lock.path
140
- end
141
-
142
- def pipfile
143
- @pipfile ||= dependency_files.find { |f| f.name == "Pipfile" }
144
- end
145
-
146
- def pipfile_lock
147
- @pipfile_lock ||=
148
- dependency_files.find { |f| f.name == "Pipfile.lock" }
149
- end
150
- end
151
- end
152
- end
153
- end
154
- end
@@ -1,141 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "toml-rb"
4
-
5
- require "dependabot/dependency"
6
- require "dependabot/file_parsers/base/dependency_set"
7
- require "dependabot/file_parsers/python/pip"
8
- require "dependabot/errors"
9
-
10
- module Dependabot
11
- module FileParsers
12
- module Python
13
- class Pip
14
- class PoetryFilesParser
15
- POETRY_DEPENDENCY_TYPES = %w(dependencies dev-dependencies).freeze
16
-
17
- def initialize(dependency_files:)
18
- @dependency_files = dependency_files
19
- end
20
-
21
- def dependency_set
22
- dependency_set = Dependabot::FileParsers::Base::DependencySet.new
23
-
24
- dependency_set += pyproject_dependencies
25
- dependency_set += lockfile_dependencies if lockfile
26
-
27
- dependency_set
28
- end
29
-
30
- private
31
-
32
- attr_reader :dependency_files
33
-
34
- def pyproject_dependencies
35
- dependencies = Dependabot::FileParsers::Base::DependencySet.new
36
-
37
- POETRY_DEPENDENCY_TYPES.each do |type|
38
- deps_hash = parsed_pyproject.dig("tool", "poetry", type) || {}
39
-
40
- deps_hash.each do |name, req|
41
- next if normalised_name(name) == "python"
42
- next if req.is_a?(Hash) && req.key?("git")
43
-
44
- dependencies <<
45
- Dependency.new(
46
- name: normalised_name(name),
47
- version: version_from_lockfile(name),
48
- requirements: [{
49
- requirement: req.is_a?(String) ? req : req["version"],
50
- file: pyproject.name,
51
- source: nil,
52
- groups: [type]
53
- }],
54
- package_manager: "pip"
55
- )
56
- end
57
- end
58
-
59
- dependencies
60
- end
61
-
62
- # Create a DependencySet where each element has no requirement. Any
63
- # requirements will be added when combining the DependencySet with
64
- # other DependencySets.
65
- def lockfile_dependencies
66
- dependencies = Dependabot::FileParsers::Base::DependencySet.new
67
-
68
- parsed_lockfile.fetch("package", []).each do |details|
69
- next if details.dig("source", "type") == "git"
70
-
71
- dependencies <<
72
- Dependency.new(
73
- name: details.fetch("name"),
74
- version: details.fetch("version"),
75
- requirements: [],
76
- package_manager: "pip"
77
- )
78
- end
79
-
80
- dependencies
81
- end
82
-
83
- def version_from_lockfile(dep_name)
84
- return unless parsed_lockfile
85
-
86
- parsed_lockfile.fetch("package", []).
87
- find { |p| p.fetch("name") == normalised_name(dep_name) }&.
88
- fetch("verison", nil)
89
- end
90
-
91
- # See https://www.python.org/dev/peps/pep-0503/#normalized-names
92
- def normalised_name(name)
93
- name.downcase.gsub(/[-_.]+/, "-")
94
- end
95
-
96
- def parsed_pyproject
97
- @parsed_pyproject ||= TomlRB.parse(pyproject.content)
98
- rescue TomlRB::ParseError
99
- raise Dependabot::DependencyFileNotParseable, pyproject.path
100
- end
101
-
102
- def parsed_pyproject_lock
103
- @parsed_pyproject_lock ||= TomlRB.parse(pyproject_lock.content)
104
- rescue TomlRB::ParseError
105
- raise Dependabot::DependencyFileNotParseable, pyproject_lock.path
106
- end
107
-
108
- def parsed_poetry_lock
109
- @parsed_poetry_lock ||= TomlRB.parse(poetry_lock.content)
110
- rescue TomlRB::ParseError
111
- raise Dependabot::DependencyFileNotParseable, poetry_lock.path
112
- end
113
-
114
- def pyproject
115
- @pyproject ||=
116
- dependency_files.find { |f| f.name == "pyproject.toml" }
117
- end
118
-
119
- def lockfile
120
- poetry_lock || pyproject_lock
121
- end
122
-
123
- def parsed_lockfile
124
- return parsed_poetry_lock if poetry_lock
125
- return parsed_pyproject_lock if pyproject_lock
126
- end
127
-
128
- def pyproject_lock
129
- @pyproject_lock ||=
130
- dependency_files.find { |f| f.name == "pyproject.lock" }
131
- end
132
-
133
- def poetry_lock
134
- @poetry_lock ||=
135
- dependency_files.find { |f| f.name == "poetry.lock" }
136
- end
137
- end
138
- end
139
- end
140
- end
141
- end