dependabot-python 0.108.19 → 0.108.21

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e0f7ee1df3e5d469f00a05bd8b7806c2204279f97e1394f6d3be2442c26c6f0
4
- data.tar.gz: b34a290ea0a8748858fdb22292961d72ad0b3eb97868c4ead1054a5aaf7ea79d
3
+ metadata.gz: 854e1401da6d4347a3ee43320ad1c92c6f74c54794f456722b2914453947c1ff
4
+ data.tar.gz: adba97d1c4efb823a34c46bea97569f09aa34bb3a3b1ec7aa9db76df93923a81
5
5
  SHA512:
6
- metadata.gz: a91f8ce18580038e1e6de4d0889fa848287a1accd8c457b23568f8f0ca65be411872284af5bace3be7fcb23f4531a922d9b373fd803061442391ae4e6cc25d16
7
- data.tar.gz: b83afaac5e110ebc65b60454a58bc0256100899e39571b5c165ad0fa6fe774dc0452851ee5aa86b6641d5223bdaa83a41de687d0a245c3dbac5e70e8a6c42a03
6
+ metadata.gz: 2afd4503cc8f06a7a445a8dc48cb67510adceda5711588c4d44434094427921665cdf76408b443b3451c2f824323cb50391b8f0fa7443026f7a74211d42878fb
7
+ data.tar.gz: 5720f061637253c91d2fae8408c03607b9b47e16a88365dc6f98537a120a582b08f950d0d77b509b7bbb4b6a08e696902081d59f6181157d9341bfff82fe1c34
@@ -11,11 +11,12 @@ module Dependabot
11
11
  module Python
12
12
  class FileParser
13
13
  class SetupFileParser
