What does the "key: value" syntax do in composer scripts

Viewed 27

From compser documentation you can write scripts like so:

{
    "scripts": {
        "some-event": [
            "command1",
            "command2",
            "command3"
        ],
    }
}

But in Symfony I found a slightly different syntax that instead of a list is using a key:value pair like this:

{
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
    },
}

How does this syntax work exactly? Does it redirect commands to another one, adds a dependency between 2 commands or what?

2 Answers

How does this syntax work exactly?

This syntax is undefined in Composer.

To learn more, remove it and then check which component(s) break(s). Then consult the support of that/these component(s) to learn more (and/or leave a comment here).

Does it redirect commands to another one, adds a dependency between 2 commands or what?

As written this is undefined. As far as you're concerned about Composer you can check if it is recognized as a script:

composer run-script --list

You'll likely see that auto-scripts is listed as a script, that is, Composer is recognizing at least the auto-scripts keyword.

You can then execute that script to see how Composer executes it (it is highly recommended you do this and the following in an isolated environment):

composer run-script auto-scripts

To see if a plugin would make a difference, you can also execute it with plugins disabled:

composer --no-plugins run-script auto-scripts

Take care.

And with Composer there is always -vvv.


Some notes on internal Composer configuration file handling: JSON Text files (.json, .lock) in Composer are typically parsed into associative arrays (not stdClass::class objects).

Therefore foreach'ing a script member - which can be a string as well, likely post-processed with an (array) cast - would not care about the key (attribute name), just executing the scripts lines.

This syntax is used by symfony/flex plugin and is only valid under auto-scripts key. The code in flex looks like this:

        $json = new JsonFile(Factory::getComposerFile());
        $jsonContents = $json->read();

        $executor = new ScriptExecutor($this->composer, $this->io, $this->options);
        foreach ($jsonContents['scripts']['auto-scripts'] as $cmd => $type) {
            $executor->execute($type, $cmd);
        }

With execute being handled using this code:

        switch ($type) {
            case 'symfony-cmd':
                return $this->expandSymfonyCmd($cmd);
            case 'php-script':
                return $this->expandPhpScript($cmd);
            case 'script':
                return $cmd;
            default:
                throw new \InvalidArgumentException();
        }
Related