New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow running only actions specified on the command line #137
base: main
Are you sure you want to change the base?
Conversation
// Otherwise, use the verbosity setting from the configuration. | ||
if (!$input->hasOption('verbose') || !$input->getOption('verbose')) { | ||
$output->setVerbosity(IOUtil::mapConfigVerbosity($config->getVerbosity())); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this because I found that captainhook
didn't respect the verbosity option (i.e., -v
, -vv
, and -vvv
) passed on the command line. It was always setting the output to whatever was configured in captainhook.json
.
IMO, if you pass verbosity on the command line, it should override whatever is configured in captainhook.json
.
@@ -92,6 +92,7 @@ public function execute(Config $config, IO $io, Repository $repository, Config\A | |||
* Setup the action, reading and validating all config settings | |||
* | |||
* @param \CaptainHook\App\Config\Options $options | |||
* @codeCoverageIgnore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method does nothing here. It only has a comment in it, but it was showing up in coverage reports as an uncovered method.
public function isEnabled(): bool | ||
{ | ||
return $this->isAnyConfigEnabled($this->getHookConfigsToHandle()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows the hook command class access to know whether the hook is enabled.
public function getActions(): array | ||
{ | ||
return $this->getActionsToExecute($this->getHookConfigsToHandle()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows the hook command class access to the list of actions configured for the hook, so it may use these to list the actions, when --list-actions
is provided.
$this->io->write(' - <fg=blue>' . $this->formatActionOutput($action->getAction()) . '</> : ', false); | ||
|
||
if (!$this->doConditionsApply($action->getConditions())) { | ||
$this->io->write('<comment>skipped</comment>', true); | ||
if ($this->checkSkipAction($action)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this to reduce the amount of code in the handleAction()
method and, hopefully, to simplify the logic, so it's easier to read and understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -114,12 +114,19 @@ public function run(): void | |||
{ | |||
$hookConfigs = $this->getHookConfigsToHandle(); | |||
|
|||
$this->io->write('<comment>' . $this->hook . ':</comment> '); | |||
/** @var IO\Base $io */ | |||
$io = $this->io; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the benefit of PHPStan, since getOption()
is not on the Console\IO
interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the getOption method. I think it would be better to handle the option stuff on the outside (inside the Command) and set an explicit setting on the runner with $runner->setActions
or $runner->disablePlugins
...
This way we could get rid of the option
methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll give this a try. I didn't like adding the getOption()
method. 🙂
private function cliSkipAction(Config\Action $action): bool | ||
{ | ||
/** @var IO\Base $io */ | ||
$io = $this->io; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the benefit of PHPStan, since getOption()
is not on the Console\IO
interface.
@@ -449,10 +517,17 @@ private function getHookPlugins(): array | |||
*/ | |||
private function executeHookPluginsFor(string $method, ?Config\Action $action = null): void | |||
{ | |||
/** @var IO\Base $io */ | |||
$io = $this->io; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the benefit of PHPStan, since getOption()
is not on the Console\IO
interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will not need this if we are not using the IO
to make decision inside Runner
See previous comment on src/Runner/Hook.php
if ($input->getOption('list-actions') === true) { | ||
foreach ($this->getDefinition()->getArguments() as $arg) { | ||
if ($arg->isRequired() && $input->getArgument($arg->getName()) === null) { | ||
$input->setArgument($arg->getName(), ''); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about creating three separate commands (e.g. hook:pre-commit:list-actions
) instead of adding those as options with need for this magic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of separating the list functionality from the execution functionality
I think one command is enough captainhook list-actions pre-commit
:)
Then this can be done in a separate Runner\ListActions
Maybe we can move the getHookConfigsToHandle
functionality to the Config
class. This way we would not have duplicate code in Runner\Hook
and Runner\ListActions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ramsey have you seen this comment as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty nice, the only thing to discuss would be the ->getOption
stuff.
@@ -114,12 +114,19 @@ public function run(): void | |||
{ | |||
$hookConfigs = $this->getHookConfigsToHandle(); | |||
|
|||
$this->io->write('<comment>' . $this->hook . ':</comment> '); | |||
/** @var IO\Base $io */ | |||
$io = $this->io; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the getOption method. I think it would be better to handle the option stuff on the outside (inside the Command) and set an explicit setting on the runner with $runner->setActions
or $runner->disablePlugins
...
This way we could get rid of the option
methods.
$this->io->write(' - <fg=blue>' . $this->formatActionOutput($action->getAction()) . '</> : ', false); | ||
|
||
if (!$this->doConditionsApply($action->getConditions())) { | ||
$this->io->write('<comment>skipped</comment>', true); | ||
if ($this->checkSkipAction($action)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
149f4f6
to
5f589b4
Compare
This PR adds 3 new hook command options:
--list-actions
--action
--disable-plugins
--list-actions
This option allows you to list all the configured actions for a given hook:
--action
This option allows you to pass one or more actions to execute for a given hook. All other actions configured for the hook are skipped.
--disable-plugins
This option is useful for combining with the
--action
option to disable any plugins while executing only the specified actions.Rationale
As discussed in #122, I'm working on a
DisallowActionChanges
plugin that will extend thePreserveWorkingTree
plugin to check whether any actions make changes and, if so, fail. As part of the failure message, I want to list the actions that made changes and instruct the user with a message like this:The
--list-actions
option is a helper option that I thought to include so a user can quickly list all actions configured for a hook. The names of the actions it lists are the same names that you would pass to the--action
option.IO::getOptions() and IO::getOption()
I've added these two methods to allow retrieving options from IO, just like you can retrieve arguments. However, I did not add these to the
IO
interface, since that would likely require a major version bump. For now, they're only onConsole\IO\DefaultIO
andConsole\IO\Base
. They should also be added to theConsole\IO
interface in version 6.0.0.