dependabot-core 0.78.0 → 0.79.0

Sign up to get free protection for your applications and to get access to all the features.
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,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dependabot/update_checkers/ruby/bundler"
4
- require "dependabot/update_checkers/python/pip"
5
4
  require "dependabot/update_checkers/java_script/npm_and_yarn"
6
5
  require "dependabot/update_checkers/java/maven"
7
6
  require "dependabot/update_checkers/java/gradle"
@@ -20,7 +19,6 @@ module Dependabot
20
19
  "npm_and_yarn" => UpdateCheckers::JavaScript::NpmAndYarn,
21
20
  "maven" => UpdateCheckers::Java::Maven,
22
21
  "gradle" => UpdateCheckers::Java::Gradle,
23
- "pip" => UpdateCheckers::Python::Pip,
24
22
  "composer" => UpdateCheckers::Php::Composer,
25
23
  "hex" => UpdateCheckers::Elixir::Hex,
26
24
  "cargo" => UpdateCheckers::Rust::Cargo,
@@ -5,7 +5,6 @@ require "dependabot/utils/elixir/version"
5
5
  require "dependabot/utils/java/version"
6
6
  require "dependabot/utils/java_script/version"
7
7
  require "dependabot/utils/php/version"
8
- require "dependabot/utils/python/version"
9
8
  require "dependabot/utils/rust/version"
10
9
  require "dependabot/utils/go/version"
11
10
  require "dependabot/utils/elm/version"
@@ -15,7 +14,6 @@ require "dependabot/utils/elixir/requirement"
15
14
  require "dependabot/utils/java/requirement"
16
15
  require "dependabot/utils/java_script/requirement"
17
16
  require "dependabot/utils/php/requirement"
18
- require "dependabot/utils/python/requirement"
19
17
  require "dependabot/utils/ruby/requirement"
20
18
  require "dependabot/utils/rust/requirement"
21
19
  require "dependabot/utils/go/requirement"
@@ -33,7 +31,6 @@ module Dependabot
33
31
  "maven" => Utils::Java::Version,
34
32
  "gradle" => Utils::Java::Version,
35
33
  "npm_and_yarn" => Utils::JavaScript::Version,
36
- "pip" => Utils::Python::Version,
37
34
  "composer" => Utils::Php::Version,
38
35
  "hex" => Utils::Elixir::Version,
39
36
  "cargo" => Utils::Rust::Version,
@@ -61,7 +58,6 @@ module Dependabot
61
58
  "maven" => Utils::Java::Requirement,
62
59
  "gradle" => Utils::Java::Requirement,
63
60
  "npm_and_yarn" => Utils::JavaScript::Requirement,
64
- "pip" => Utils::Python::Requirement,
65
61
  "composer" => Utils::Php::Requirement,
66
62
  "hex" => Utils::Elixir::Requirement,
67
63
  "cargo" => Utils::Rust::Requirement,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dependabot
4
- VERSION = "0.78.0"
4
+ VERSION = "0.79.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.78.0
4
+ version: 0.79.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-07 00:00:00.000000000 Z
11
+ date: 2018-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-ecr
@@ -340,11 +340,6 @@ files:
340
340
  - helpers/php/src/Hasher.php
341
341
  - helpers/php/src/UpdateChecker.php
342
342
  - helpers/php/src/Updater.php
343
- - helpers/python/lib/__init__.py
344
- - helpers/python/lib/hasher.py
345
- - helpers/python/lib/parser.py
346
- - helpers/python/requirements.txt
347
- - helpers/python/run.py
348
343
  - helpers/test/run.rb
349
344
  - helpers/utils/git-credential-store-immutable
350
345
  - helpers/yarn/.eslintrc
@@ -393,7 +388,6 @@ files:
393
388
  - lib/dependabot/file_fetchers/java_script/npm_and_yarn.rb
394
389
  - lib/dependabot/file_fetchers/java_script/npm_and_yarn/path_dependency_builder.rb
395
390
  - lib/dependabot/file_fetchers/php/composer.rb
396
- - lib/dependabot/file_fetchers/python/pip.rb
397
391
  - lib/dependabot/file_fetchers/ruby/bundler.rb
398
392
  - lib/dependabot/file_fetchers/ruby/bundler/child_gemfile_finder.rb
399
393
  - lib/dependabot/file_fetchers/ruby/bundler/path_gemspec_finder.rb
@@ -420,10 +414,6 @@ files:
420
414
  - lib/dependabot/file_parsers/java/maven/repositories_finder.rb
