"Your package name My Repository is invalid": bug or breaking change?
Hello,
Using the satis.json from the docs at https://getcomposer.org/doc/articles/handling-private-packages.md#setup :
{
"name": "My Repository",
"homepage": "http://packages.example.org",
"repositories": [
{ "type": "vcs", "url": "https://github.com/mycompany/privaterepo" },
{ "type": "vcs", "url": "http://svn.example.org/private/repo" },
{ "type": "vcs", "url": "https://github.com/mycompany/privaterepo2" }
],
"require-all": true
}
And the latest container tag:
Digest: sha256:0f6cb23de613edf42bfe4da17333b5ada6bb99e21c20324ed91db5f13bb9e744
Status: Downloaded newer image for composer/satis:latest
I get this error:
docker run --rm --init -it \
--user $(id -u):$(id -g) \
--volume $(pwd):/build \
composer/satis build satis.json foo
In RootPackageLoader.php line 76:
Your package name My Repository is invalid, it should have a vendor name, a forward slash, and a package name. The vendor and package name can be words separated by -, . or _. The complete name shoul
d match "^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$".
build [--repository-url [REPOSITORY-URL]] [--repository-strict] [--no-html-output] [--skip-errors] [--stats] [--] [<file> [<output-dir> [<packages>...]]]
Is this a bug or a breaking change?
Cheers!
Here's the latest working version I've pulled: composer/satis@sha256:a73607b8588f306e307a69449f08342570c807b3afa6aa290f045bd99a1cb5f6
docker run --rm --init -it \
--user $(id -u):$(id -g) \
--volume $(pwd):/build \
composer/satis@sha256:a73607b8588f306e307a69449f08342570c807b3afa6aa290f045bd99a1cb5f6 build satis.json foo
Seems related to https://github.com/composer/satis/issues/526 , https://github.com/composer/composer/commit/5c4ef1eb96d4b3aaed601a40870752460b94fa1a
Repository names seem to have the same requirement as package names, and composer v2 is enforcing this. So no freestyle names anymore.
I think it is too much work to work around that requirement. So if it is a blocker for you, I recommend you stick to running an older version of satis (e.g. the 2.x branch). Otherwise, just update the name in your satis.json file. Admittedly, the documentation about this should be updated. But documentation for satis is quite sparse and lacking in general. I started on something new a long time ago but never finished it and I simply don't have the time anymore (see the docs directory and https://composer.github.io/satis/). The documentation in the Composer repository is even more out of sync and since it is in another repository it is also easy to forget it exists at all.
I had same problem.. after fixing the name, another error appeared: https://github.com/composer/satis/issues/655 (no solution yet)
@alcohol One idea to "work around" the requirement is simply to create formatting rules for displaying the package name. For example:
- The vendor would become a prefix ending in a colon
- Split the vendor and package on the slash (
/) - Vendor and package names would have dashes (
-) and underscores (_) replaced with spaces - Consecutive spaces in the name would be squashed into one space (e.g.,
foo--barwould becomefoo bar) - Each word in the vendor/package strings would be capitalized (e.g.,
foo barwould becomeFoo Bar)
Uhm.. not sure I follow.
The problem is that some users have a satis.json that looks like this:
{
"name": "my repository",
...
}
This name is not allowed in this format anymore with Composer 2.0, it has to follow the <vendor>/<package> convention.
@alcohol
Using your example:
{
"name": "my repository",
...
}
The user would reformat their name to be in the <vendor>/<package> notation, such as (for example): my/repository or my-repository/my-package. Then, when Satis goes to generate the HTML it would apply the above rules and come out with something that would look like either My: Repository or My Repository: My Package, respectively.
Does that help?
Yeah, okay. I get it. But that seems like a lot of work for something that does not even directly address the original issue. The original issue is that the name values that users sometimes used are now no longer allowed. They still have to be fixed by the user.
@alcohol
...does not even directly address the original issue
Is there anywhere else that the name of the satis repository is used, outside of the title/heading of the web page that satis generates? I admit that I am not a composer/satis expert, so my apologies if I'm missing another vital use case.
They still have to be fixed by the user.
You're correct. But, again if I'm not mistaken, this is a composer issue and not something that satis can address. So while the user will still have to change the package name, it at least gives them some structure that they can use to achieve a reasonable title/header for their web portal.
And to reiterate, it's a suggestion for your consideration. I certainly didn't mean to cause any confusion. :)
I tried to verify that the satis package name is really used somewhere as an identifier inside the created repository metadata, but I had no luck finding it. Seems like the Composer part inside is treating it as a package name somewhere, but not putting it into the metadata output. Maybe there is a way to avoid passing in to Composer? Or work around the validation any other way.
I'd not propose this if the value is actually used in the metadata, but if so: Where?
I've applied this patch to our local Satis:
From b122c20bb36c2dc3da8a92ab07f6d4a7329e6a40 Mon Sep 17 00:00:00 2001
From: Sean <[email protected]>
Date: Wed, 14 Jul 2021 10:31:00 -0700
Subject: [PATCH] fix(web): move the "name" property to "repository-name",
allow pretty names with Composer v2
---
res/satis-schema.json | 4 ++--
src/Builder/WebBuilder.php | 20 ++++++++++++++++----
src/Console/Command/BuildCommand.php | 1 +
3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/res/satis-schema.json b/res/satis-schema.json
index 7985852..e63f961 100644
--- a/res/satis-schema.json
+++ b/res/satis-schema.json
@@ -3,9 +3,9 @@
"name": "Repository Configuration",
"type": "object",
"additionalProperties": false,
- "required": [ "name", "homepage" ],
+ "required": [ "repository-name", "homepage" ],
"properties": {
- "name": {
+ "repository-name": {
"type": "string",
"description": "Repository name."
},
diff --git a/src/Builder/WebBuilder.php b/src/Builder/WebBuilder.php
index f8a82e0..97f63aa 100644
--- a/src/Builder/WebBuilder.php
+++ b/src/Builder/WebBuilder.php
@@ -29,6 +29,8 @@ class WebBuilder extends Builder
private $dependencies;
/** @var Environment */
private $twig;
+ /** @var string|null */
+ private $repositoryName = null;
/** @var string[string] The labels for the fields to toggle on the front end */
private $fieldsToToggle = [
'description' => 'Description',
@@ -46,10 +48,13 @@ public function dump(array $packages): void
{
$mappedPackages = $this->getMappedPackageList($packages);
- $name = $this->rootPackage->getPrettyName();
- if ('__root__' === $name) {
- $name = 'A';
- $this->output->writeln('Define a "name" property in your json config to name the repository');
+ $name = $this->repositoryName;
+ if ($name === null) {
+ $name = $this->rootPackage->getPrettyName();
+ if ('__root__' === $name) {
+ $name = 'A';
+ $this->output->writeln('Define a "name" property in your json config to name the repository');
+ }
}
if (!$this->rootPackage->getHomepage()) {
@@ -134,6 +139,13 @@ private function setDependencies(array $packages): self
return $this;
}
+ public function setRepositoryName(?string $repositoryName): self
+ {
+ $this->repositoryName = $repositoryName;
+
+ return $this;
+ }
+
/**
* Gets a list of packages grouped by name with a list of versions.
*
diff --git a/src/Console/Command/BuildCommand.php b/src/Console/Command/BuildCommand.php
index 472ada4..70ab724 100644
--- a/src/Console/Command/BuildCommand.php
+++ b/src/Console/Command/BuildCommand.php
@@ -217,6 +217,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($htmlView) {
$web = new WebBuilder($output, $outputDir, $config, $skipErrors);
$web->setRootPackage($composer->getPackage());
+ $web->setRepositoryName($config['repository-name'] ?? null);
$web->dump($packages);
}
--
2.32.0
I tried to verify that the satis package name is really used somewhere as an identifier inside the created repository metadata, but I had no luck finding it. Seems like the Composer part inside is treating it as a package name somewhere, but not putting it into the metadata output. Maybe there is a way to avoid passing in to Composer? Or work around the validation any other way.
I'd not propose this if the value is actually used in the metadata, but if so: Where?
We use the config component from Composer to parse the configuration, since the format is quite similar. But Composer treats it as a root package json file. Hence the requirement that name is a valid package name.
@AlbinoDrought if you would be willing to submit a PR, I will happily merge it :-)
This is especially confusing since the linked docs still show a non-package-valid name:
https://getcomposer.org/doc/articles/handling-private-packages.md
That documentation is quite out of sync and outdated. It is open source documentation ;-)
One could make this work again by dropping/faking the name attribute when pushing the config array into the composer instance. However I would prefer if both formats would be more compatible and satis would put its attributes into the extra or config section of a valid composer.json file. Interested in a patch?