diff --git a/doc/04-schema.md b/doc/04-schema.md index d237282e3..00070a0b8 100644 --- a/doc/04-schema.md +++ b/doc/04-schema.md @@ -877,6 +877,21 @@ A set of options for creating package archives. The following options are supported: +* **name:** Allows configuring base name for archive. + By default (if not configured, and `--file` is not passed as command-line argument), + `preg_replace('#[^a-z0-9-_]#i', '-', name)` is used. + +Example: + +```json +{ + "name": "org/strangeName", + "archive": { + "name": "Strange_name" + } +} +``` + * **exclude:** Allows configuring a list of patterns for excluded paths. The pattern syntax matches .gitignore files. A leading exclamation mark (!) will result in any matching files to be included even if a previous pattern diff --git a/res/composer-schema.json b/res/composer-schema.json index 47666a843..165ffcf85 100644 --- a/res/composer-schema.json +++ b/res/composer-schema.json @@ -359,6 +359,10 @@ "type": ["object"], "description": "Options for creating package archives for distribution.", "properties": { + "name": { + "type": "string", + "description": "A base name for archive." + }, "exclude": { "type": "array", "description": "A list of patterns for paths to exclude or include if prefixed with an exclamation mark." diff --git a/src/Composer/Package/AliasPackage.php b/src/Composer/Package/AliasPackage.php index 54e26979d..4a8e2e96e 100644 --- a/src/Composer/Package/AliasPackage.php +++ b/src/Composer/Package/AliasPackage.php @@ -395,6 +395,11 @@ class AliasPackage extends BasePackage implements CompletePackageInterface return $this->aliasOf->getNotificationUrl(); } + public function getArchiveName() + { + return $this->aliasOf->getArchiveName(); + } + public function getArchiveExcludes() { return $this->aliasOf->getArchiveExcludes(); diff --git a/src/Composer/Package/Archiver/ArchiveManager.php b/src/Composer/Package/Archiver/ArchiveManager.php index 5e4ec0100..aed8ccf80 100644 --- a/src/Composer/Package/Archiver/ArchiveManager.php +++ b/src/Composer/Package/Archiver/ArchiveManager.php @@ -78,7 +78,12 @@ class ArchiveManager */ public function getPackageFilename(PackageInterface $package) { - $nameParts = array(preg_replace('#[^a-z0-9-_]#i', '-', $package->getName())); + if ($package->getArchiveName()) { + $baseName = $package->getArchiveName(); + } else { + $baseName = preg_replace('#[^a-z0-9-_]#i', '-', $package->getName()); + } + $nameParts = array($baseName); if (preg_match('{^[a-f0-9]{40}$}', $package->getDistReference())) { array_push($nameParts, $package->getDistReference(), $package->getDistType()); @@ -131,20 +136,6 @@ class ArchiveManager } $filesystem = new Filesystem(); - if (null === $fileName) { - $packageName = $this->getPackageFilename($package); - } else { - $packageName = $fileName; - } - - // Archive filename - $filesystem->ensureDirectoryExists($targetDir); - $target = realpath($targetDir).'/'.$packageName.'.'.$format; - $filesystem->ensureDirectoryExists(dirname($target)); - - if (!$this->overwriteFiles && file_exists($target)) { - return $target; - } if ($package instanceof RootPackageInterface) { $sourcePath = realpath('.'); @@ -167,12 +158,30 @@ class ArchiveManager if (file_exists($composerJsonPath = $sourcePath.'/composer.json')) { $jsonFile = new JsonFile($composerJsonPath); $jsonData = $jsonFile->read(); + if (!empty($jsonData['archive']['name'])) { + $package->setArchiveName($jsonData['archive']['name']); + } if (!empty($jsonData['archive']['exclude'])) { $package->setArchiveExcludes($jsonData['archive']['exclude']); } } } + if (null === $fileName) { + $packageName = $this->getPackageFilename($package); + } else { + $packageName = $fileName; + } + + // Archive filename + $filesystem->ensureDirectoryExists($targetDir); + $target = realpath($targetDir).'/'.$packageName.'.'.$format; + $filesystem->ensureDirectoryExists(dirname($target)); + + if (!$this->overwriteFiles && file_exists($target)) { + return $target; + } + // Create the archive $tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format; $filesystem->ensureDirectoryExists(dirname($tempTarget)); diff --git a/src/Composer/Package/Dumper/ArrayDumper.php b/src/Composer/Package/Dumper/ArrayDumper.php index 3ebd44f26..46bcf639a 100644 --- a/src/Composer/Package/Dumper/ArrayDumper.php +++ b/src/Composer/Package/Dumper/ArrayDumper.php @@ -70,6 +70,9 @@ class ArrayDumper } } + if ($package->getArchiveName()) { + $data['archive']['name'] = $package->getArchiveName(); + } if ($package->getArchiveExcludes()) { $data['archive']['exclude'] = $package->getArchiveExcludes(); } diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index adf8fb039..f50358776 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -194,6 +194,9 @@ class ArrayLoader implements LoaderInterface $package->setNotificationUrl($config['notification-url']); } + if (!empty($config['archive']['name'])) { + $package->setArchiveName($config['archive']['name']); + } if (!empty($config['archive']['exclude'])) { $package->setArchiveExcludes($config['archive']['exclude']); } diff --git a/src/Composer/Package/Package.php b/src/Composer/Package/Package.php index 3c2e74219..5e393a11c 100644 --- a/src/Composer/Package/Package.php +++ b/src/Composer/Package/Package.php @@ -57,6 +57,7 @@ class Package extends BasePackage protected $autoload = array(); protected $devAutoload = array(); protected $includePaths = array(); + protected $archiveName; protected $archiveExcludes = array(); /** @@ -551,6 +552,24 @@ class Package extends BasePackage return $this->notificationUrl; } + /** + * Sets default base filename for archive + * + * @param string $name + */ + public function setArchiveName($name) + { + $this->archiveName = $name; + } + + /** + * {@inheritDoc} + */ + public function getArchiveName() + { + return $this->archiveName; + } + /** * Sets a list of patterns to be excluded from archives * diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php index cda65f5cb..1c2ad2e06 100644 --- a/src/Composer/Package/PackageInterface.php +++ b/src/Composer/Package/PackageInterface.php @@ -357,6 +357,13 @@ interface PackageInterface */ public function getPrettyString(); + /** + * Returns default base filename for archive + * + * @return array + */ + public function getArchiveName(); + /** * Returns a list of patterns to exclude from package archives *