satis icon indicating copy to clipboard operation
satis copied to clipboard

"Your package name My Repository is invalid": bug or breaking change?

Open AlbinoDrought opened this issue 4 years ago • 17 comments

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!

AlbinoDrought avatar Jul 08 '21 21:07 AlbinoDrought

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

AlbinoDrought avatar Jul 08 '21 21:07 AlbinoDrought

Seems related to https://github.com/composer/satis/issues/526 , https://github.com/composer/composer/commit/5c4ef1eb96d4b3aaed601a40870752460b94fa1a

AlbinoDrought avatar Jul 08 '21 22:07 AlbinoDrought

Repository names seem to have the same requirement as package names, and composer v2 is enforcing this. So no freestyle names anymore.

SvenRtbg avatar Jul 09 '21 08:07 SvenRtbg

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.

alcohol avatar Jul 09 '21 11:07 alcohol

I had same problem.. after fixing the name, another error appeared: https://github.com/composer/satis/issues/655 (no solution yet)

kluvi avatar Jul 12 '21 05:07 kluvi

@alcohol One idea to "work around" the requirement is simply to create formatting rules for displaying the package name. For example:

  1. The vendor would become a prefix ending in a colon
  2. Split the vendor and package on the slash (/)
  3. Vendor and package names would have dashes (-) and underscores (_) replaced with spaces
  4. Consecutive spaces in the name would be squashed into one space (e.g., foo--bar would become foo bar)
  5. Each word in the vendor/package strings would be capitalized (e.g., foo bar would become Foo Bar)

d42ohpaz avatar Jul 12 '21 15:07 d42ohpaz

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 avatar Jul 14 '21 10:07 alcohol

@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?

d42ohpaz avatar Jul 14 '21 12:07 d42ohpaz

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 avatar Jul 14 '21 13:07 alcohol

@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. :)

d42ohpaz avatar Jul 14 '21 14:07 d42ohpaz

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?

SvenRtbg avatar Jul 14 '21 17:07 SvenRtbg

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

AlbinoDrought avatar Jul 14 '21 17:07 AlbinoDrought

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.

alcohol avatar Jul 15 '21 07:07 alcohol

@AlbinoDrought if you would be willing to submit a PR, I will happily merge it :-)

alcohol avatar Jul 15 '21 07:07 alcohol

This is especially confusing since the linked docs still show a non-package-valid name:

https://getcomposer.org/doc/articles/handling-private-packages.md

robations avatar Apr 11 '22 10:04 robations

That documentation is quite out of sync and outdated. It is open source documentation ;-)

alcohol avatar Apr 13 '22 15:04 alcohol

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?

ralflang avatar Aug 17 '22 19:08 ralflang