dependabot-composer 0.89.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/.php_cs +32 -0
- data/helpers/bin/run.php +84 -0
- data/helpers/build +14 -0
- data/helpers/composer.json +14 -0
- data/helpers/composer.lock +1528 -0
- data/helpers/php/.php_cs +34 -0
- data/helpers/setup.sh +4 -0
- data/helpers/src/DependabotInstallationManager.php +61 -0
- data/helpers/src/DependabotPluginManager.php +23 -0
- data/helpers/src/ExceptionIO.php +25 -0
- data/helpers/src/Hasher.php +21 -0
- data/helpers/src/UpdateChecker.php +123 -0
- data/helpers/src/Updater.php +97 -0
- data/lib/dependabot/composer.rb +11 -0
- data/lib/dependabot/composer/file_fetcher.rb +132 -0
- data/lib/dependabot/composer/file_parser.rb +179 -0
- data/lib/dependabot/composer/file_updater.rb +78 -0
- data/lib/dependabot/composer/file_updater/lockfile_updater.rb +267 -0
- data/lib/dependabot/composer/file_updater/manifest_updater.rb +66 -0
- data/lib/dependabot/composer/metadata_finder.rb +68 -0
- data/lib/dependabot/composer/native_helpers.rb +20 -0
- data/lib/dependabot/composer/requirement.rb +98 -0
- data/lib/dependabot/composer/update_checker.rb +176 -0
- data/lib/dependabot/composer/update_checker/requirements_updater.rb +253 -0
- data/lib/dependabot/composer/update_checker/version_resolver.rb +214 -0
- data/lib/dependabot/composer/version.rb +26 -0
- metadata +195 -0
data/helpers/php/.php_cs
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
$finder = PhpCsFixer\Finder::create()
|
4
|
+
->in(__DIR__ . '/src')
|
5
|
+
->in(__DIR__ . '/bin');
|
6
|
+
|
7
|
+
return PhpCsFixer\Config::create()
|
8
|
+
->setRules([
|
9
|
+
'@Symfony' => true,
|
10
|
+
'array_syntax' => ['syntax' => 'short'],
|
11
|
+
'blank_line_after_opening_tag' => true,
|
12
|
+
'concat_space' => ['spacing' => 'one'],
|
13
|
+
'declare_strict_types' => true,
|
14
|
+
'increment_style' => ['style' => 'post'],
|
15
|
+
'is_null' => ['use_yoda_style' => false],
|
16
|
+
'list_syntax' => ['syntax' => 'short'],
|
17
|
+
'method_argument_space' => ['ensure_fully_multiline' => true],
|
18
|
+
'modernize_types_casting' => true,
|
19
|
+
'no_multiline_whitespace_before_semicolons' => true,
|
20
|
+
'no_useless_else' => true,
|
21
|
+
'no_useless_return' => true,
|
22
|
+
'ordered_imports' => true,
|
23
|
+
'phpdoc_align' => false,
|
24
|
+
'phpdoc_order' => true,
|
25
|
+
'php_unit_construct' => true,
|
26
|
+
'php_unit_dedicate_assert' => true,
|
27
|
+
'single_line_comment_style' => true,
|
28
|
+
'ternary_to_null_coalescing' => true,
|
29
|
+
'yoda_style' => false,
|
30
|
+
'void_return' => true,
|
31
|
+
])
|
32
|
+
->setFinder($finder)
|
33
|
+
->setUsingCache(true)
|
34
|
+
->setRiskyAllowed(true);
|
data/helpers/setup.sh
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
2
|
+
php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo hash_file('SHA384', 'composer-setup.php'); unlink('composer-setup.php'); } echo PHP_EOL;"
|
3
|
+
php composer-setup.php
|
4
|
+
php -r "unlink('composer-setup.php');"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
declare(strict_types=1);
|
4
|
+
|
5
|
+
namespace Dependabot\PHP;
|
6
|
+
|
7
|
+
use Composer\DependencyResolver\Operation\InstallOperation;
|
8
|
+
use Composer\DependencyResolver\Operation\UninstallOperation;
|
9
|
+
use Composer\DependencyResolver\Operation\UpdateOperation;
|
10
|
+
use Composer\Installer\InstallationManager;
|
11
|
+
use Composer\Package\PackageInterface;
|
12
|
+
use Composer\Repository\RepositoryInterface;
|
13
|
+
|
14
|
+
class DependabotInstallationManager extends InstallationManager
|
15
|
+
{
|
16
|
+
private $installed = [];
|
17
|
+
private $updated = [];
|
18
|
+
private $uninstalled = [];
|
19
|
+
|
20
|
+
public function install(RepositoryInterface $repo, InstallOperation $operation): void
|
21
|
+
{
|
22
|
+
parent::install($repo, $operation);
|
23
|
+
$this->installed[] = $operation->getPackage();
|
24
|
+
}
|
25
|
+
|
26
|
+
public function update(RepositoryInterface $repo, UpdateOperation $operation): void
|
27
|
+
{
|
28
|
+
parent::update($repo, $operation);
|
29
|
+
$this->updated[] = [$operation->getInitialPackage(), $operation->getTargetPackage()];
|
30
|
+
}
|
31
|
+
|
32
|
+
public function uninstall(RepositoryInterface $repo, UninstallOperation $operation): void
|
33
|
+
{
|
34
|
+
parent::uninstall($repo, $operation);
|
35
|
+
$this->uninstalled[] = $operation->getPackage();
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @return PackageInterface[]
|
40
|
+
*/
|
41
|
+
public function getInstalledPackages(): array
|
42
|
+
{
|
43
|
+
return $this->installed;
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* @return PackageInterface[]
|
48
|
+
*/
|
49
|
+
public function getUpdatedPackages(): array
|
50
|
+
{
|
51
|
+
return $this->updated;
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @return PackageInterface[]
|
56
|
+
*/
|
57
|
+
public function getUninstalledPackages(): array
|
58
|
+
{
|
59
|
+
return $this->uninstalled;
|
60
|
+
}
|
61
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
declare(strict_types=1);
|
4
|
+
|
5
|
+
namespace Dependabot\PHP;
|
6
|
+
|
7
|
+
use Composer\Package\PackageInterface;
|
8
|
+
use Composer\Plugin\PluginManager;
|
9
|
+
|
10
|
+
class DependabotPluginManager extends PluginManager
|
11
|
+
{
|
12
|
+
public function registerPackage(PackageInterface $package, $failOnMissingClasses = false): void
|
13
|
+
{
|
14
|
+
// This package does some setup for PHP_CodeSniffer, but errors out the
|
15
|
+
// install if Symfony isn't installed (which it won't be for a lockfile
|
16
|
+
// only install run). Safe to ignore
|
17
|
+
if (strpos($package->getName(), 'phpcodesniffer') !== false) {
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
|
21
|
+
parent::registerPackage($package, $failOnMissingClasses);
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
declare(strict_types=1);
|
4
|
+
|
5
|
+
namespace Dependabot\PHP;
|
6
|
+
|
7
|
+
use Composer\IO\NullIO;
|
8
|
+
|
9
|
+
class ExceptionIO extends NullIO
|
10
|
+
{
|
11
|
+
private $raise_next_error = false;
|
12
|
+
|
13
|
+
public function writeError($messages, $newline = true, $verbosity = self::NORMAL): void
|
14
|
+
{
|
15
|
+
if (is_array($messages)) {
|
16
|
+
return;
|
17
|
+
}
|
18
|
+
if ($this->raise_next_error) {
|
19
|
+
throw new \RuntimeException('Your requirements could not be resolved to an installable set of packages.' . $messages);
|
20
|
+
}
|
21
|
+
if (strpos($messages, 'Your requirements could not be resolved') !== false) {
|
22
|
+
$this->raise_next_error = true;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
declare(strict_types=1);
|
4
|
+
|
5
|
+
namespace Dependabot\PHP;
|
6
|
+
|
7
|
+
use Composer\Factory;
|
8
|
+
|
9
|
+
class Hasher
|
10
|
+
{
|
11
|
+
public static function getContentHash(array $args): ?string
|
12
|
+
{
|
13
|
+
[$workingDirectory] = $args;
|
14
|
+
|
15
|
+
$io = new ExceptionIO();
|
16
|
+
$composer = Factory::create($io, $workingDirectory . '/composer.json');
|
17
|
+
$locker = $composer->getLocker();
|
18
|
+
|
19
|
+
return $locker->getContentHash(file_get_contents(Factory::getComposerFile()));
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,123 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
declare(strict_types=1);
|
4
|
+
|
5
|
+
namespace Dependabot\PHP;
|
6
|
+
|
7
|
+
use Composer\Factory;
|
8
|
+
use Composer\Installer;
|
9
|
+
use Composer\Package\PackageInterface;
|
10
|
+
|
11
|
+
class UpdateChecker
|
12
|
+
{
|
13
|
+
public static function getLatestResolvableVersion(array $args): ?string
|
14
|
+
{
|
15
|
+
[$workingDirectory, $dependencyName, $gitCredentials, $registryCredentials] = $args;
|
16
|
+
|
17
|
+
$io = new ExceptionIO();
|
18
|
+
$composer = Factory::create($io, $workingDirectory . '/composer.json');
|
19
|
+
$config = $composer->getConfig();
|
20
|
+
$httpBasicCredentials = [];
|
21
|
+
|
22
|
+
foreach ($gitCredentials as &$cred) {
|
23
|
+
$httpBasicCredentials[$cred['host']] = [
|
24
|
+
'username' => $cred['username'],
|
25
|
+
'password' => $cred['password'],
|
26
|
+
];
|
27
|
+
}
|
28
|
+
|
29
|
+
foreach ($registryCredentials as &$cred) {
|
30
|
+
$httpBasicCredentials[$cred['registry']] = [
|
31
|
+
'username' => $cred['username'],
|
32
|
+
'password' => $cred['password'],
|
33
|
+
];
|
34
|
+
}
|
35
|
+
|
36
|
+
if ($httpBasicCredentials) {
|
37
|
+
$config->merge(
|
38
|
+
[
|
39
|
+
'config' => [
|
40
|
+
'http-basic' => $httpBasicCredentials,
|
41
|
+
],
|
42
|
+
]
|
43
|
+
);
|
44
|
+
$io->loadConfiguration($config);
|
45
|
+
}
|
46
|
+
|
47
|
+
$installationManager = new DependabotInstallationManager();
|
48
|
+
$install = new Installer(
|
49
|
+
$io,
|
50
|
+
$config,
|
51
|
+
$composer->getPackage(),
|
52
|
+
$composer->getDownloadManager(),
|
53
|
+
$composer->getRepositoryManager(),
|
54
|
+
$composer->getLocker(),
|
55
|
+
$installationManager,
|
56
|
+
$composer->getEventDispatcher(),
|
57
|
+
$composer->getAutoloadGenerator()
|
58
|
+
);
|
59
|
+
|
60
|
+
// For all potential options, see UpdateCommand in composer
|
61
|
+
$install
|
62
|
+
->setDryRun(true)
|
63
|
+
->setUpdate(true)
|
64
|
+
->setDevMode(true)
|
65
|
+
->setUpdateWhitelist([$dependencyName])
|
66
|
+
->setWhitelistTransitiveDependencies(true)
|
67
|
+
->setExecuteOperations(false)
|
68
|
+
->setDumpAutoloader(false)
|
69
|
+
->setRunScripts(false);
|
70
|
+
|
71
|
+
/*
|
72
|
+
* If a platform is set we assume people know what they are doing and we respect the setting.
|
73
|
+
* If no platform is set we ignore it so that the php we run as doesn't interfere
|
74
|
+
*/
|
75
|
+
if ($config->get('platform') === []) {
|
76
|
+
$install->setIgnorePlatformRequirements(true);
|
77
|
+
}
|
78
|
+
|
79
|
+
$install->run();
|
80
|
+
|
81
|
+
$installedPackages = $installationManager->getInstalledPackages();
|
82
|
+
|
83
|
+
$updatedPackage = current(array_filter($installedPackages, function (PackageInterface $package) use ($dependencyName) {
|
84
|
+
return $package->getName() == $dependencyName;
|
85
|
+
}));
|
86
|
+
|
87
|
+
// We found the package in the list of updated packages. Return its version.
|
88
|
+
if ($updatedPackage) {
|
89
|
+
return preg_replace('/^([v])/', '', $updatedPackage->getPrettyVersion());
|
90
|
+
}
|
91
|
+
|
92
|
+
// We didn't find the package in the list of updated packages. Check if
|
93
|
+
// it was replaced by another package (in which case we can ignore).
|
94
|
+
foreach ($composer->getPackage()->getReplaces() as $link) {
|
95
|
+
if ($link->getTarget() == $dependencyName) {
|
96
|
+
return null;
|
97
|
+
}
|
98
|
+
}
|
99
|
+
foreach ($installedPackages as $package) {
|
100
|
+
foreach ($package->getReplaces() as $link) {
|
101
|
+
if ($link->getTarget() == $dependencyName) {
|
102
|
+
return null;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
// Similarly, check if the package was provided by any other package.
|
108
|
+
foreach ($composer->getPackage()->getProvides() as $link) {
|
109
|
+
if ($link->getTarget() == $dependencyName) {
|
110
|
+
return preg_replace('/^([v])/', '', $link->getPrettyConstraint());
|
111
|
+
}
|
112
|
+
}
|
113
|
+
foreach ($installedPackages as $package) {
|
114
|
+
foreach ($package->getProvides() as $link) {
|
115
|
+
if ($link->getTarget() == $dependencyName) {
|
116
|
+
return preg_replace('/^([v])/', '', $link->getPrettyConstraint());
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
throw new \RuntimeException('Package not found in updated packages!');
|
122
|
+
}
|
123
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
declare(strict_types=1);
|
4
|
+
|
5
|
+
namespace Dependabot\PHP;
|
6
|
+
|
7
|
+
use Composer\Factory;
|
8
|
+
use Composer\Installer;
|
9
|
+
|
10
|
+
class Updater
|
11
|
+
{
|
12
|
+
public static function update(array $args): array
|
13
|
+
{
|
14
|
+
[$workingDirectory, $dependencyName, $dependencyVersion, $gitCredentials, $registryCredentials] = $args;
|
15
|
+
|
16
|
+
// Change working directory to the one provided, this ensures that we
|
17
|
+
// install dependencies into the working dir, rather than a vendor folder
|
18
|
+
// in the root of the project
|
19
|
+
$originalDir = getcwd();
|
20
|
+
chdir($workingDirectory);
|
21
|
+
|
22
|
+
$io = new ExceptionIO();
|
23
|
+
$composer = Factory::create($io);
|
24
|
+
$config = $composer->getConfig();
|
25
|
+
$httpBasicCredentials = [];
|
26
|
+
|
27
|
+
$pm = new DependabotPluginManager($io, $composer, null, false);
|
28
|
+
$composer->setPluginManager($pm);
|
29
|
+
$pm->loadInstalledPlugins();
|
30
|
+
|
31
|
+
foreach ($gitCredentials as &$cred) {
|
32
|
+
$httpBasicCredentials[$cred['host']] = [
|
33
|
+
'username' => $cred['username'],
|
34
|
+
'password' => $cred['password'],
|
35
|
+
];
|
36
|
+
}
|
37
|
+
|
38
|
+
foreach ($registryCredentials as &$cred) {
|
39
|
+
$httpBasicCredentials[$cred['registry']] = [
|
40
|
+
'username' => $cred['username'],
|
41
|
+
'password' => $cred['password'],
|
42
|
+
];
|
43
|
+
}
|
44
|
+
|
45
|
+
if ($httpBasicCredentials) {
|
46
|
+
$config->merge(
|
47
|
+
[
|
48
|
+
'config' => [
|
49
|
+
'http-basic' => $httpBasicCredentials,
|
50
|
+
],
|
51
|
+
]
|
52
|
+
);
|
53
|
+
$io->loadConfiguration($config);
|
54
|
+
}
|
55
|
+
|
56
|
+
$install = new Installer(
|
57
|
+
$io,
|
58
|
+
$config,
|
59
|
+
$composer->getPackage(),
|
60
|
+
$composer->getDownloadManager(),
|
61
|
+
$composer->getRepositoryManager(),
|
62
|
+
$composer->getLocker(),
|
63
|
+
$composer->getInstallationManager(),
|
64
|
+
$composer->getEventDispatcher(),
|
65
|
+
$composer->getAutoloadGenerator()
|
66
|
+
);
|
67
|
+
|
68
|
+
// For all potential options, see UpdateCommand in composer
|
69
|
+
$install
|
70
|
+
->setWriteLock(true)
|
71
|
+
->setUpdate(true)
|
72
|
+
->setDevMode(true)
|
73
|
+
->setUpdateWhitelist([$dependencyName])
|
74
|
+
->setWhitelistTransitiveDependencies(true)
|
75
|
+
->setExecuteOperations(false)
|
76
|
+
->setDumpAutoloader(false)
|
77
|
+
->setRunScripts(false);
|
78
|
+
|
79
|
+
/*
|
80
|
+
* If a platform is set we assume people know what they are doing and we respect the setting.
|
81
|
+
* If no platform is set we ignore it so that the php we run as doesn't interfere
|
82
|
+
*/
|
83
|
+
if ($config->get('platform') === []) {
|
84
|
+
$install->setIgnorePlatformRequirements(true);
|
85
|
+
}
|
86
|
+
|
87
|
+
$install->run();
|
88
|
+
|
89
|
+
$result = [
|
90
|
+
'composer.lock' => file_get_contents('composer.lock'),
|
91
|
+
];
|
92
|
+
|
93
|
+
chdir($originalDir);
|
94
|
+
|
95
|
+
return $result;
|
96
|
+
}
|
97
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# These all need to be required so the various classes can be registered in a
|
4
|
+
# lookup table of package manager names to concrete classes.
|
5
|
+
require "dependabot/composer/file_fetcher"
|
6
|
+
require "dependabot/composer/file_parser"
|
7
|
+
require "dependabot/composer/update_checker"
|
8
|
+
require "dependabot/composer/file_updater"
|
9
|
+
require "dependabot/composer/metadata_finder"
|
10
|
+
require "dependabot/composer/requirement"
|
11
|
+
require "dependabot/composer/version"
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dependabot/file_fetchers"
|
4
|
+
require "dependabot/file_fetchers/base"
|
5
|
+
|
6
|
+
module Dependabot
|
7
|
+
module Composer
|
8
|
+
class FileFetcher < Dependabot::FileFetchers::Base
|
9
|
+
def self.required_files_in?(filenames)
|
10
|
+
filenames.include?("composer.json")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.required_files_message
|
14
|
+
"Repo must contain a composer.json."
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def fetch_files
|
20
|
+
fetched_files = []
|
21
|
+
fetched_files << composer_json
|
22
|
+
fetched_files << composer_lock if composer_lock
|
23
|
+
fetched_files << auth_json if auth_json
|
24
|
+
fetched_files += path_dependencies
|
25
|
+
fetched_files
|
26
|
+
end
|
27
|
+
|
28
|
+
def composer_json
|
29
|
+
@composer_json ||= fetch_file_from_host("composer.json")
|
30
|
+
end
|
31
|
+
|
32
|
+
def composer_lock
|
33
|
+
return @composer_lock if @composer_lock_lookup_attempted
|
34
|
+
|
35
|
+
@composer_lock_lookup_attempted = true
|
36
|
+
@composer_lock ||= fetch_file_if_present("composer.lock")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Note: This is fetched but currently unused
|
40
|
+
def auth_json
|
41
|
+
@auth_json ||= fetch_file_if_present("auth.json")&.
|
42
|
+
tap { |f| f.support_file = true }
|
43
|
+
end
|
44
|
+
|
45
|
+
def path_dependencies
|
46
|
+
@path_dependencies ||=
|
47
|
+
begin
|
48
|
+
composer_json_files = []
|
49
|
+
unfetchable_deps = []
|
50
|
+
|
51
|
+
path_sources.each do |path|
|
52
|
+
directories = path.end_with?("*") ? expand_path(path) : [path]
|
53
|
+
|
54
|
+
directories.each do |dir|
|
55
|
+
file = File.join(dir, "composer.json")
|
56
|
+
|
57
|
+
begin
|
58
|
+
composer_json_files << fetch_file_with_root_fallback(file)
|
59
|
+
rescue Dependabot::DependencyFileNotFound
|
60
|
+
# Collected, but currently ignored
|
61
|
+
unfetchable_deps << file
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Mark the path dependencies as support files - we don't currently
|
67
|
+
# parse or update them.
|
68
|
+
composer_json_files.tap do |files|
|
69
|
+
files.each { |f| f.support_file = true }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def path_sources
|
75
|
+
@path_sources ||=
|
76
|
+
JSON.parse(composer_json.content).
|
77
|
+
fetch("repositories", []).
|
78
|
+
select { |details| details["type"] == "path" }.
|
79
|
+
map { |details| details["url"] }
|
80
|
+
rescue JSON::ParserError
|
81
|
+
raise Dependabot::DependencyFileNotParseable, composer_json.path
|
82
|
+
end
|
83
|
+
|
84
|
+
def expand_path(path)
|
85
|
+
repo_contents(dir: path.gsub(/\*$/, "")).
|
86
|
+
select { |file| file.type == "dir" }.
|
87
|
+
map { |f| path.gsub(/\*$/, f.name) }
|
88
|
+
rescue Octokit::NotFound, Gitlab::Error::NotFound
|
89
|
+
# If there's no lockfile, or if none of the dependencies are path
|
90
|
+
# dependencies, then we can ignore failures to find path deps
|
91
|
+
return [] unless composer_lock&.content&.include?('"path"')
|
92
|
+
|
93
|
+
# Otherwise, we don't know what to do. For now, just raise. If we see
|
94
|
+
# this in the wild we can make a call on the correct handling
|
95
|
+
raise if directory == "/"
|
96
|
+
|
97
|
+
# If the directory isn't found at the full path, try looking for it
|
98
|
+
# at the root of the repository.
|
99
|
+
depth = directory.gsub(%r{^/}, "").gsub(%r{/$}, "").split("/").count
|
100
|
+
dir = "../" * depth + path.gsub(/\*$/, "")
|
101
|
+
|
102
|
+
repo_contents(dir: dir).
|
103
|
+
select { |file| file.type == "dir" }.
|
104
|
+
map { |f| path.gsub(/\*$/, f.name) }
|
105
|
+
end
|
106
|
+
|
107
|
+
def fetch_file_with_root_fallback(filename, type: "file")
|
108
|
+
path = Pathname.new(File.join(directory, filename)).cleanpath.to_path
|
109
|
+
|
110
|
+
begin
|
111
|
+
fetch_file_from_host(filename, type: type)
|
112
|
+
rescue Dependabot::DependencyFileNotFound
|
113
|
+
# If the file isn't found at the full path, try looking for it
|
114
|
+
# without considering the directory (i.e., check if the path should
|
115
|
+
# have been relevative to the root of the repository).
|
116
|
+
cleaned_filename = Pathname.new(filename).cleanpath.to_path
|
117
|
+
|
118
|
+
DependencyFile.new(
|
119
|
+
name: cleaned_filename,
|
120
|
+
content: fetch_file_content(cleaned_filename),
|
121
|
+
directory: directory,
|
122
|
+
type: type
|
123
|
+
)
|
124
|
+
end
|
125
|
+
rescue Octokit::NotFound, Gitlab::Error::NotFound
|
126
|
+
raise Dependabot::DependencyFileNotFound, path
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
Dependabot::FileFetchers.register("composer", Dependabot::Composer::FileFetcher)
|