1
0
Fork 0

Default exclude patterns for the "archive" command (#11239)

* Issue #11235 - Adds default exclude patterns for the "archive" command based on the target file name
pull/11292/head
Andor 2023-01-27 17:16:33 +01:00 committed by GitHub
parent ad7bc18028
commit 50cded331c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 137 additions and 28 deletions

View File

@ -70,6 +70,54 @@ class ArchiveManager
return $this;
}
/**
* @return array<string, string>
* @internal
*/
public function getPackageFilenameParts(CompletePackageInterface $package): array
{
$baseName = $package->getArchiveName();
if (null === $baseName) {
$baseName = Preg::replace('#[^a-z0-9-_]#i', '-', $package->getName());
}
$parts = [
'base' => $baseName,
];
$distReference = $package->getDistReference();
if (null !== $distReference && Preg::isMatch('{^[a-f0-9]{40}$}', $distReference)) {
$parts['dist_reference'] = $distReference;
$parts['dist_type'] = $package->getDistType();
} else {
$parts['version'] = $package->getPrettyVersion();
$parts['dist_reference'] = $distReference;
}
$sourceReference = $package->getSourceReference();
if (null !== $sourceReference) {
$parts['source_reference'] = substr(sha1($sourceReference), 0, 6);
}
$parts = array_filter($parts);
foreach ($parts as $key => $part) {
$parts[$key] = str_replace('/', '-', $part);
}
return $parts;
}
/**
* @param array<string, string> $parts
*
* @return string
* @internal
*/
public function getPackageFilenameFromParts(array $parts): string
{
return implode('-', $parts);
}
/**
* Generate a distinct filename for a particular version of a package.
*
@ -79,28 +127,7 @@ class ArchiveManager
*/
public function getPackageFilename(CompletePackageInterface $package): string
{
if ($package->getArchiveName()) {
$baseName = $package->getArchiveName();
} else {
$baseName = Preg::replace('#[^a-z0-9-_]#i', '-', $package->getName());
}
$nameParts = [$baseName];
if (null !== $package->getDistReference() && Preg::isMatch('{^[a-f0-9]{40}$}', $package->getDistReference())) {
array_push($nameParts, $package->getDistReference(), $package->getDistType());
} else {
array_push($nameParts, $package->getPrettyVersion(), $package->getDistReference());
}
if ($package->getSourceReference()) {
$nameParts[] = substr(sha1($package->getSourceReference()), 0, 6);
}
$name = implode('-', array_filter($nameParts, static function ($p): bool {
return !empty($p);
}));
return str_replace('/', '-', $name);
return $this->getPackageFilenameFromParts($this->getPackageFilenameParts($package));
}
/**
@ -169,11 +196,13 @@ class ArchiveManager
}
}
if (null === $fileName) {
$packageName = $this->getPackageFilename($package);
} else {
$packageName = $fileName;
}
$supportedFormats = $this->getSupportedFormats();
$packageNameParts = null === $fileName ?
$this->getPackageFilenameParts($package)
: ['base' => $fileName];
$packageName = $this->getPackageFilenameFromParts($packageNameParts);
$excludePatterns = $this->buildExcludePatterns($packageNameParts, $supportedFormats);
// Archive filename
$filesystem->ensureDirectoryExists($targetDir);
@ -188,7 +217,13 @@ class ArchiveManager
$tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format;
$filesystem->ensureDirectoryExists(dirname($tempTarget));
$archivePath = $usableArchiver->archive($sourcePath, $tempTarget, $format, $package->getArchiveExcludes(), $ignoreFilters);
$archivePath = $usableArchiver->archive(
$sourcePath,
$tempTarget,
$format,
array_merge($excludePatterns, $package->getArchiveExcludes()),
$ignoreFilters
);
$filesystem->rename($archivePath, $target);
// cleanup temporary download
@ -199,4 +234,54 @@ class ArchiveManager
return $target;
}
/**
* @param string[] $parts
* @param string[] $formats
*
* @return string[]
*/
private function buildExcludePatterns(array $parts, array $formats): array
{
$base = $parts['base'];
if (count($parts) > 1) {
$base .= '-*';
}
$patterns = [];
foreach ($formats as $format) {
$patterns[] = "$base.$format";
}
return $patterns;
}
/**
* @return string[]
*/
private function getSupportedFormats(): array
{
// The problem is that the \Composer\Package\Archiver\ArchiverInterface
// doesn't provide method to get the supported formats.
// Supported formats are also hard-coded into the description of the
// --format option.
// See \Composer\Command\ArchiveCommand::configure().
$formats = [];
foreach ($this->archivers as $archiver) {
$items = [];
switch (get_class($archiver)) {
case ZipArchiver::class:
$items = ['zip'];
break;
case PharArchiver::class:
$items = ['zip', 'tar', 'tar.gz', 'tar.bz2'];
break;
}
$formats = array_merge($formats, $items);
}
return array_unique($formats);
}
}

View File

@ -99,6 +99,30 @@ class ArchiveManagerTest extends ArchiverTest
unlink($target);
}
public function testGetPackageFilenameParts(): void
{
$expected = [
'base' => 'archivertest-archivertest',
'version' => 'master',
'source_reference' => '4f26ae',
];
$package = $this->setupPackage();
self::assertSame(
$expected,
$this->manager->getPackageFilenameParts($package)
);
}
public function testGetPackageFilename(): void
{
$package = $this->setupPackage();
self::assertSame(
'archivertest-archivertest-master-4f26ae',
$this->manager->getPackageFilename($package)
);
}
protected function getTargetName(CompletePackage $package, string $format, ?string $fileName = null): string
{
if (null === $fileName) {