14
- INSTALL_REQUIRES_REGEX =
15
- /install_requires\s*=\s*(\[.*?\])[,)\s]/m.freeze
16
- SETUP_REQUIRES_REGEX = /setup_requires\s*=\s*(\[.*?\])[,)\s]/m.freeze
17
- TESTS_REQUIRE_REGEX = /tests_require\s*=\s*(\[.*?\])[,)\s]/m.freeze
18
- EXTRAS_REQUIRE_REGEX = /extras_require\s*=\s*(\{.*?\})[,)\s]/m.freeze
14
+ INSTALL_REQUIRES_REGEX = /install_requires\s*=\s*\[/m.freeze
15
+ SETUP_REQUIRES_REGEX = /setup_requires\s*=\s*\[/m.freeze
16
+ TESTS_REQUIRE_REGEX = /tests_require\s*=\s*\[/m.freeze
17
+ EXTRAS_REQUIRE_REGEX = /extras_require\s*=\s*\{/m.freeze
18
+
19
+ CLOSING_BRACKET = { "[" => "]", "{" => "}" }.freeze
19
20
 
20
21
  def initialize(dependency_files:)
21
22
  @dependency_files = dependency_files
@@ -121,16 +122,10 @@ module Dependabot
121
122
  # entries are dynamic), but it is an alternative approach to the one
122
123
  # used in parser.py which sometimes succeeds when that has failed.
123
124
  def write_sanitized_setup_file
124
- original_content = setup_file.content
125
-
126
- install_requires =
127
- original_content.match(INSTALL_REQUIRES_REGEX)&.captures&.first
128
- setup_requires =
129
- original_content.match(SETUP_REQUIRES_REGEX)&.captures&.first
130
- tests_require =
131
- original_content.match(TESTS_REQUIRE_REGEX)&.captures&.first
132
- extras_require =
133
- original_content.match(EXTRAS_REQUIRE_REGEX)&.captures&.first
125
+ install_requires = get_regexed_req_array(INSTALL_REQUIRES_REGEX)
126
+ setup_requires = get_regexed_req_array(SETUP_REQUIRES_REGEX)
127
+ tests_require = get_regexed_req_array(TESTS_REQUIRE_REGEX)
128
+ extras_require = get_regexed_req_dict(EXTRAS_REQUIRE_REGEX)
134
129
 
135
130
  tmp = "from setuptools import setup\n\n"\
136
131
  "setup(name=\"sanitized-package\",version=\"0.0.1\","
@@ -144,6 +139,30 @@ module Dependabot
144
139
  File.write("setup.py", tmp)
145
140
  end
146
141
 
142
+ def get_regexed_req_array(regex)
143
+ return unless (mch = setup_file.content.match(regex))
144
+
145
+ "[#{mch.post_match[0..closing_bracket_index(mch.post_match, '[')]}"
146
+ end
147
+
148
+ def get_regexed_req_dict(regex)
149
+ return unless (mch = setup_file.content.match(regex))
150
+
151
+ "{#{mch.post_match[0..closing_bracket_index(mch.post_match, '{')]}"
152
+ end
153
+
154
+ def closing_bracket_index(string, bracket)
155
+ closes_required = 1
156
+
157
+ string.chars.each_with_index do |char, index|
158
+ closes_required += 1 if char == bracket
159
+ closes_required -= 1 if char == CLOSING_BRACKET.fetch(bracket)
160
+ return index if closes_required.zero?
161
+ end
162
+
163
+ 0
164
+ end
165
+
147
166
  # See https://www.python.org/dev/peps/pep-0503/#normalized-names
148
167
  def normalised_name(name)
149
168
  name.downcase.gsub(/[-_.]+/, "-")
@@ -446,6 +446,7 @@ module Dependabot
446
446
  options << "--no-header"
447
447
  end
448
448
 
449
+ options << "--pre" if requirements_file.content.include?("--pre")
449
450
  options.join(" ")
450
451
  end
451
452
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cgi"
3
4
  require "excon"
4
5
 
5
6
  require "dependabot/python/update_checker"
@@ -12,6 +13,9 @@ module Dependabot
12
13
  class LatestVersionFinder
13
14
  require_relative "index_finder"
14
15
 
16
+ PYTHON_REQUIREMENT_REGEX =
17
+ /data-requires-python\s*=\s*["'](?<requirement>[^"']+)["']/m.freeze
18
+
15
19
  def initialize(dependency:, dependency_files:, credentials:,
16
20
  ignored_versions:, security_advisories:)
17
21
  @dependency = dependency
@@ -21,17 +25,19 @@ module Dependabot
21
25
  @security_advisories = security_advisories
22
26
  end
23
27
 
24
- def latest_version
25
- @latest_version ||= fetch_latest_version
28
+ def latest_version(python_version: nil)
29
+ @latest_version ||=
30
+ fetch_latest_version(python_version: python_version)
26
31
  end
27
32
 
28
- def latest_version_with_no_unlock
33
+ def latest_version_with_no_unlock(python_version: nil)
29
34
  @latest_version_with_no_unlock ||=
30
- fetch_latest_version_with_no_unlock
35
+ fetch_latest_version_with_no_unlock(python_version: python_version)
31
36
  end
32
37
 
33
- def lowest_security_fix_version
34
- @lowest_security_fix_version ||= fetch_lowest_security_fix_version
38
+ def lowest_security_fix_version(python_version: nil)
39
+ @lowest_security_fix_version ||=
40
+ fetch_lowest_security_fix_version(python_version: python_version)
35
41
  end
36
42
 
37
43
  private
@@ -39,23 +45,26 @@ module Dependabot
39
45
  attr_reader :dependency, :dependency_files, :credentials,
40
46
  :ignored_versions, :security_advisories
41
47
 
42
- def fetch_latest_version
48
+ def fetch_latest_version(python_version:)
43
49
  versions = available_versions
50
+ versions = filter_unsupported_versions(versions, python_version)
44
51
  versions = filter_prerelease_versions(versions)
45
52
  versions = filter_ignored_versions(versions)
46
53
  versions.max
47
54
  end
48
55
 
49
- def fetch_latest_version_with_no_unlock
56
+ def fetch_latest_version_with_no_unlock(python_version:)
50
57
  versions = available_versions
58
+ versions = filter_unsupported_versions(versions, python_version)
51
59
  versions = filter_prerelease_versions(versions)
52
60
  versions = filter_ignored_versions(versions)
53
61
  versions = filter_out_of_range_versions(versions)
54
62
  versions.max
55
63
  end
56
64
 
57
- def fetch_lowest_security_fix_version
65
+ def fetch_lowest_security_fix_version(python_version:)
58
66
  versions = available_versions
67
+ versions = filter_unsupported_versions(versions, python_version)
59
68
  versions = filter_prerelease_versions(versions)
60
69
  versions = filter_ignored_versions(versions)
61
70
  versions = filter_vulnerable_versions(versions)
@@ -63,6 +72,17 @@ module Dependabot
63
72
  versions.min
64
73
  end
65
74
 
75
+ def filter_unsupported_versions(versions_array, python_version)
76
+ versions_array.map do |details|
77
+ python_requirement = details.fetch(:python_requirement)
78
+ next details.fetch(:version) unless python_version
79
+ next details.fetch(:version) unless python_requirement
80
+ next unless python_requirement.satisfied_by?(python_version)
81
+
82
+ details.fetch(:version)
83
+ end.compact
84
+ end
85
+
66
86
  def filter_prerelease_versions(versions_array)
67
87
  return versions_array if wants_prerelease?
68
88
 
@@ -118,19 +138,13 @@ module Dependabot
118
138
  raise PrivateSourceAuthenticationFailure, sanitized_url
119
139
  end
120
140
 
121
- index_response.body.
122
- scan(%r{<a\s.*?>(.*?)</a>}m).flatten.
123
- select { |n| n.match?(name_regex) }.
124
- map do |filename|
125
- version =
126
- filename.
127
- gsub(/#{name_regex}-/i, "").
128
- split(/-|\.tar\.|\.zip|\.whl/).
129
- first
130
- next unless version_class.correct?(version)
131
-
132
- version_class.new(version)
133
- end.compact
141
+ version_links = []
142
+ index_response.body.scan(%r{<a\s.*?>.*?</a>}m) do
143
+ details = version_details_from_link(Regexp.last_match.to_s)
144
+ version_links << details if details
145
+ end
146
+
147
+ version_links.compact
134
148
  rescue Excon::Error::Timeout, Excon::Error::Socket
135
149
  raise if MAIN_PYPI_INDEXES.include?(index_url)
136
150
 
@@ -138,6 +152,38 @@ module Dependabot
138
152
  end
139
153
  end
140
154
 
155
+ def version_details_from_link(link)
156
+ filename = link.match(%r{<a\s.*?>(.*?)</a>}).captures.first
157
+ return unless filename.match?(name_regex)
158
+
159
+ version = get_version_from_filename(filename)
160
+ return unless version_class.correct?(version)
161
+
162
+ {
163
+ version: version_class.new(version),
164
+ python_requirement: build_python_requirement_from_link(link)
165
+ }
166
+ end
167
+
168
+ def get_version_from_filename(filename)
169
+ filename.
170
+ gsub(/#{name_regex}-/i, "").
171
+ split(/-|\.tar\.|\.zip|\.whl/).
172
+ first
173
+ end
174
+
175
+ def build_python_requirement_from_link(link)
176
+ req_string = link.
177
+ match(PYTHON_REQUIREMENT_REGEX)&.
178
+ named_captures&.
179
+ fetch("requirement")
180
+ return unless req_string
181
+
182
+ requirement_class.new(CGI.unescapeHTML(req_string))
183
+ rescue Gem::Requirement::BadRequirementError
184
+ nil
185
+ end
186
+
141
187
  def index_urls
142
188
  @index_urls ||=
143
189
  IndexFinder.new(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-python
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.108.19
4
+ version: 0.108.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-18 00:00:00.000000000 Z
11
+ date: 2019-06-22 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.108.19
19
+ version: 0.108.21
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.108.19
26
+ version: 0.108.21
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement