Skip to content

Commit

Permalink
Add forward mode (bamarni#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
mimmi20 committed Feb 22, 2022
1 parent f7fb03e commit 49934ff
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 10 deletions.
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
1. [Auto-installation](#auto-installation)
1. [Disable links](#disable-links)
1. [Change directory](#change-directory)
1. [Forward mode](#forward-mode)
1. [Reduce clutter](#reduce-clutter)
1. [Related plugins](#related-plugins)

Expand Down Expand Up @@ -162,7 +163,6 @@ For convenience, you can add the following script in your `composer.json` :

This makes sure all your bins are installed during `composer install` and updated during `composer update`.


### Disable links

By default, binaries of the sub namespaces are linked to the root one like described in [example](#example). If you
Expand All @@ -178,7 +178,6 @@ wish to disable that behaviour, you can do so by adding a little setting in the
}
```


### Change directory

By default, the packages are looked for in the `vendor-bin` directory. The location can be changed using `target-directory` value in the extra config:
Expand All @@ -193,6 +192,23 @@ By default, the packages are looked for in the `vendor-bin` directory. The locat
}
```

### Forward mode

There is a `forward mode` which is disabled by default. This can be activated by using the `forward-command` value in the extra config.

```json
{
"extra": {
"bamarni-bin": {
"forward-command": true
}
}
}
```

If this mode is activated, all your `composer install` and `composer update` commands are forwared to all bin directories.
This is an replacement for the tasks shown in section [Auto-installation](#auto-installation).

### Reduce clutter

You can add following line to your `.gitignore` file in order to avoid committing dependencies of your tools.
Expand Down
37 changes: 31 additions & 6 deletions src/BinCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function execute(InputInterface $input, OutputInterface $output)

$vendorRoot = $config->getTargetDirectory();
$namespace = $input->getArgument('namespace');

$input = new StringInput(preg_replace(
sprintf('/bin\s+(--ansi\s)?%s(\s.+)/', preg_quote($namespace, '/')),
'$1$2',
Expand Down Expand Up @@ -77,8 +78,12 @@ private function executeAllNamespaces(ComposerApplication $application, $binVend

$originalWorkingDir = getcwd();
$exitCode = 0;
foreach ($binRoots as $binRoot) {
$exitCode += $this->executeInNamespace($application, $binRoot, $input, $output);
foreach ($binRoots as $namespace) {
$output->writeln(
sprintf('Run in namespace <comment>%s</comment>', $namespace),
OutputInterface::VERBOSITY_VERBOSE
);
$exitCode += $this->executeInNamespace($application, $namespace, $input, $output);

chdir($originalWorkingDir);
$this->resetComposers($application);
Expand Down Expand Up @@ -107,11 +112,15 @@ private function executeInNamespace(ComposerApplication $application, $namespace
if (!file_exists(Factory::getComposerFile())) {
file_put_contents(Factory::getComposerFile(), '{}');
}

$input = new StringInput((string) $input . ' --working-dir=.');

$this->getIO()->writeError('<info>Run with <comment>' . $input->__toString() . '</comment></info>', true, IOInterface::VERBOSE);

$this->getIO()->writeError(
sprintf('<info>Run with <comment>%s</comment></info>', $input->__toString()),
true,
IOInterface::VERBOSE
);

return $application->doRun($input, $output);
}

Expand All @@ -127,23 +136,39 @@ public function isProxyCommand()
* Resets all Composer references in the application.
*
* @param ComposerApplication $application
* @return void
*/
private function resetComposers(ComposerApplication $application)
{
$application->resetComposer();

foreach ($this->getApplication()->all() as $command) {
if ($command instanceof BaseCommand) {
$command->resetComposer();
}
}
}

/**
* @param $dir
* @return void
*/
private function chdir($dir)
{
chdir($dir);
$this->getIO()->writeError('<info>Changed current directory to ' . $dir . '</info>', true, IOInterface::VERBOSE);

$this->getIO()->writeError(
sprintf('<info>Changed current directory to %s</info>', $dir),
true,
IOInterface::VERBOSE
);
}

/**
* @return \Composer\Config
* @throws \Composer\Json\JsonValidationException
* @throws \Seld\JsonLint\ParsingException
*/
private function createConfig()
{
$config = Factory::createConfig();
Expand Down
9 changes: 9 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public function __construct(Composer $composer)
[
'bin-links' => true,
'target-directory' => 'vendor-bin',
'forward-command' => false,
],
isset($extra['bamarni-bin']) ? $extra['bamarni-bin'] : []
);
Expand All @@ -35,4 +36,12 @@ public function getTargetDirectory()
{
return $this->config['target-directory'];
}

/**
* @return bool
*/
public function isCommandForwarded()
{
return $this->config['forward-command'];
}
}
92 changes: 90 additions & 2 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,40 @@
namespace Bamarni\Composer\Bin;

use Composer\Composer;
use Composer\Console\Application;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\IO\IOInterface;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\Capable;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;

class Plugin implements PluginInterface, Capable
class Plugin implements PluginInterface, Capable, EventSubscriberInterface
{
/**
* @var Composer
*/
protected $composer;

/**
* @var IOInterface
*/
protected $io;

/**
* @return void
*/
public function activate(Composer $composer, IOInterface $io)
{
$this->composer = $composer;
$this->io = $io;
}

/**
* @return array
* @return string[]
*/
public function getCapabilities()
{
Expand All @@ -39,4 +58,73 @@ public function deactivate(Composer $composer, IOInterface $io)
public function uninstall(Composer $composer, IOInterface $io)
{
}

/**
* @return string[]
*/
public static function getSubscribedEvents()
{
return [
PluginEvents::COMMAND => 'onCommandEvent',
];
}

/**
* @param CommandEvent $event
* @return bool
*/
public function onCommandEvent(CommandEvent $event)
{
$config = new Config($this->composer);

if ($config->isCommandForwarded()) {
switch ($event->getCommandName()) {
case 'update':
case 'install':
return $this->onCommandEventInstallUpdate($event);
}
}

return true;
}

/**
* @param CommandEvent $event
* @return bool
*/
protected function onCommandEventInstallUpdate(CommandEvent $event)
{
$command = new BinCommand();
$command->setComposer($this->composer);
$command->setApplication(new Application());

$arguments = [
'command' => $command->getName(),
'namespace' => 'all',
'args' => [],
];

foreach (array_filter($event->getInput()->getArguments()) as $argument) {
$arguments['args'][] = $argument;
}

foreach (array_keys(array_filter($event->getInput()->getOptions())) as $option) {
$arguments['args'][] = '--' . $option;
}

$definition = new InputDefinition();
$definition->addArgument(new InputArgument('command', InputArgument::REQUIRED));
$definition->addArguments($command->getDefinition()->getArguments());
$definition->addOptions($command->getDefinition()->getOptions());

$input = new ArrayInput($arguments, $definition);

try {
$returnCode = $command->run($input, $event->getOutput());
} catch (\Exception $e) {
return false;
}

return $returnCode === 0;
}
}

0 comments on commit 49934ff

Please sign in to comment.