代码拉取完成,页面将自动刷新
同步操作将从 guanguans/music-dl 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#!/usr/bin/env php
<?php
declare(strict_types=1);
/**
* This file is part of the guanguans/music-dl.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/
use Composer\InstalledVersions;
use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\SingleCommandApplication;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Process\ExecutableFinder;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;
require __DIR__.'/vendor/autoload.php';
/** @noinspection PhpUnhandledExceptionInspection */
$status = (new SingleCommandApplication())
->setName('Composer Updater')
->addOption('composer-json-path', null, InputOption::VALUE_OPTIONAL)
->addOption('highest-php-binary', null, InputOption::VALUE_REQUIRED)
->addOption('composer-binary', null, InputOption::VALUE_OPTIONAL)
->addOption('except-packages', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL)
->addOption('except-dependency-versions', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL)
->addOption('dry-run', null, InputOption::VALUE_NONE)
->setCode(function (InputInterface $input, OutputInterface $output): void {
assert_options(ASSERT_BAIL, 1);
assert($this instanceof SingleCommandApplication);
assert((bool) $input->getOption('highest-php-binary'));
(new class(
$input->getOption('composer-json-path') ?: __DIR__.'/composer.json',
$input->getOption('highest-php-binary'),
$input->getOption('composer-binary'),
$input->getOption('except-packages'),
$input->getOption('except-dependency-versions'),
$input->getOption('dry-run'),
new SymfonyStyle($input, $output),
new Differ(new UnifiedDiffOutputBuilder("--- Original\n+++ New\n", true)),
) {
private string $composerJsonContents;
private string $highestComposerBinary;
private string $composerBinary;
private array $exceptPackages;
private array $exceptDependencyVersions;
private SymfonyStyle $symfonyStyle;
private Differ $differ;
/**
* @noinspection ParameterDefaultsNullInspection
*/
public function __construct(
private string $composerJsonPath,
?string $highestPhpBinary = null,
?string $composerBinary = null,
array $exceptPackages = [],
array $exceptDependencyVersions = [],
private bool $dryRun = false,
?SymfonyStyle $symfonyStyle = null,
?Differ $differ = null
) {
assert_options(ASSERT_BAIL, 1);
assert((bool) $composerJsonPath);
$this->composerJsonContents = file_get_contents($composerJsonPath);
$this->highestComposerBinary = $this->getComposerBinary($composerBinary, $highestPhpBinary);
$this->composerBinary = $this->getComposerBinary($composerBinary);
$this->exceptPackages = array_merge([
'php',
'ext-*',
], $exceptPackages);
$this->exceptDependencyVersions = array_merge([
'\*',
'*-*',
'*@*',
// '*|*',
], $exceptDependencyVersions);
$this->symfonyStyle = $symfonyStyle ?? new SymfonyStyle(new ArgvInput(), new ConsoleOutput());
$this->differ = $differ ?? new Differ(new UnifiedDiffOutputBuilder("--- Original\n+++ New\n", true));
}
public function __invoke(): void
{
$this
->updateComposerPackages()
->updateOutdatedComposerPackages()
->updateComposerPackages()
->updateOutdatedComposerPackages()
->updateComposerPackages()
->normalizeComposerJson()
->success();
}
private function updateComposerPackages(): self
{
$this->mustRunCommand("$this->composerBinary update -W --ansi");
return $this;
}
/**
* @noinspection JsonEncodingApiUsageInspection
*
* @return $this|never-return
*/
private function updateOutdatedComposerPackages(): self
{
$outdatedComposerJsonContents = json_encode(
$this->getOutdatedDecodedComposerJson(),
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
).PHP_EOL;
if ($this->dryRun) {
$this->symfonyStyle->writeln($this->formatDiff($this->differ->diff(
$this->composerJsonContents,
$outdatedComposerJsonContents
)));
exit(0);
}
file_put_contents($this->composerJsonPath, $outdatedComposerJsonContents);
return $this;
}
private function normalizeComposerJson(): self
{
$this->mustRunCommand("$this->composerBinary normalize --diff --ansi");
return $this;
}
private function success(): void
{
$this->symfonyStyle->success('Composer packages updated successfully!');
}
/**
* @noinspection JsonEncodingApiUsageInspection
*/
private function getOutdatedDecodedComposerJson(): array
{
$outdatedComposerPackages = $this->getOutdatedComposerPackages();
$decodedComposerJson = json_decode(file_get_contents($this->composerJsonPath), true);
(fn () => self::reload(null))->call(new InstalledVersions());
foreach ($decodedComposerJson as $name => &$value) {
if (! in_array($name, ['require', 'require-dev'], true)) {
continue;
}
foreach ($value as $package => &$dependencyVersion) {
if (
$this->strIs($this->exceptPackages, $package)
|| $this->strIs($this->exceptDependencyVersions, $dependencyVersion)
) {
continue;
}
if ($version = InstalledVersions::getVersion($package)) {
$dependencyVersion = $this->toDependencyVersion($version);
}
if (isset($outdatedComposerPackages[$package])) {
$dependencyVersion = $outdatedComposerPackages[$package]['dependency_version'];
}
}
}
return $decodedComposerJson;
}
/**
* @noinspection JsonEncodingApiUsageInspection
*/
private function getOutdatedComposerPackages(): array
{
return array_reduce(
json_decode(
$this
->mustRunCommand("$this->highestComposerBinary outdated --format=json --direct --ansi")
->getOutput(),
true
)['installed'],
function (array $carry, array $package): array {
$lowestArrayVersion = $this->toArrayVersion($package['version']);
$highestArrayVersion = $this->toArrayVersion($package['latest']);
$dependencyVersions = [$this->toDependencyVersion($package['version'])];
if ($lowestArrayVersion[0] !== $highestArrayVersion[0]) {
$dependencyVersions = array_merge($dependencyVersions, array_map(
static fn (string $major): string => "^$major.0",
range($lowestArrayVersion[0] + 1, $highestArrayVersion[0])
));
}
$package['dependency_version'] = implode(' || ', $dependencyVersions);
$carry[$package['name']] = $package;
return $carry;
},
[]
);
}
private function getComposerBinary(?string $composerBinary = null, ?string $phpBinary = null): string
{
return sprintf(
'%s %s',
$phpBinary ?? (new PhpExecutableFinder())->find(),
$composerBinary ?? (new ExecutableFinder())->find('composer')
);
}
/**
* @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input
*
* @noinspection MissingParameterTypeDeclarationInspection
* @noinspection PhpSameParameterValueInspection
*/
private function mustRunCommand(
array|string $command,
?string $cwd = null,
?array $env = null,
mixed $input = null,
?float $timeout = 300
): Process {
$process = is_string($command)
? Process::fromShellCommandline($command, $cwd, $env, $input, $timeout)
: new Process($command, $cwd, $env, $input, $timeout);
$this->symfonyStyle->warning($process->getCommandLine());
return $process
->setWorkingDirectory(dirname($this->composerJsonPath))
->setEnv(['COMPOSER_MEMORY_LIMIT' => -1])
->mustRun(function (string $type, string $buffer): void {
$this->symfonyStyle->isVerbose() and $this->symfonyStyle->write($buffer);
});
}
private function toDependencyVersion(string $version): string
{
return '^'.implode('.', array_slice($this->toArrayVersion($version), 0, 2));
}
private function toArrayVersion(string $version): array
{
return explode('.', ltrim($version, 'v'));
}
/**
* @noinspection SuspiciousLoopInspection
* @noinspection ComparisonScalarOrderInspection
* @noinspection MissingParameterTypeDeclarationInspection
*/
private function strIs(array|string $pattern, string $value): bool
{
$patterns = (array) $pattern;
if (empty($patterns)) {
return false;
}
foreach ($patterns as $pattern) {
$pattern = (string) $pattern;
if ($pattern === $value) {
return true;
}
$pattern = preg_quote($pattern, '#');
$pattern = str_replace('\*', '.*', $pattern);
if (1 === preg_match('#^'.$pattern.'\z#u', $value)) {
return true;
}
}
return false;
}
private function formatDiff(string $diff): string
{
$lines = explode(
"\n",
$diff,
);
$formatted = array_map(static function (string $line): string {
return preg_replace(
[
'/^(\+.*)$/',
'/^(-.*)$/',
],
[
'<fg=green>$1</>',
'<fg=red>$1</>',
],
$line,
);
}, $lines);
return implode(
"\n",
$formatted,
);
}
})();
})
->run();
exit($status);
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。