421
415
  - lib/dependabot/file_parsers/java_script/npm_and_yarn.rb
422
416
  - lib/dependabot/file_parsers/php/composer.rb
423
- - lib/dependabot/file_parsers/python/pip.rb
424
- - lib/dependabot/file_parsers/python/pip/pipfile_files_parser.rb
425
- - lib/dependabot/file_parsers/python/pip/poetry_files_parser.rb
426
- - lib/dependabot/file_parsers/python/pip/setup_file_parser.rb
427
417
  - lib/dependabot/file_parsers/ruby/bundler.rb
428
418
  - lib/dependabot/file_parsers/ruby/bundler/file_preparer.rb
429
419
  - lib/dependabot/file_parsers/ruby/bundler/gemfile_checker.rb
@@ -464,16 +454,6 @@ files:
464
454
  - lib/dependabot/file_updaters/php/composer.rb
465
455
  - lib/dependabot/file_updaters/php/composer/lockfile_updater.rb
466
456
  - lib/dependabot/file_updaters/php/composer/manifest_updater.rb
467
- - lib/dependabot/file_updaters/python/pip.rb
468
- - lib/dependabot/file_updaters/python/pip/pip_compile_file_updater.rb
469
- - lib/dependabot/file_updaters/python/pip/pipfile_file_updater.rb
470
- - lib/dependabot/file_updaters/python/pip/pipfile_preparer.rb
471
- - lib/dependabot/file_updaters/python/pip/poetry_file_updater.rb
472
- - lib/dependabot/file_updaters/python/pip/pyproject_preparer.rb
473
- - lib/dependabot/file_updaters/python/pip/requirement_file_updater.rb
474
- - lib/dependabot/file_updaters/python/pip/requirement_replacer.rb
475
- - lib/dependabot/file_updaters/python/pip/setup_file_sanitizer.rb
476
- - lib/dependabot/file_updaters/ruby/.DS_Store
477
457
  - lib/dependabot/file_updaters/ruby/bundler.rb
478
458
  - lib/dependabot/file_updaters/ruby/bundler/gemfile_updater.rb
479
459
  - lib/dependabot/file_updaters/ruby/bundler/gemspec_dependency_name_finder.rb
@@ -501,7 +481,6 @@ files:
501
481
  - lib/dependabot/metadata_finders/java/maven.rb
502
482
  - lib/dependabot/metadata_finders/java_script/npm_and_yarn.rb
503
483
  - lib/dependabot/metadata_finders/php/composer.rb
504
- - lib/dependabot/metadata_finders/python/pip.rb
505
484
  - lib/dependabot/metadata_finders/ruby/bundler.rb
506
485
  - lib/dependabot/metadata_finders/rust/cargo.rb
507
486
  - lib/dependabot/pull_request_creator.rb
@@ -555,12 +534,6 @@ files:
555
534
  - lib/dependabot/update_checkers/php/composer.rb
556
535
  - lib/dependabot/update_checkers/php/composer/requirements_updater.rb
557
536
  - lib/dependabot/update_checkers/php/composer/version_resolver.rb
558
- - lib/dependabot/update_checkers/python/pip.rb
559
- - lib/dependabot/update_checkers/python/pip/latest_version_finder.rb
560
- - lib/dependabot/update_checkers/python/pip/pip_compile_version_resolver.rb
561
- - lib/dependabot/update_checkers/python/pip/pipfile_version_resolver.rb
562
- - lib/dependabot/update_checkers/python/pip/poetry_version_resolver.rb
563
- - lib/dependabot/update_checkers/python/pip/requirements_updater.rb
564
537
  - lib/dependabot/update_checkers/ruby/bundler.rb
565
538
  - lib/dependabot/update_checkers/ruby/bundler/file_preparer.rb
566
539
  - lib/dependabot/update_checkers/ruby/bundler/force_updater.rb
@@ -590,14 +563,10 @@ files:
590
563
  - lib/dependabot/utils/java_script/version.rb
591
564
  - lib/dependabot/utils/php/requirement.rb
592
565
  - lib/dependabot/utils/php/version.rb
593
- - lib/dependabot/utils/python/requirement.rb
594
- - lib/dependabot/utils/python/version.rb
595
566
  - lib/dependabot/utils/ruby/requirement.rb
596
567
  - lib/dependabot/utils/rust/requirement.rb
597
568
  - lib/dependabot/utils/rust/version.rb
598
569
  - lib/dependabot/version.rb
