GithubHelp home page GithubHelp logo

Comments (6)

sebastianfeldmann avatar sebastianfeldmann commented on June 9, 2024 1

I just released version 5.14.2 that displays the errors even if the failure is not killing the got command.

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on June 9, 2024

I just released version 5.14.0 with the new settings. A more detailed description can be found on the release page.

from captainhook.

alfredbez avatar alfredbez commented on June 9, 2024

Many thanks for the fast feedback 🚀

I'm unsure if I'm doing something wrong or if there is an issue either in the documentation of the new feature or in the future itself.

Your code example shows that the new flag can be added to the settings section, but the code and also the test reads it from config:

Can you clarify that?

Bonus point: It would be awesome to print the error message even if the action is allowed to fail.

A fix for both things I mentioned can look like this:

diff --git a/src/Config/Factory.php b/src/Config/Factory.php
index c1d4c85..abfcbce 100644
--- a/src/Config/Factory.php
+++ b/src/Config/Factory.php
@@ -176,8 +176,8 @@ private function configureHook(Config\Hook $config, array $json): void
             $conditions = isset($actionJson['conditions']) && is_array($actionJson['conditions'])
                         ? $actionJson['conditions']
                         : [];
-            $settings   = isset($actionJson['config']) && is_array($actionJson['config'])
-                        ? $actionJson['config']
+            $settings   = isset($actionJson['settings']) && is_array($actionJson['settings'])
+                        ? $actionJson['settings']
                         : [];
             $config->addAction(new Config\Action($actionJson['action'], $options, $conditions, $settings));
         }
diff --git a/src/Runner/Hook.php b/src/Runner/Hook.php
index 8f323f4..1307779 100644
--- a/src/Runner/Hook.php
+++ b/src/Runner/Hook.php
@@ -342,6 +342,10 @@ private function handleAction(Config\Action $action): void
             $this->io->write('<info>done</info>', true);
         } catch (Exception  $e) {
             $this->io->write('<error>failed</error>', true);
+            $errorMessage = $action->getOptions()->get('error', false);
+            if (!$errorMessage) {
+                $this->io->write($errorMessage, true);
+            }
             if (!$action->isFailureAllowed($this->config->isFailureAllowed())) {
                 throw $e;
             }

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on June 9, 2024

You are absolutely right, I mixed up the json indexes and the object property name.
Definitely not a smart decision to call them settings in code but config in json.

So I fixed the mismatch in version 5.14.1.

You should use config within your configuration file.

I updated the release notes, so this should work now.

{
  "pre-commit": {
    "is-enabled": true,
    "actions": [
      {
        "action": "ls -lisa",
        "config": {"allow-failure": true}
      }
    ]
  }

from captainhook.

alfredbez avatar alfredbez commented on June 9, 2024

Thanks for clarification 👍

Regarding the error message: Would you be open for a PR that adds something like this?

--- a/src/Config/Action.php
+++ b/src/Config/Action.php
@@ -23,6 +23,16 @@
  */
 class Action
 {
+    public const STATE_NOT_EXECUTED_YET = 1;
+    public const STATE_SKIPPED = 2;
+    public const STATE_SUCCESSFULLY_EXECUTED = 3;
+    public const STATE_FAILED = 4;
+
+    /**
+     * @var self::STATE_*
+     */
+    private int $currentState;
+
     /**
      * Action php class, php static method, or cli script
      *
@@ -74,6 +84,23 @@ public function __construct(string $action, array $options = [], array $conditio
         $this->setupOptions($options);
         $this->setupConditions($conditions);
         $this->setupSettings($settings);
+        $this->setCurrentState(self::STATE_NOT_EXECUTED_YET);
+    }
+
+    /**
+     * @param self::STATE_* $state
+     */
+    public function setCurrentState(int $state): void
+    {
+        $this->currentState = $state;
+    }
+
+    /**
+     * @return self::STATE_*
+     */
+    public function getCurrentState(): int
+    {
+        return $this->currentState;
     }

     /**
diff --git a/src/Runner/Hook.php b/src/Runner/Hook.php
index 8f323f4..5b2286e 100644
--- a/src/Runner/Hook.php
+++ b/src/Runner/Hook.php
@@ -314,6 +314,7 @@ private function executeFailAfterAllActions(array $actions): void
     private function handleAction(Config\Action $action): void
     {
         if ($this->shouldSkipActions()) {
+            $action->setCurrentState(Config\Action::STATE_SKIPPED);
             $this->io->write(
                 $this->formatActionOutput($action->getAction()) . ': <comment>deactivated</comment>',
                 true
@@ -324,6 +325,7 @@ private function handleAction(Config\Action $action): void
         $this->io->write(' - <fg=blue>' . $this->formatActionOutput($action->getAction()) . '</> : ', false);

         if (!$this->doConditionsApply($action->getConditions())) {
+            $action->setCurrentState(Config\Action::STATE_SKIPPED);
             $this->io->write('<comment>skipped</comment>', true);
             return;
         }
@@ -333,14 +335,17 @@ private function handleAction(Config\Action $action): void
         // The beforeAction() method may indicate that the current and all
         // remaining actions should be skipped. If so, return here.
         if ($this->shouldSkipActions()) {
+            $action->setCurrentState(Config\Action::STATE_SKIPPED);
             return;
         }

         try {
             $execMethod = self::getExecMethod(Util::getExecType($action->getAction()));
             $this->{$execMethod}($action);
+            $action->setCurrentState(Config\Action::STATE_SUCCESSFULLY_EXECUTED);
             $this->io->write('<info>done</info>', true);
         } catch (Exception  $e) {
+            $action->setCurrentState(Config\Action::STATE_FAILED);
             $this->io->write('<error>failed</error>', true);
             if (!$action->isFailureAllowed($this->config->isFailureAllowed())) {
                 throw $e;

That would allow us to create a Plugin which prints the error message in the afterAction if the action failed. I think this can be beneficial to other scenarios, too.

Otherwise, we would either need to use composer-patches or overwrite the Regex action like so:

use CaptainHook\App\Config;
use CaptainHook\App\Console\IO;
use CaptainHook\App\Exception\ActionFailed;
use SebastianFeldmann\Git\Repository;

class Regex extends \CaptainHook\App\Hook\Message\Action\Regex
{
    public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
    {
        try {
            parent::execute($config, $io, $repository, $action);
        } catch (ActionFailed $exception) {
            $io->write('<error>failed</error>');
            $io->write($exception->getMessage());
        }
    }
}

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on June 9, 2024

The error should still be visible but you are right the error exception message is not displayed anymore.

I think tracking the state of the executed action is not enough. You would have to keep tabs on the original exception message as well to print it in any afterAction plugin.

I think it would make sense to display the error messages anyway so we should store the allowed error messages and after executing all actions display all occurred errors.

from captainhook.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.