Very flexible git hook manager for php developers

Overview

Latest Stable Version Minimum PHP Version Downloads License Build Status Scrutinizer Code Quality Code Coverage Twitter

CaptainHook

CaptainHook logo

CaptainHook is an easy to use and very flexible git hook library for php developers. It enables you to configure your git hook actions in a simple json file.

You can use CaptainHook to validate or prepare your commit messages, ensure code quality or run unit tests before you commit or push changes to git. You can automatically clear local caches or install the latest composer dependencies after pulling the latest changes.

CaptainHook makes it easy to share hooks within your team and even can make sure that everybody in your team activates the hooks locally.

You can run cli commands, use some built in validators, or write your own PHP classes that get executed by CaptainHook. For more information have a look at the documentation.

Installation

Install the CaptainHook PHAR using Phive or download the PHAR from the github release page.

    $ phive install captainhook

Or use Composer to install CaptainHook.

    $ composer require --dev captainhook/captainhook

Setup

After installing CaptainHook you can use the captainhook executable to create a configuration.

    $ vendor/bin/captainhook configure

Now there should be a captainhook.json configuration file.

If you are not using the composer-plugin yet you have to activate the hooks manually by installing them to your local .git repository. To do so just run the following captainhook command.

    $ vendor/bin/captainhook install

Have a look at this short installation video.

Install demo

If you want to make sure your whole team uses the same hooks and you want to make sure everybody has the hooks installed you can use the CaptainHook composer-plugin as an addition.

    $ composer require --dev captainhook/plugin-composer

The plugin will make sure that the hooks get activated after every composer install or update. If you don't like the extra dependency just add the following scripts command to your composer.json file instead.

{
  "scripts": {
    "post-autoload-dump": "vendor/bin/captainhook install -f -s"
  }
}

Configuration

Here's an example captainhook.json configuration file.

{
  "commit-msg": {
    "enabled": true,
    "actions": [
      {
        "action": "\\CaptainHook\\App\\Hook\\Message\\Action\\Beams",
        "options": []
      }
    ]
  },
  "pre-commit": {
    "enabled": true,
    "actions": [
      {
        "action": "phpunit"
      },
      {
        "action": "phpcs --standard=psr2 src"
      }
    ]
  },
  "pre-push": {
    "enabled": false,
    "actions": []
  }
}

Contributing

So you'd like to contribute to the CaptainHook library? Excellent! Thank you very much. I can absolutely use your help.

Have a look at the contribution guidelines.