599
- - lib/python_requirement_parser.rb
600
- - lib/python_versions.rb
601
570
  homepage: https://github.com/dependabot/dependabot-core
602
571
  licenses:
603
572
  - Nonstandard
@@ -618,7 +587,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
618
587
  version: 2.7.3
619
588
  requirements: []
620
589
  rubyforge_project:
621
- rubygems_version: 2.7.8
590
+ rubygems_version: 2.7.7
622
591
  signing_key:
623
592
  specification_version: 4
624
593
  summary: Automated dependency management
File without changes
@@ -1,23 +0,0 @@
1
- import hashin
2
- import json
3
- import pipfile
4
- from poetry.poetry import Poetry
5
-
6
- def get_dependency_hash(dependency_name, dependency_version, algorithm):
7
- hashes = hashin.get_package_hashes(
8
- dependency_name,
9
- version=dependency_version,
10
- algorithm=algorithm
11
- )
12
-
13
- return json.dumps({ "result": hashes["hashes"] })
14
-
15
- def get_pipfile_hash(directory):
16
- p = pipfile.load(directory + '/Pipfile')
17
-
18
- return json.dumps({ "result": p.hash })
19
-
20
- def get_pyproject_hash(directory):
21
- p = Poetry.create(directory)
22
-
23
- return json.dumps({ "result": p.locker._get_content_hash() })
@@ -1,130 +0,0 @@
1
- from itertools import chain
2
- import glob
3
- import io
4
- import json
5
- import os.path
6
- import re
7
-
8
- import setuptools
9
- import pip._internal.req.req_file
10
- from pip._internal.download import PipSession
11
- from pip._internal.req.constructors import install_req_from_line
12
-
13
- def parse_requirements(directory):
14
- # Parse the requirements.txt
15
- requirement_packages = []
16
-
17
- requirement_files = glob.glob(os.path.join(directory, '*.txt')) \
18
- + glob.glob(os.path.join(directory, '**', '*.txt'))
19
-
20
- pip_compile_files = glob.glob(os.path.join(directory, '*.in')) \
21
- + glob.glob(os.path.join(directory, '**', '*.in'))
22
-
23
- for reqs_file in requirement_files + pip_compile_files:
24
- try:
25
- requirements = pip._internal.req.req_file.parse_requirements(
26
- reqs_file,
27
- session=PipSession()
28
- )
29
- for install_req in requirements:
30
- if install_req.original_link:
31
- continue
32
- if install_req.is_pinned:
33
- version = next(iter(install_req.specifier)).version
34
- else:
35
- version = None
36
-
37
- pattern = r"-[cr] (.*) \(line \d+\)"
38
- abs_path = re.search(pattern, install_req.comes_from).group(1)
39
- rel_path = os.path.relpath(abs_path, directory)
40
-
41
- requirement_packages.append({
42
- "name": install_req.req.name,
43
- "version": version,
44
- "markers": str(install_req.markers) or None,
45
- "file": rel_path,
46
- "requirement": str(install_req.specifier) or None
47
- })
48
- except Exception as e:
49
- print(json.dumps({ "error": repr(e) }))
50
- exit(1)
51
-
52
- return json.dumps({ "result": requirement_packages })
53
-
54
- def parse_setup(directory):
55
- # Parse the setup.py
56
- setup_packages = []
57
- if os.path.isfile(directory + '/setup.py'):
58
- def parse_requirement(req, req_type):
59
- install_req = install_req_from_line(req)
60
- if install_req.original_link:
61
- return
62
- if install_req.is_pinned:
63
- version = next(iter(install_req.specifier)).version
64
- else:
65
- version = None
66
- setup_packages.append({
67
- "name": install_req.req.name,
68
- "version": version,
69
- "markers": str(install_req.markers) or None,
70
- "file": "setup.py",
71
- "requirement": str(install_req.specifier) or None,
72
- "requirement_type": req_type
73
- })
74
-
75
- def setup(*args, **kwargs):
76
- for arg in ['setup_requires', 'install_requires', 'tests_require']:
77
- if not kwargs.get(arg):
78
- continue
79
- for req in kwargs.get(arg):
80
- parse_requirement(req, arg)
81
- extras_require_dict = kwargs.get('extras_require', {})
82
- for key in extras_require_dict:
83
- for req in extras_require_dict[key]:
84
- parse_requirement(req, 'extras_require:{}'.format(key))
85
- setuptools.setup = setup
86
-
87
- def noop(*args, **kwargs):
88
- pass
89
-
90
- def fake_parse(*args, **kwargs):
91
- return []
92
-
93
- global fake_open
94
- def fake_open(*args, **kwargs):
95
- content = ("VERSION = ('0', '0', '1+dependabot')\n"
96
- "__version__ = '0.0.1+dependabot'\n"
97
- "__author__ = 'someone'\n"
98
- "__title__ = 'something'\n"
99
- "__description__ = 'something'\n"
100
- "__author_email__ = 'something'\n"
101
- "__license__ = 'something'\n"
102
- "__url__ = 'something'\n")
103
- return io.StringIO(content)
104
-
105
- content = open(directory + '/setup.py', 'r').read()
106
-
107
- # Remove `print`, `open`, `log` and import statements
108
- content = re.sub(r"print\s*\(", "noop(", content)
109
- content = re.sub(r"log\s*(\.\w+)*\(", "noop(", content)
110
- content = re.sub(r"\b(\w+\.)*(open|file)\s*\(", "fake_open(", content)
111
- content = content.replace("parse_requirements(", "fake_parse(")
112
- version_re = re.compile(r"^.*import.*__version__.*$", re.MULTILINE)
113
- content = re.sub(version_re, "", content)
114
-
115
- # Set variables likely to be imported
116
- __version__ = '0.0.1+dependabot'
117
- __author__ = 'someone'
118
- __title__ = 'something'
119
- __description__ = 'something'
120
- __author_email__ = 'something'
121
- __license__ = 'something'
122
- __url__ = 'something'
123
-
124
- # Run as main (since setup.py is a script)
125
- __name__ = '__main__'
126
-
127
- # Exec the setup.py
128
- exec(content) in globals(), locals()
129
-
130
- return json.dumps({ "result": setup_packages })
@@ -1,9 +0,0 @@
1
- pip==18.1
2
- pip-tools==3.1.0
3
- hashin==0.14.0
4
- pipenv==2018.11.26
5
- pipfile==0.0.2
6
- poetry==0.12.10
7
-
8
- # Some dependencies will only install if Cython is present
9
- Cython==0.29.1
@@ -1,18 +0,0 @@
1
- import sys
2
- import json
3
-
4
- from lib import parser, hasher
5
-
6
- if __name__ == "__main__":
7
- args = json.loads(sys.stdin.read())
8
-
9
- if args["function"] == "parse_requirements":
10
- print(parser.parse_requirements(args["args"][0]))
11
- if args["function"] == "parse_setup":
12
- print(parser.parse_setup(args["args"][0]))
13
- elif args["function"] == "get_dependency_hash":
14
- print(hasher.get_dependency_hash(*args["args"]))
15
- elif args["function"] == "get_pipfile_hash":
16
- print(hasher.get_pipfile_hash(*args["args"]))
17
- elif args["function"] == "get_pyproject_hash":
18
- print(hasher.get_pyproject_hash(*args["args"]))
@@ -1,305 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "toml-rb"
4
-
5
- require "dependabot/file_fetchers/base"
6
- require "dependabot/file_parsers/python/pip"
7
- require "dependabot/errors"
8
-
9
- module Dependabot
10
- module FileFetchers
11
- module Python
12
- class Pip < Dependabot::FileFetchers::Base
13
- CHILD_REQUIREMENT_REGEX = /^-r\s?(?<path>.*\.txt)/.freeze
14
- CONSTRAINT_REGEX = /^-c\s?(?<path>\..*)/.freeze
15
-
16
- def self.required_files_in?(filenames)
17
- return true if filenames.any? { |name| name.end_with?(".txt", ".in") }
18
-
19
- # If there is a directory of requirements return true
20
- return true if filenames.include?("requirements")
21
-
22
- # If this repo is using a Pipfile return true
23
- return true if filenames.include?("Pipfile")
24
-
25
- # If this repo is using Poetry return true
26
- return true if filenames.include?("pyproject.toml")
27
-
28
- filenames.include?("setup.py")
29
- end
30
-
31
- def self.required_files_message
32
- "Repo must contain a requirements.txt, setup.py, pyproject.toml, "\
33
- "or a Pipfile."
34
- end
35
-
36
- private
37
-
38
- def fetch_files
39
- fetched_files = []
40
-
41
- fetched_files += pipenv_files
42
- fetched_files += pyproject_files
43
-
44
- fetched_files += requirements_in_files
45
- fetched_files += requirement_files if requirements_txt_files.any?
46
-
47
- fetched_files << setup_file if setup_file
48
- fetched_files << setup_cfg if setup_cfg
49
- fetched_files += path_setup_files
50
- fetched_files << pip_conf if pip_conf
51
- fetched_files << python_version if python_version
52
-
53
- check_required_files_present
54
- fetched_files.uniq
55
- end
56
-
57
- def pipenv_files
58
- [pipfile, pipfile_lock].compact
59
- end
60
-
61
- def pyproject_files
62
- [pyproject, pyproject_lock, poetry_lock].compact
63
- end
64
-
65
- def requirement_files
66
- [
67
- *requirements_txt_files,
68
- *child_requirement_files,
69
- *constraints_files
70
- ]
71
- end
72
-
73
- def check_required_files_present
74
- if requirements_txt_files.any? || setup_file || pipfile || pyproject
75
- return
76
- end
77
-
78
- path = Pathname.new(File.join(directory, "requirements.txt")).
79
- cleanpath.to_path
80
- raise Dependabot::DependencyFileNotFound, path
81
- end
82
-
83
- def setup_file
84
- @setup_file ||= fetch_file_if_present("setup.py")
85
- end
86
-
87
- def setup_cfg
88
- @setup_cfg ||= fetch_file_if_present("setup.cfg")
89
- end
90
-
91
- def pip_conf
92
- @pip_conf ||= fetch_file_if_present("pip.conf")&.
93
- tap { |f| f.support_file = true }
94
- end
95
-
96
- def python_version
97
- @python_version ||= fetch_file_if_present(".python-version")&.
98
- tap { |f| f.support_file = true }
99
- end
100
-
101
- def pipfile
102
- @pipfile ||= fetch_file_if_present("Pipfile")
103
- end
104
-
105
- def pipfile_lock
106
- @pipfile_lock ||= fetch_file_if_present("Pipfile.lock")
107
- end
108
-
109
- def pyproject
110
- @pyproject ||= fetch_file_if_present("pyproject.toml")
111
- end
112
-
113
- def pyproject_lock
114
- @pyproject_lock ||= fetch_file_if_present("pyproject.lock")
115
- end
116
-
117
- def poetry_lock
118
- @poetry_lock ||= fetch_file_if_present("poetry.lock")
119
- end
120
-
121
- def requirements_txt_files
122
- req_txt_and_in_files.select { |f| f.name.end_with?(".txt") }
123
- end
124
-
125
- def requirements_in_files
126
- req_txt_and_in_files.select { |f| f.name.end_with?(".in") }
127
- end
128
-
129
- def parsed_pipfile
130
- raise "No Pipfile" unless pipfile
131
-
132
- @parsed_pipfile ||= TomlRB.parse(pipfile.content)
133
- rescue TomlRB::ParseError
134
- raise Dependabot::DependencyFileNotParseable, pipfile.path
135
- end
136
-
137
- def req_txt_and_in_files
138
- return @req_txt_and_in_files if @req_txt_and_in_files
139
-
140
- @req_txt_and_in_files = []
141
-
142
- repo_contents.
143
- select { |f| f.type == "file" }.
144
- select { |f| f.name.end_with?(".txt", ".in") }.
145
- map { |f| fetch_file_from_host(f.name) }.
146
- select { |f| requirements_file?(f) }.
147
- each { |f| @req_txt_and_in_files << f }
148
-
149
- repo_contents.
150
- select { |f| f.type == "dir" }.
151
- each { |f| @req_txt_and_in_files += req_files_for_dir(f) }
152
-
153
- @req_txt_and_in_files
154
- end
155
-
156
- def req_files_for_dir(requirements_dir)
157
- dir = directory.gsub(%r{(^/|/$)}, "")
158
- relative_reqs_dir =
159
- requirements_dir.path.gsub(%r{^/?#{Regexp.escape(dir)}/?}, "")
160
-
161
- repo_contents(dir: relative_reqs_dir).
162
- select { |f| f.type == "file" }.
163
- select { |f| f.name.end_with?(".txt", ".in") }.
164
- map { |f| fetch_file_from_host("#{relative_reqs_dir}/#{f.name}") }.
165
- select { |f| requirements_file?(f) }
166
- end
167
-
168
- def child_requirement_files
169
- @child_requirement_files ||=
170
- begin
171
- fetched_files = requirements_txt_files.dup
172
- requirements_txt_files.flat_map do |requirement_file|
173
- child_files = fetch_child_requirement_files(
174
- file: requirement_file,
175
- previously_fetched_files: fetched_files
176
- )
177
-
178
- fetched_files += child_files
179
- child_files
180
- end
181
- end
182
- end
183
-
184
- def fetch_child_requirement_files(file:, previously_fetched_files:)
185
- paths = file.content.scan(CHILD_REQUIREMENT_REGEX).flatten
186
- current_dir = File.dirname(file.name)
187
-
188
- paths.flat_map do |path|
189
- path = File.join(current_dir, path) unless current_dir == "."
190
- path = Pathname.new(path).cleanpath.to_path
191
-
192
- next if previously_fetched_files.map(&:name).include?(path)
193
- next if file.name == path
194
-
195
- fetched_file = fetch_file_from_host(path)
196
- grandchild_requirement_files = fetch_child_requirement_files(
197
- file: fetched_file,
198
- previously_fetched_files: previously_fetched_files + [file]
199
- )
200
- [fetched_file, *grandchild_requirement_files]
201
- end.compact
202
- end
203
-
204
- def constraints_files
205
- all_requirement_files = requirements_txt_files +
206
- child_requirement_files
207
-
208
- constraints_paths = all_requirement_files.map do |req_file|
209
- req_file.content.scan(CONSTRAINT_REGEX).flatten
210
- end.flatten.uniq
211
-
212
- constraints_paths.map { |path| fetch_file_from_host(path) }
213
- end
214
-
215
- def path_setup_files
216
- path_setup_files = []
217
- unfetchable_files = []
218
-
219
- path_setup_file_paths.each do |path|
220
- path = Pathname.new(File.join(path, "setup.py")).cleanpath.to_path
221
- next if path == "setup.py" && setup_file
222
-
223
- begin
224
- path_setup_files << fetch_file_from_host(path).
225
- tap { |f| f.support_file = true }
226
- rescue Dependabot::DependencyFileNotFound
227
- unfetchable_files << path
228
- end
229
-
230
- begin
231
- cfg_path = path.gsub(/\.py$/, ".cfg")
232
- path_setup_files << fetch_file_from_host(cfg_path).
233
- tap { |f| f.support_file = true }
234
- rescue Dependabot::DependencyFileNotFound
235
- # Ignore lack of a setup.cfg
236
- nil
237
- end
238
- end
239
-
240
- if unfetchable_files.any?
241
- raise Dependabot::PathDependenciesNotReachable, unfetchable_files
242
- end
243
-
244
- path_setup_files
245
- end
246
-
247
- def requirements_file?(file)
248
- return true if file.name.match?(/requirements/x)
249
-
250
- content = file.content.
251
- gsub(CONSTRAINT_REGEX, "").
252
- gsub(CHILD_REQUIREMENT_REGEX, "")
253
-
254
- tmp_file = DependencyFile.new(name: file.name, content: content)
255
- Dependabot::FileParsers::Python::Pip.
256
- new(dependency_files: [tmp_file], source: source).
257
- parse.any?
258
- rescue Dependabot::DependencyFileNotEvaluatable
259
- false
260
- end
261
-
262
- def path_setup_file_paths
263
- requirement_txt_path_setup_file_paths + pipfile_path_setup_file_paths
264
- end
265
-
266
- def requirement_txt_path_setup_file_paths
267
- (requirements_txt_files + child_requirement_files).map do |req_file|
268
- uneditable_reqs =
269
- req_file.content.
270
- scan(/^['"]?(?<path>\..*?)(?=\[|#|'|"|$)/).
271
- flatten.
272
- map(&:strip).
273
- reject { |p| p.include?("://") }
274
-
275
- editable_reqs =
276
- req_file.content.
277
- scan(/^(?:-e)\s+['"]?(?<path>.*?)(?=\[|#|'|"|$)/).
278
- flatten.
279
- map(&:strip).
280
- reject { |p| p.include?("://") }
281
-
282
- uneditable_reqs + editable_reqs
283
- end.flatten.uniq
284
- end
285
-
286
- def pipfile_path_setup_file_paths
287
- return [] unless pipfile
288
-
289
- paths = []
290
- %w(packages dev-packages).each do |dep_type|
291
- next unless parsed_pipfile[dep_type]
292
-
293
- parsed_pipfile[dep_type].each do |_, req|
294
- next unless req.is_a?(Hash) && req["path"]
295
-
296
- paths << req["path"]
297
- end
298
- end
299
-
300
- paths
301
- end
302
- end
303
- end
304
- end
305
- end