1
0
Fork 0

Merge branch '2.4'

pull/11150/head
Jordi Boggiano 2022-10-25 15:27:14 +02:00
commit 8ffd8bef08
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
7 changed files with 27 additions and 10 deletions

View File

@ -45,7 +45,7 @@ jobs:
- name: "Determine composer cache directory" - name: "Determine composer cache directory"
id: "determine-composer-cache-directory" id: "determine-composer-cache-directory"
run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" run: "echo \"directory=$(composer config cache-dir)\" >> $GITHUB_OUTPUT"
- name: "Cache dependencies installed with composer" - name: "Cache dependencies installed with composer"
uses: "actions/cache@v3" uses: "actions/cache@v3"

View File

@ -137,6 +137,8 @@ class Cache
*/ */
public function write(string $file, string $contents) public function write(string $file, string $contents)
{ {
$wasEnabled = $this->enabled === true;
if ($this->isEnabled() && !$this->readOnly) { if ($this->isEnabled() && !$this->readOnly) {
$file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file); $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
@ -146,6 +148,14 @@ class Cache
try { try {
return file_put_contents($tempFileName, $contents) !== false && rename($tempFileName, $this->root . $file); return file_put_contents($tempFileName, $contents) !== false && rename($tempFileName, $this->root . $file);
} catch (\ErrorException $e) { } catch (\ErrorException $e) {
// If the write failed despite isEnabled checks passing earlier, rerun the isEnabled checks to
// see if they are still current and recreate the cache dir if needed. Refs https://github.com/composer/composer/issues/11076
if ($wasEnabled) {
clearstatcache();
$this->enabled = null;
return $this->write($file, $contents);
}
$this->io->writeError('<warning>Failed to write into cache: '.$e->getMessage().'</warning>', true, IOInterface::DEBUG); $this->io->writeError('<warning>Failed to write into cache: '.$e->getMessage().'</warning>', true, IOInterface::DEBUG);
if (Preg::isMatch('{^file_put_contents\(\): Only ([0-9]+) of ([0-9]+) bytes written}', $e->getMessage(), $m)) { if (Preg::isMatch('{^file_put_contents\(\): Only ([0-9]+) of ([0-9]+) bytes written}', $e->getMessage(), $m)) {
// Remove partial file. // Remove partial file.

View File

@ -600,19 +600,19 @@ EOT
} }
} }
$io->write(''); $io->writeError('');
$io->write('<info>Direct dependencies required in composer.json:</>'); $io->writeError('<info>Direct dependencies required in composer.json:</>');
if (\count($directDeps) > 0) { if (\count($directDeps) > 0) {
$this->printPackages($io, $directDeps, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength); $this->printPackages($io, $directDeps, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
} else { } else {
$io->write('Everything up to date'); $io->writeError('Everything up to date');
} }
$io->write(''); $io->writeError('');
$io->write('<info>Transitive dependencies not required in composer.json:</>'); $io->writeError('<info>Transitive dependencies not required in composer.json:</>');
if (\count($transitiveDeps) > 0) { if (\count($transitiveDeps) > 0) {
$this->printPackages($io, $transitiveDeps, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength); $this->printPackages($io, $transitiveDeps, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
} else { } else {
$io->write('Everything up to date'); $io->writeError('Everything up to date');
} }
} else { } else {
$this->printPackages($io, $packages, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength); $this->printPackages($io, $packages, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength);

View File

@ -17,6 +17,7 @@ use Composer\Util\Filesystem;
use Composer\Util\Platform; use Composer\Util\Platform;
use Composer\Util\Silencer; use Composer\Util\Silencer;
use LogicException; use LogicException;
use RuntimeException;
use Seld\Signal\SignalHandler; use Seld\Signal\SignalHandler;
use Symfony\Component\Console\Application as BaseApplication; use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Exception\CommandNotFoundException; use Symfony\Component\Console\Exception\CommandNotFoundException;
@ -514,6 +515,10 @@ class Application extends BaseApplication
if ($required) { if ($required) {
throw $e; throw $e;
} }
} catch (RuntimeException $e) {
if ($required) {
throw $e;
}
} }
} }

View File

@ -13,6 +13,7 @@
namespace Composer\Json; namespace Composer\Json;
use Composer\Pcre\Preg; use Composer\Pcre\Preg;
use Composer\Util\Filesystem;
use JsonSchema\Validator; use JsonSchema\Validator;
use Seld\JsonLint\JsonParser; use Seld\JsonLint\JsonParser;
use Seld\JsonLint\ParsingException; use Seld\JsonLint\ParsingException;
@ -93,7 +94,7 @@ class JsonFile
if ($this->httpDownloader) { if ($this->httpDownloader) {
$json = $this->httpDownloader->get($this->path)->getBody(); $json = $this->httpDownloader->get($this->path)->getBody();
} else { } else {
if (!is_readable($this->path)) { if (!Filesystem::isReadable($this->path)) {
throw new \RuntimeException('The file "'.$this->path.'" is not readable.'); throw new \RuntimeException('The file "'.$this->path.'" is not readable.');
} }
if ($this->io && $this->io->isDebug()) { if ($this->io && $this->io->isDebug()) {
@ -193,7 +194,7 @@ class JsonFile
*/ */
public function validateSchema(int $schema = self::STRICT_SCHEMA, ?string $schemaFile = null): bool public function validateSchema(int $schema = self::STRICT_SCHEMA, ?string $schemaFile = null): bool
{ {
if (!is_readable($this->path)) { if (!Filesystem::isReadable($this->path)) {
throw new \RuntimeException('The file "'.$this->path.'" is not readable.'); throw new \RuntimeException('The file "'.$this->path.'" is not readable.');
} }
$content = file_get_contents($this->path); $content = file_get_contents($this->path);

View File

@ -111,7 +111,7 @@ class Url
$url = Preg::replaceCallback('{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i', static function ($m): string { $url = Preg::replaceCallback('{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i', static function ($m): string {
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that // if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that
if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) { if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+|github_pat_[a-zA-Z0-9_]+)$}', $m['user'])) {
return $m['prefix'].'***:***@'; return $m['prefix'].'***:***@';
} }

View File

@ -82,6 +82,7 @@ class UrlTest extends TestCase
['https://example.org/foo/bar?access_token=***', 'https://example.org/foo/bar?access_token=abcdef'], ['https://example.org/foo/bar?access_token=***', 'https://example.org/foo/bar?access_token=abcdef'],
['https://example.org/foo/bar?foo=bar&access_token=***', 'https://example.org/foo/bar?foo=bar&access_token=abcdef'], ['https://example.org/foo/bar?foo=bar&access_token=***', 'https://example.org/foo/bar?foo=bar&access_token=abcdef'],
['https://***:***@github.com/acme/repo', 'https://ghp_1234567890abcdefghijklmnopqrstuvwxyzAB:x-oauth-basic@github.com/acme/repo'], ['https://***:***@github.com/acme/repo', 'https://ghp_1234567890abcdefghijklmnopqrstuvwxyzAB:x-oauth-basic@github.com/acme/repo'],
['https://***:***@github.com/acme/repo', 'https://github_pat_1234567890abcdefghijkl_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW:x-oauth-basic@github.com/acme/repo'],
// without scheme // without scheme
['foo:***@example.org/', 'foo:bar@example.org/'], ['foo:***@example.org/', 'foo:bar@example.org/'],
['foo@example.org/', 'foo@example.org/'], ['foo@example.org/', 'foo@example.org/'],