Comments
  • Make written hook files relocatable

    Make written hook files relocatable

    I don't like absolute path being hardcoded to hook files.

    It should be possible to detect GIT_DIR (git already exports it afaik) or resolve from basename of "$0".

    ➜ pwd
    /Users/glen/scm/eventum/eventum
    
    ➜ head .git/hooks/post-commit
    #!/bin/sh
    
    # installed by CaptainHook 5.10.6
    
    INTERACTIVE="--no-interaction"
    
    /Users/glen/Library/Caches/glen/composer/eventum/eventum/vendor/captainhook/captainhook/bin/captainhook $INTERACTIVE --configuration=captainhook.json --bootstrap=vendor/autoload.php hook:post-commit "$@" <&0
    
    opened by glensc 27
  • [Feature] Non-empty directory and file check

    [Feature] Non-empty directory and file check

    We have created custom hooks that check if a give file or a given directory is empty.

    The checkFile hook we have differs a bit from https://github.com/CaptainHookPhp/captainhook/blob/63627ba9b1140674164ea66619ee1225555edaca/src/Hook/File/Action/IsEmpty.php since we open the file and check for its contents and make sure that its not an empty file.

    We also have a CheckFolder hook that checks a given folder if its empty or not. Could this be something that could be implemented as a core feature? If so, we are willing to open a PR for this.

    If not, we would submit these features as a custom module/plugin in https://captainhookphp.github.io/captainhook/extend.html#plugins

    question feature request 
    opened by BorisovskiP 20
  • Fatal Error During Execution After Branch Change

    Fatal Error During Execution After Branch Change

    We use local Composer repositories, so our composer.json contains something like this:

    "local-packages": {
        "type": "path",
        "url": "./local-packages/*/*"
    }
    

    This means that our local packages reside under ./local-packages/Namespace/Module and can be included via Composer. Since these are client-specific packages, we require the @dev version from it. This way, the modules are symlinked into the vendor directory and we always have the latest version installed. Example:

    $ ll vendor/namespace/module
    lrwxrwxrwx 1 www-data tape 23 May  6 07:52 vendor/namespace/module -> ../../local-packages/Namespace/Module
    

    When I now switch branches and one of these local modules is not available in the new branch, we have a broken symlink and I get a fatal error during the CaptainHook execution:

    $ vendor/captainhook/captainhook/bin/captainhook -vvv                                                                                07:49:25
    PHP Warning:  require(/var/www/html/vendor/composer/../namespace/module/registration.php): failed to open stream: No such file or directory in /var/www/html/vendor/composer/autoload_real.php on line 75
    
    Warning: require(/var/www/html/vendor/composer/../namespace/module/registration.php): failed to open stream: No such file or directory in /var/www/html/vendor/composer/autoload_real.php on line 75
    PHP Fatal error:  require(): Failed opening required '/var/www/html/vendor/composer/../namespace/module/registration.php' (include_path='/var/www/html/vendor/magento/zendframework1/library:.:/usr/share/pear:/usr/share/php') in /var/www/html/vendor/composer/autoload_real.php on line 75
    
    Fatal error: require(): Failed opening required '/var/www/html/vendor/composer/../namespace/module/registration.php' (include_path='/var/www/html/vendor/magento/zendframework1/library:.:/usr/share/pear:/usr/share/php') in /var/www/html/vendor/composer/autoload_real.php on line 75
    

    It breaks exactly at the line require CAPTAINHOOK_COMPOSER_AUTOLOAD; of bin/captainhook. I tried dumping the autoloader via composer dump-autoload before the hook execution, but even this does not work. Only a composer install before the hook execution fixes the issue.

    Do you see any way to fix this, @sebastianfeldmann? My current idea would be to wrap the require call in a try-catch-block and if an exception occurs, run composer install automagically and try to require the autoload file again. I think this should work, but not sure if you find this workaround acceptable...?

    bug 
    opened by sprankhub 19
  • Implement plugin system and add PreserveWorkingTree plugin

    Implement plugin system and add PreserveWorkingTree plugin

    Description

    I went through several refactorings of this PR before I decided to open it up for final review.

    In its current state, this diverges from the proposed functionality in #122 in that this implements a plugin system that allows for plugins that can execute code before and after a hook runs, as well as before and after each action runs. This allows extensions to hook into the beforeHook(), beforeAction(), etc. methods to extend what CaptainHook can do.

    This PR also provides an initial plugin to illustrate the plugin behavior: PreserveWorkingTree. This plugin implements some of the feature I proposed in #122. When added to the plugins list in captainhook.json, this plugin will run before and after each hook to move any working tree changes out of the way and then reapply them. It will do this for any hook, since it's possible that an action in any hook could modify the working tree and/or staged files. Others can extend this class and implement the Constrained interface to constrain it to only specific hooks.

    Notable Changes/Details

    • I've changed the CaptainHook\App\Runner\Hook::beforeAction() signature to include a CaptainHook\App\Config\Action $action parameter. This is so we can pass this value to the plugin. Technically, this is a BC break, since this is a public method, and children of Hook that override this method will need to update their signatures. However, in practice, I don't think CaptainHook provides a way to inject your own hook classes to override the ones in CaptainHook\App\Runner\Hook, so this change might not affect any external users.
    • I've changed the CaptainHook\App\Runner\Hook::afterAction() signature for the same reason.
    • I've moved Hook::beforeAction() and Hook::afterAction() into the Hook::handleAction() method, so they will now run for both PHP and CLI actions (previously, they only ran before and after PHP actions).
    • As long as the hook is enabled, Hook::beforeHook() and Hook::afterHook() will always run, even if there are no actions. This allows runner plugins to run their beforeHook() and afterHook() methods, even if the hook has no actions configured. Previously, if there were no actions, these methods did not execute.
    • Added Hook::shouldSkipActions(?bool $shouldSkip = null): bool that allows plugins to tell the hook to skip any remaining actions.
    • Added Hook::getName() to return the string name of the hook, so plugins can use this.
    • Added a CaptainHookException interface that all CaptainHook exceptions implement.

    Documentation

    The following documentation has also been submitted as part of https://github.com/captainhookphp/captainhook/pull/130

    Plugins

    Actions and Conditions are suitable for most needs, but there may be times you need to add more functionality to CaptainHook, such as performing tasks before or after a hook runs. CaptainHook's plugin system provides this flexibility!

    All CaptainHook plugins implement the CaptainHook\App\Plugin\CaptainHook interface. To use a plugin, add it to the plugins array in your config. If a plugin requires options, you may also provide those.

    {
      "config": {
        "plugins": [
          {
            "plugin": "\\MyName\\GitHook\\MyPlugin",
            "options": {
              "myOption": true,
              "stuff": "cool things"
            }
          }
        ]
      }
    }
    

    Runner Plugins

    Runner plugins are so-called because they execute during the hook runner stage of CaptainHook, allowing you to do things before and after the hook runs, as well as before and after each action in the hook.

    To create a runner plugin, implement the CaptainHook\App\Plugin\Runner interface. Optionally, you may extend the CaptainHook\App\Plugin\Runner\Base abstract class, which provides some basic functionality.

    To see an example runner plugin, check out CaptainHook\App\Plugin\Runner\PreserveWorkingTree.

    namespace MyName\GitHook;
    
    use CaptainHook\App\Config;
    use CaptainHook\App\Plugin;
    use CaptainHook\App\Runner\Hook as RunnerHook;
    
    class MyPlugin extends Plugin\Runner\Base implements Plugin\Runner
    {
        /**
         * Runs before the hook.
         *
         * @param RunnerHook $hook This is the current hook that's running.
         */
        public function beforeHook(RunnerHook $hook): void
        {
            $stuff = $this->plugin->getOptions()->get('stuff');
            $this->io->write("Do {$stuff} before {$hook->getName()} runs");
        }
    
        /**
         * Runs before each action.
         *
         * @param RunnerHook $hook This is the current hook that's running.
         * @param Config\Action $action This is the configuration for action that will
         *                              run immediately following this method.
         */
        public function beforeAction(RunnerHook $hook, Config\Action $action): void
        {
            $this->io->write("Do stuff before action {$action->getAction()} runs");
        }
    
        /**
         * Runs after each action.
         *
         * @param RunnerHook $hook This is the current hook that's running.
         * @param Config\Action $action This is the configuration for action that just
         *                              ran immediately before this method.
         */
        public function afterAction(RunnerHook $hook, Config\Action $action): void
        {
            $this->io->write("Do stuff after action {$action->getAction()} runs");
        }
    
        /**
         * Runs after the hook.
         *
         * @param RunnerHook $hook This is the current hook that's running.
         */
        public function afterHook(RunnerHook $hook): void
        {
            $this->io->write("Do stuff after {$hook->getName()} runs");
        }
    }
    
    opened by ramsey 18
  • Discussion - Force PHAR usage via sub package

    Discussion - Force PHAR usage via sub package

    Problem

    Currently there are two ways to execute the Cap'n. The first is executing the PHP script installed via composer, the second one is via PHAR file. Both methods have some minor but significant differences that could lead to maintaining problems in the future.

    Possible solution

    To get back to a single way of executing the Cap'n the idea is to transform the main captainhook composer package into a PHAR container package only containing the PHAR files and move the source code and all to a new captainhook-app repository. As an example you can see something similar in the PHPStan repository.

    Pro

    • Only one way of execution
    • Easier to maintain
    • Less bugs (hopefully)
    • Never any version collisions because of the isolated scoped PHAR file (this is HUGE)

    Contra

    • Testing a dev-master state would get really complicated and will potentially stupidly increase the size of the PHAR container repository if we would commit a new PHAR for every push into the app repository.
    • Not important but I personally do not like the idea of committing binary files to a repository :)

    Side effect

    Doing this change would have a nice side effect. The main package could be converted into a composer plugin. This would make the handling of certain events easier (install/uninstall) and we could deprecate the plugin-composer package and always have the functionality build in from the get go. If someone needs the pure variant without composer, they could always go for the PHAR only installation.

    Things to consider

    A possible migration could be challenging. Older versions should still be installable so we would have to "leave" the source code and all inside the main repository (at least in the git history) even if it is not needed there for the latest version. No biggy but then we would have 2 repositories with the full source code history until version 5 🤦

    The release process would get massively more complicated

    • Push and tag app repository
    • Build PHAR
    • Copy PHAR to main repository
    • Commit PHAR into main repository
    • Tag main repository as well
    • Create release for main repository with PHAR and signature file

    I'm happy to get feedback on this idea.

    question 
    opened by sebastianfeldmann 18
  • PHPStan runs forever as pre-commit hook

    PHPStan runs forever as pre-commit hook

    This might be similar to https://github.com/CaptainHookPhp/captainhook/issues/35, but I opened a new issue to be more specific:

    I have a reasonably large codebase with lots of legacy code, and am using PHPStan and Psalm for new code while ignoring the issues in the older code. I usually run PHPStan via composer (so I can just type in composer phpstan) and that works fine.

    I attempted a few times to add the exact same command I use via composer scripts as a pre-commit hook with CaptainHook, but it seems PHPStan crashes without CaptainHook noticing, as the PHPStan command just runs forever and never returns: via composer it runs for maybe 15-20 seconds, but even after waiting for 10 minutes or longer via CaptainHook nothing happens. This has been an issue ever since I adopted PHPStan for the project (about 6 months ago) and is still occuring with the latest PHP 7.3 version and the latest CaptainHook and PHPStan versions.

    Why I report this here instead of with PHPStan is that it does work via composer scripts, which should work similarly as CaptainHook (with spawning another process, running it and then reporting back), and because CaptainHook just waits forever on PHPStan and there is no error message or hint what actually happened to PHPStan, so I actually wouldn't know what problem to report, where it occurs and why.

    This problem does not occur with a new 6-month-old codebase, so there is something in this legacy project that leads to the problem. Ideally there would be a way to show the output from PHPStan while running CaptainHook, or maybe something that composer scripts does can be added to CaptainHook to overcome this.

    bug 
    opened by iquito 17
  • {$STAGED_FILES} empty in docker

    {$STAGED_FILES} empty in docker

    Hello !

    When using Cap'n in Laravel Sail (a simple wrapper for docker-compose), {$STAGED_FILES} is empty.

    Here is a configuration sample:

    {
        "config": {
            "run-mode": "docker",
            "run-exec": "docker-compose exec -T -u sail -e \"APP_URL=http://laravel.test\" -e \"DUSK_DRIVER_URL=http://selenium:4444/wd/hub\" laravel.test",
            "verbosity": "verbose"
        },
        "pre-commit": {
            "enabled": true,
            "actions": [
                {
                    "action": "echo {$STAGED_FILES} > .commit && echo '----' >> .commit",
                    "options": [],
                    "conditions": []
                },
                {
                    "action": "git diff-index --name-status HEAD >> .commit",
                    "options": [],
                    "conditions": []
                }
            ]
        }
    }
    

    Here is the output of the .commit file:

    
    ----
    M	captainhook.json
    

    If I remove the run-* directives and reinstall the hooks, the output of the .commit file is :

    captainhook.json
    ----
    M	captainhook.json
    

    as expected.

    under-investigation 
    opened by potsky 16
  • Post-pull hook

    Post-pull hook

    Hello,

    I would like to have a post-pull hook in my project, so every time I execute a git pull it could clear the local cache, execute other developers database migrations, or so. Do I make a PR? I think it should be more or less as #22.

    question 
    opened by cmmata 13
  • git lfs cannot be installed when using captainhook

    git lfs cannot be installed when using captainhook

    $ git lfs install
    Hook already exists: pre-push
    
    	#!/usr/bin/env php
    	<?php
    	$autoLoader = __DIR__ . '/../../vendor/autoload.php';
    	
    	if (!file_exists($autoLoader)) {
    	fwrite(STDERR, 'Composer autoload.php could not be found');
    	exit(1);
    	}
    	require $autoLoader;
    	$config = realpath(__DIR__ . '/../../captainhook.json');
    	$app    = new CaptainHook\App\Console\Application\Hook();
    	$app->setHook('pre-push');
    	$app->setConfigFile($config);
    	$app->setRepositoryPath(dirname(dirname(__DIR__)));
    	$app->run();
    
    To resolve this, either:
      1: run `git lfs update --manual` for instructions on how to merge hooks.
      2: run `git lfs update --force` to overwrite your hook.
    

    So I called

    $ git lfs update --manual
    Add the following to .git/hooks/pre-push:
    
    	#!/bin/sh
    	command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n"; exit 2; }
    	git lfs pre-push "$@"
    

    But how can I merge a shell script with a PHP script?

    opened by amenk 12
  • [Feature] Allow HookAction to run only for specific hooks

    [Feature] Allow HookAction to run only for specific hooks

    For most HookActions it's probably irrelevant to which Git hook they belong. For some HookActions like captainhook-rejectpush a specific hook needs to be configured to make sure the HookAction works as intended.

    I'd love to see a method in the HookAction that will be used by the Capt'n to check which hooks are valid for this action. When running the Capt'n each action configuration for the current Git hook needs to be checked and fail in case an ActionHook is used that "does not work" in the current Git hook configuration.

    Basically I see two ways to accomplish this:

    • Extend the existing CaptainHook\App\Hook\Action with a parent method that would allow the HookAction to be executed in all Git hooks (as it works now)
    • Add a new marker interface with one specific method that HookActions need to implement. If the object instance does not implement the interface it would mean execute in all Git hooks (as it works now)
    feature request 
    opened by shochdoerfer 11
  • Docker error configuration with own images (or how to configure with cap'n image)

    Docker error configuration with own images (or how to configure with cap'n image)

    I'm trying to configure captainhook to run inside my docker container with my custom docker image with PHP 7.2

    # run inside my container
    cd /var/ww/html/project && vendor/bin/captainhook install -f --container <my_container> -r docker
    

    ( /var/www/html/project is a docker shared folder with my git project)

    If I check the git hooks configurations I found this (example)

    FILE: .git/hooks/commit-msg

    #!/usr/bin/env bash
    docker exec <my_container> ./ndor/bin/captainhook-run commit-msg "$@"%  
    

    And the problem seems in this file: src/Hook/Template/Builder.php because the "vendor path configuration" is based on captainhook docker images.

    Question: how do you configure captainhook with your images?

    bug 
    opened by giuseppemorelli 11
  • Allow a working directory to be specified

    Allow a working directory to be specified

    We are adding some additional (micro) services to our project, so now we have:

    composer.json
    composer.lock
    services/
      foo/
        package.json
        package-lock.json
    

    I'd like to be able to check for changes to services/foo/package{-lock,}.json and execute npm install but within the services/foo directory.

    Is there any way that I can tell CaptainHook to execute the action in a different directory? I'm looking for something like:

    {
      "action": "npm install",
      "options": {
        "in-directory": "services/foo"
      },
      "conditions": [ ]
    }
    
    opened by shadowhand 2
  • [Question] Cannot specify git directory with composer plugin

    [Question] Cannot specify git directory with composer plugin

    Recently we have tried to add captainhook to our project, currently using a dockerized project with a PHP container, so for that reason, we used the following command as we use docker, and we have .git folder one level above the src.

    vendor/bin/captainhook install --run-mode=docker --run-exec="docker exec elmo-beta-php" --git-directory=../.git

    The thing is, we wanted to use the plugin suggested in the docs, so the team will have the hooks activated in their local repository. But we found out that we cannot specify the git directory this way.

    Maybe are we missing something? It's possible that the install command should be executed first and then install the composer plugin?

    We have tried to create a symbolic link of our .git inside the src folder, but turns out is not possible.

    Any suggestion will be gladly received! Thanks in advance and thanks for create this repo :)

    question 
    opened by miguel-is-coding 3
  • $STAGED_FILES is empty during ´git commit -a´ in Docker mode

    $STAGED_FILES is empty during ´git commit -a´ in Docker mode

    @renky @ktomk

    STAGED_FILES are empty in a 'commit -a -m' call if you didn't add anything before.... But nevertheless I'd like to check them in a 'commit -a -m' call

    In my case I modified two files (js and php) and if I call: git diff-index --diff-algorithm=myers --no-ext-diff --cached --name-status HEAD i get no files

    git diff-index --diff-algorithm=myers --no-ext-diff --name-status HEAD shows me the two files...

    so the question is, why only look onto the really staged files? From my point of view git commit -a -m is an often used command...

    here my output:

    $ git status
    On branch testbranch
    Your branch is ahead of 'origin/testbranch' by 14 commits.
      (use "git push" to publish your local commits)
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   app/Http/Controllers/Controller.php
            modified:   resources/js/app.js
    
    no changes added to commit (use "git add" and/or "git commit -a")
    

    now run

    $git commit -a -m "testmessage"
    

    all hooks are skipped due to empty STAGED_FILES

    What could be the solution - remove --cached option to get all files? Only add files that would be commited with commit -a -> this means only formatter M - so git diff-index would have to be called twice - first time with --cached and all formatters, and second time without --cached but only formatter M

    If captain hook would have the possibility to get the commit-attributes, maybe it even could check if commit was called with the -a option and add unstaged modified files in this case?

    Another option would also be to add a new Variable - UNSTAGED_FILES additionally to STAGED_FILES - then everybody could decide on his own if he wants to search in both...

    EDIT: I made additional tests. I modified a php-File without calling git add. captainhook is running in local run-mode

    "config": {
            "verbosity": "verbose"
        },
    

    I added a dump in git/src/Operator/Index.php in Line 205 and dump the result:

    $result    = $this->runner->run($cmd, $formatter);
    dd($result);
    $files     = $result->getFormattedOutput();
    

    When calling git commit -a -m "test" I get the following result:

    SebastianFeldmann\Cli\Command\Runner\Result^ {#203
      -cmdResult: SebastianFeldmann\Cli\Command\Result^ {#200
        -cmd: "git diff-index --diff-algorithm=myers --no-ext-diff --cached --name-status HEAD"
        -code: 0
        -validExitCodes: array:1 [
          0 => 0
        ]
        -buffer: array:1 [
          0 => "M\tapp/Models/Model.php"
        ]
        -stdOut: "M\tapp/Models/Model.php\n"
        -stdErr: ""
        -redirectPath: ""
      }
      -formatted: array:1 [
        0 => "app/Models/Model.php"
      ]
    }
    

    So it really finds the modified file, although it is not staged already! thats the behaviour I'd expect.

    Now I switch to docker run-mode - without changing any other file - still only modified and not staged.:

      "config": {
          "verbosity": "verbose",
          "run-mode": "docker",
          "run-exec": "docker exec -t phpcontainer"
      },
    

    and my dump gives me this:

    SebastianFeldmann\Cli\Command\Runner\Result^ {#202
      -cmdResult: SebastianFeldmann\Cli\Command\Result^ {#199
        -cmd: "git diff-index --diff-algorithm=myers --no-ext-diff --cached --name-status HEAD"
        -code: 0
        -validExitCodes: array:1 [
          0 => 0
        ]
        -buffer: []
        -stdOut: ""
        -stdErr: ""
        -redirectPath: ""
      }
      -formatted: []
    }
    

    so the same situation, one time local, one time docker gives different result. What I don't understand: If I call the command

    git diff-index --diff-algorithm=myers --no-ext-diff --cached --name-status HEAD
    

    directly on the bash it ALLWAYS doesn't give me any result - so I don't understandy why in the first case (local) it really finds any file...

    bug 
    opened by sebastianfeldmann 30
  • Do not prevent Git usage if Captain Hook installation is broken

    Do not prevent Git usage if Captain Hook installation is broken

    There is some edge case scenario, that happens sometimes in our organisation:

    • Install Captain Hook and its hooks
    • vendor/bin/captainhook is created, vendor/captainhook/captainhook is available, everything works in Git
    • Remove vendor
    • Try to commit something 😉

    There is error: .git/hooks/pre-commit: line 7: vendor/bin/captainhook: No such file or directory which prevents commit

    In our case it happens because we have huge monolith app and some people does not work with PHP there, sometimes people just want to fix some texts without building whole app. The problem is that sometimes they trigger Captain Hook's scripts installation (we have it on post-autoload-dump) and then for some reason remove vendor dir. In the end they have invalid environment, with Git hooks installed, and vendor/bin/captainhook called, which fails. It leads to problems because often people do not know how to fix it which causes unneeded discussions.

    It would be great if Captain Hook was fail-safe and transparent from developer's point of view. Each script or wrapper should not prevent from using Git when CH installation is broken.

    PS. similar scenario is when vendor dir is present, vendor/bin/captainhook is present, but only vendor/captainhook/captainhook is missing for some reason:

    Warning: fopen(.../vendor/bin/../captainhook/captainhook/bin/captainhook): failed to open stream: No such file or directory in .../vendor/bin/captainhook on line 35
    PHP Warning:  include(phpvfscomposer:///.../vendor/bin/../captainhook/captainhook/bin/captainhook): failed to open stream: "Composer\BinProxyWrapper::stream_open" call failed in .../vendor/bin/captainhook on line 112
    
    opened by Wirone 1
  • [feature] install only enabled hooks

    [feature] install only enabled hooks

    when running in docker mode, every hook has to spawn a new container, even if the corresponding captain hook is disabled. This is not a big issue, but in scenarios involving multiple hooks, the time allocated to starting a container per hook to print "hook disabled" is not negligible.

    The user can explicitely choose hooks to install with the --hook option, but this only accepts a single hook name

    An additional option like --only-activated could be useful in such scenarii.

    The drawback I can see is that any change to captainhook.json is not automatically propagated to hooks, and the doc has to be clear about this (We can even suggest an action running captainhook install every time the config file has changed).

    If this sounds a reasonable feature to you, I am willing to contribute with a PR.

    feature request 
    opened by CircleCode 3
  • [feature] add a custom hint for failing actions

    [feature] add a custom hint for failing actions

    In some companies, or communities, code rules are detailed in custom documentation. For example, in my compani, we have a comprehensive code style redacted and hosted in our internal wiki. When lint action fails, I'd like to add a message like this:

    Your code does not pass the code style.
    Go ahead and read it carefully at https://example.net/.
    Note: you can automatically fix modified files by running make beautify-php
    

    I'd suggest to add a hint section in actions, accepting:

    • a single string to be printed
    • an array of strings to be printed

    Note: I was wondering if accepting a custom callable would be useful, and I am not against it, but if you are about to write custom code, why not writing the full action in custom code, and thus you do not need the hint section.

    If this sounds a reasonable feature to you, I am willing to contribute with a PR.

    feature request 
    opened by CircleCode 5
Releases(5.12.0)
Owner
CaptainHook
CaptainHook
Creating data transfer objects with the power of php objects. No php attributes, no reflection api, and no other under the hook work.

Super Simple DTO Creating data transfer objects with the power of php objects. No php attributes, no reflection api, and no other under the hook work.

Mohammed Manssour 8 Jun 8, 2023
Very easy to use a current limiting component, the code is very simple, based on the webman framework.

Very easy to use a current limiting component, the code is very simple, based on the webman framework.

nsp-team 13 Dec 29, 2022
Hook-logger-plugin - Debug WordPress action / filter hooks.

hook-logger-plugin Easily debug WordPress action / filter hooks, finding where actions are called from and understanding the flow of execution. This p

bruce aldridge 4 Feb 5, 2022
An amazing Rank and Permissions Manager. The best ranks manager for PocketMine-MP.

?? RankSystem ?? An amazing Rank and Permissions Manager Description: An amazing Rank and Permissions Manager. The best ranks manager for PocketMine-M

null 22 Nov 7, 2022
Laravel Podcast Manager is a complete podcast manager package for Laravel 5.3+ that enables you to manage RSS feeds for your favorite podcasts and listen to the episodes in a seamless UI.

laravelpodcast | A Laravel podcast manager package - v0.0.8 Introduction Laravel Podcast Manager is a complete podcast manager package for Laravel 5.3

Jeremy Kenedy 22 Nov 4, 2022
Laragon MultiPHP per App + PECL Module + Extension manager + Ini Manager

LMPA Laragon MultiPHP per App This tools allow you to run multiple PHP version per app with Laragon, so you can have multiple site running different p

Gilbert Paquin 8 Oct 10, 2022
This is an experiment to export all RFCs from the PHP wiki into Git, including the change history for each RFC (along with the date and author of each change). This is not meant to replace the wiki.

PHP Requests for Comments (RFCs) About This repository is an experiment to export all RFCs from the PHP wiki into Git, including the change history fo

Ben Ramsey 34 Jun 20, 2022
PhpGit - A Git wrapper for PHP 7.1+

PhpGit PhpGit - A Git wrapper for PHP 7.1+ The project is forked from https://github.com/kzykhys/PHPGit Requirements PHP 7.1+ Git Installation Update

PHPPkg 9 Nov 1, 2022
Remote Git Library for PHP

This library provides methods to handle git repositories remotely without having to clone the whole repo. It uses the Symfony process component to run the git client.

Martin Auswöger 4 Dec 14, 2022
Version is a library that helps with managing the version number of Git-hosted PHP projects

Version Version is a library that helps with managing the version number of Git-hosted PHP projects. Installation You can add this library as a local,

Sebastian Bergmann 6.3k Dec 26, 2022
Utility that helps you switch git configurations with ease.

git-profile Utility that helps you switch git configurations with ease Preface It is possible that you have multiple git configurations. For example:

Zeeshan Ahmad 240 Jul 18, 2022
Private, self-hosted Composer/Satis repository with unlimited private and open-source packages and support for Git, Mercurial, and Subversion.

Private, self-hosted Composer/Satis repository with unlimited private and open-source packages and support for Git, Mercurial, and Subversion. HTTP API, HTTPs support, webhook handler, scheduled builds, Slack and HipChat integration.

Łukasz Lach 112 Nov 24, 2022
RealMikrotikBackup - Система резервного копирования для оборудования Mikrotik, с возможностью использования функционала Git для контроля версий конфигураций оборудования.

Real Mikrotik Backup System Real Mikrotik Backup - это система централизованного создания и хранения резервных копий оборудования Mikrotik с функцией

Anton Moroz 23 Dec 18, 2022
Easily manage git hooks in your composer config

composer-git-hooks Manage git hooks easily in your composer configuration. This command line tool makes it easy to implement a consistent project-wide

Ezinwa Okpoechi 985 Jan 3, 2023
Text-mode interface for git

Tig: text-mode interface for Git What is Tig? Tig is an ncurses-based text-mode interface for git. It functions mainly as a Git repository browser, bu

Jonas Fonseca 11.4k Dec 30, 2022
CodeFever Community Edition (A Self-hosted Git Services)

CodeFever Community Edition (A Self-hosted Git Services)

PGYER 2.3k Jan 7, 2023
A Laravel test build by Incline Start-up Agency. Testing Git and framework functions.

Incognito-Confessions A laravel test build by Incline Start-up Agency. Testing Git and framework functions. Description A laravel starter for future t

null 6 Nov 9, 2022
AI PHP is a wrapper for rubix ml to make AI very approachable

AI PHP Rubix Wrap A wrapper for Rubix ML to make it very approachable Example: $report = RubixService::train($data, 'column_with_label'); Where co

null 15 Nov 5, 2022
This project is very diverse and based upon many languages and libraries such as C++, Python, JavaScript, PHP and MQTT

ADMS-Real-time-project This project is very diverse and based upon many languages and libraries such as C++, Python, JavaScript, PHP and MQTT Advance_

Nitya parikh 1 Dec 1, 2021