Flex: Symfony Flex breaks interactivity of Composer scripts

Created on 10 Jan 2018  路  13Comments  路  Source: symfony/flex

Hi,

I have a composer script defined:

{
    "scripts": {
        "post-install-cmd": [
            "My\\Cool\\ScriptHandler::run"
        ],
        "post-update-cmd": [
            "My\\Cool\\ScriptHandler::run"
        ]
    }
}

which works, except for one difference: the given InputStream is non-interactive.

<?php

use Composer\Script\Event;

class ScriptHandler
{
    public function handle (Event $event)
    {
        var_dump($event->getIO()->isInteractive());
    }
}

The problem is flex, as this short snipped shows:

$ composer run-script parameters
> My\Cool\ScriptHandler::handle
bool(false)


$ composer remove symfony/flex
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 0 updates, 1 removal
  - Removing symfony/flex (v1.0.60)
[...]


$ composer run-script parameters
> My\Cool\ScriptHandler::handle
bool(true)

This currently makes implementing something similar to incenteev/composer-parameter-handler in combination with running flex impossible.

Most helpful comment

Quick reproducer on my side:

composer create-project symfony/skeleton app
cd app && composer req friendsofsymfony/elastica-bundle

Symfony operations: 1 recipe (87cd049614f216146bb961668dd54270)
  -  IGNORING  friendsofsymfony/elastica-bundle (>=5.0): From github.com/symfony/recipes-contrib:master

I can confirm isInteractive is false at this point.

All 13 comments

As it turns out, interactivity is explicitly disabled:
https://github.com/symfony/flex/blob/558a09162d496a3b677bd1d0690470d59082c16c/src/Flex.php#L108

due to

removed question about removing VCS files

https://github.com/symfony/flex/commit/bce4c36ad8ebeb52f6296d7ab604296a395b259d

I will take a look, whether there is a better way to remove the question besides of completely disabling interactivity.

FYI: haven't found a way to disable the "remove vcd directory" message without disabling all interactivity in all dependency scripts.
Opened an issue at composer to discuss the possible solutions.

Quick reproducer on my side:

composer create-project symfony/skeleton app
cd app && composer req friendsofsymfony/elastica-bundle

Symfony operations: 1 recipe (87cd049614f216146bb961668dd54270)
  -  IGNORING  friendsofsymfony/elastica-bundle (>=5.0): From github.com/symfony/recipes-contrib:master

I can confirm isInteractive is false at this point.

May be it is not so important to setInteractive(false) ?

Or may be we could change here default behavior of create-project command instead of setInteractive(false) ?

            /** @var Application $app */
            $app = $trace['object'];
            /** @var \Composer\Command\CreateProjectCommand $command */
            $command = $app->find("create-project");
            $definition = $command->getDefinition();
            $definition->getOption('keep-vcs')->setDefault(false);
            $definition->getOption('prefer-dist')->setDefault(true);
            $definition->getOption('prefer-source')->setDefault(false);

^ i'm not sure if this will help

Also we could replace create-project command with a new one with overriden installProject or installRootPackage method. And then create a command in Symfony\Flex\Flex::activate, like it happened with require, remove and update commands.

May be it is not so important to setInteractive(false) ?

It is, as we don't want the message about removing the VCS.

Or may be we could change here default behavior of create-project command instead of setInteractive(false)?

That would mean to duplicate the code from Composer. I would prefer to just keep using composer and fix this one issue. See the linked composer ticket for details.

This may have been resolved by #296. I believe the non-interactive was only meant to be done for create-project. That was accidentally changed, and #296 puts that back. This original report was about a script being run after a composer remove, and I believe that this will now be interactive again.

@weaverryan it is resolved for every instance except create-project. But the interactivity should work in every command, for example if you are using something like incenteev/composer-parameter-handler which tries to ask for config values when creating a project.

So we should really resolve it in every instance, which would be quite easy if the upstream composer ticket would get some traction.

Note that if Composer was passing $input to the installProject() method instead of passing the result from $input, we would be able to change its value from Flex.

@seldaek would that work for you? 猬嗭笍

@fabpot how would you do this? By extending installProject() and modifying before calling parent? If so why not extend execute() and do the same? Or did I miss something?

@fabpot https://github.com/composer/composer/commit/f42e6a5772c405efb6f2c46bec6fc0d1424acf61 should let you override the option's value at the time the flex plugin gets installed/enabled, if you know how to do that (I am still not sure, but I haven't checked in depth). Please report back here or at https://github.com/composer/composer/issues/7002 whether this helps.

Should be fixed by #377.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

javiereguiluz picture javiereguiluz  路  6Comments

kolibri picture kolibri  路  3Comments

timonf picture timonf  路  8Comments

javiereguiluz picture javiereguiluz  路  4Comments

marcw picture marcw  路  4Comments