Skip to content

Commit

Permalink
[FEATURE] allow setting working dir
Browse files Browse the repository at this point in the history
The working dir option allows the user to switch to a different location to execute the application.
  • Loading branch information
jaapio committed Nov 20, 2023
1 parent 6665ac4 commit 67df46e
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 4 deletions.
7 changes: 5 additions & 2 deletions packages/guides-cli/bin/guides
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ if (is_file($vendorDir . '/../guides.xml')) {
// vendor folder was placed directly into the project directory
$containerFactory->addConfigFile($vendorDir . '/../guides.xml');
}
if (is_file($input->getParameterOption('--config', getcwd(), true).'/guides.xml')) {
$containerFactory->addConfigFile($input->getParameterOption('--config', getcwd(), true).'/guides.xml');

$workingDir = $input->getParameterOption('--working-dir', getcwd(), true);

if (is_file($input->getParameterOption('--config', $workingDir, true).'/guides.xml')) {
$containerFactory->addConfigFile($input->getParameterOption('--config', $workingDir, true).'/guides.xml');
}
$container = $containerFactory->create($vendorDir);

Expand Down
9 changes: 8 additions & 1 deletion packages/guides-cli/resources/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
use Monolog\Logger;
use phpDocumentor\Guides\Cli\Application;
use phpDocumentor\Guides\Cli\Command\Run;
use phpDocumentor\Guides\Cli\Command\WorkingDirectorySwitcher;
use Psr\Clock\ClockInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Clock\NativeClock;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\EventDispatcher\EventDispatcher;

use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
use function Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator;

return static function (ContainerConfigurator $container): void {
Expand All @@ -34,5 +37,9 @@

->set(Application::class)
->arg('$commands', tagged_iterator('phpdoc.guides.cli.command'))
->public();
->call('setDispatcher', [service(EventDispatcherInterface::class)])
->public()

->set(WorkingDirectorySwitcher::class)
->tag('event_listener', ['event' => ConsoleEvents::COMMAND, 'method' => '__invoke']);
};
8 changes: 8 additions & 0 deletions packages/guides-cli/src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ protected function getDefaultInputDefinition(): InputDefinition
getcwd(),
));

$definition->addOption(new InputOption(
'working-dir',
'w',
InputOption::VALUE_REQUIRED,
'If specified, use the given directory as working directory.',
null,
));

return $definition;
}
}
36 changes: 36 additions & 0 deletions packages/guides-cli/src/Command/WorkingDirectorySwitcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\Cli\Command;

use RuntimeException;
use Symfony\Component\Console\Event\ConsoleCommandEvent;

use function chdir;
use function sprintf;

final class WorkingDirectorySwitcher
{
public function __invoke(ConsoleCommandEvent $event): void
{
$workingDir = $event->getInput()->getOption('working-dir');
if ($workingDir === null) {
return;
}

if (!@chdir($workingDir)) {
throw new RuntimeException(sprintf(
'Could not switch to working directory "%s"',
$workingDir,
));
}

$event->getOutput()->writeln(
sprintf(
'Changing working directory to %s',
$workingDir,
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@

namespace phpDocumentor\Guides\Cli\DependencyInjection;

use InvalidArgumentException;
use Psr\Container\ContainerInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcher;

use function dirname;
use function sprintf;

class ApplicationExtension extends Extension
class ApplicationExtension extends Extension implements CompilerPassInterface
{
/** @param string[] $configs */
public function load(array $configs, ContainerBuilder $container): void
Expand All @@ -31,4 +36,25 @@ public function getAlias(): string
{
return 'application';
}

public function process(ContainerBuilder $container): void
{
$eventDispatcher = $container->getDefinition(EventDispatcher::class);

foreach ($container->findTaggedServiceIds('event_listener') as $id => $tags) {
foreach ($tags as $tag) {
if (!isset($tag['event'])) {
throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "event_listener" tags.', $id));
}

$eventDispatcher->addMethodCall(
'addListener',
[
$tag['event'],
[new Reference($id), $tag['method'] ?? '__invoke'],
],
);
}
}
}
}

0 comments on commit 67df46e

Please sign in to comment.