CaptainHook Documentation

repository·main·Indexed 22 days ago

https://github.com/captainhook-git/captainhook

A flexible git hook library for PHP developers that allows configuring git hook actions, such as validation or testing, via a JSON configuration file. It provides a CLI tool for managing hooks, support for custom actions (PHP classes or CLI scripts), and a Composer plugin for automatic hook installation across team members.

Tokens
9.6K
Snippets
41
Records
54
Agent score
78%

What's inside CaptainHook

  1. Ensure team members automatically install hooks

    main

    To prevent teammates from forgetting to install hooks locally, you can use the captainhook/hook-installer Composer plugin. This plugin automatically runs the captainhook install command whenever any Composer command is executed.

    composer require --dev captainhook/hook-installer
    composer require --dev captainhook/hook-installer
  2. Configure and activate CaptainHook hooks

    main

    After installation, follow these steps to set up your git hooks:

    1. Create a configuration file: Run the configure command to generate a captainhook.json file.

      vendor/bin/captainhook configure
    2. Activate the hooks: Install the hooks into your local .git directory to make them active.

      vendor/bin/captainhook install
    vendor/bin/captainhook configure
    vendor/bin/captainhook install
  3. Install CaptainHook

    main

    You can install CaptainHook using Phive, the PHAR Composer package, or by installing the full source code via Composer.

    Using Phive (Preferred)

    phive install captainhook

    Using Composer (PHAR package)

    composer require --dev captainhook/captainhook-phar

    Using Composer (Full source code)

    composer require --dev captainhook/captainhook
    phive install captainhook
  4. Configure an Action in CaptainHook

    main

    An Action represents a task to be performed during a git hook. It can be a PHP class, a static PHP method, or a CLI script. When defining an action, you can specify its execution command, associated options, conditions for execution, and specific settings like failure tolerance or labels.

    An action consists of:

    • Action: The command, class, or script to execute.
    • Options: Key-value pairs passed to the action.
    • Conditions: A list of requirements that must be met for the action to run. Each condition requires an exec key and can optionally include args.
    • Settings: Configuration metadata for the action itself.
  5. Use the {$BRANCH_FILES} placeholder to resolve changed files

    main

    The {$BRANCH_FILES} placeholder allows you to dynamically list files that have changed in your current branch.

    Supported Hooks: This placeholder is only functional for the following actions:

    • pre-push
    • post-rewrite
    • post-checkout
    • post-merge

    Note on pre-push: If you are pushing multiple refs at once, the placeholder will contain all changed files for all pushed refs.

    Available Filters/Modifiers: You can pipe the placeholder through several filters to refine the list of files:

    • |compare-to:<branch>: Compares the current branch against a specific branch (e.g., main). If not provided, it defaults to the branch's starting point from the reflog.
    • |separated-by:<delimiter>: Defines the character used to separate the file list (e.g., a comma or space).
    • |in-dir:<directory>: Limits the file list to a specific directory.
    • |of-type:<extension>: Limits the file list to files with a specific extension (e.g., php).
    # Compare current branch to main and separate by comma
    {$BRANCH_FILES|compare-to:main|separated-by:,}
    
    # List PHP files in the foo/bar directory
    {$BRANCH_FILES|in-dir:foo/bar|of-type:php}
  6. Use the {staged-files} placeholder in CaptainHook

    main

    The {staged-files} placeholder allows you to dynamically resolve a list of files currently in the git index (staged files) during a hook execution. This is useful for running commands like linters or testers only on the files that are about to be committed.

    You can customize the output of this placeholder using the following options:

    • diff-filter: A string of Git diff filter characters (e.g., A for Added, M for Modified, C for Copied, D for Deleted) to restrict which staged files are returned. Defaults to ['A', 'C', 'M', 'R'].
    • of-type: Restricts the files to a specific type (e.g., php, js).
    • separated-by: A string used to separate the file paths in the resulting list. Defaults to a single space ( ).
    • directory: (Implicitly used via FileList::filterByDirectory) Filters the list of files based on a directory path provided in the options.
    <!-- Example usage in captainhook.json -->
    {
        "actions": {
            "pre-commit": {
                "command": "vendor/bin/phpcs {staged-files}",
                "options": {
                    "diff-filter": "M",
                    "of-type": "php",
                    "separated-by": " "
                }
            }
        }
    }
  7. Replace argument placeholders in CLI actions

    main

    When defining actions in your CaptainHook configuration, you can use placeholders that represent Git hook arguments. The Cli runner automatically replaces these placeholders with their actual values before execution.

    Supported placeholders based on the hook type:

    Hook TypePlaceholders
    prepare-commit-msgFILE, MODE, HASH
    commit-msgFILE
    pre-pushTARGET, URL
    pre-commit- (no arguments)
    post-checkoutPREVIOUSHEAD, NEWHEAD, MODE
    post-mergeSQUASH
  8. Configure git hook actions in captainhook.json

    main

    CaptainHook uses a captainhook.json file to define actions for specific git hooks (e.g., commit-msg, pre-commit). Actions can be CLI commands or built-in validators.

    Example configuration:

    {
      "commit-msg": {
        "actions": [
          {
            "action": "CaptainHook.Message.MustFollowBeamsRules"
          }
        ]
      },
      "pre-commit": {
        "actions": [
          {
            "action": "phpunit"
          },
          {
            "action": "phpcs --standard=psr12 src"
          }
        ]
      }
    }
    {
      "commit-msg": {
        "actions": [
          {
            "action": "CaptainHook.Message.MustFollowBeamsRules"
          }
        ]
      },
      "pre-commit": {
        "actions": [
          {
            "action": "phpunit"
          },
          {
            "action": "phpcs --standard=psr12 src"
          }
        ]
      }
    }
  9. Use the {$CHANGED_FILES} placeholder to resolve changed files

    main

    The {$CHANGED_FILES} placeholder allows you to dynamically list files that have changed in the current commit or operation.

    Supported Actions This placeholder is only available for the following hook types:

    • pre-push (Note: if multiple refs are pushed, it contains all changed files for all refs)
    • post-rewrite
    • post-checkout
    • post-merge

    Filters and Formatting You can apply filters and separators to the placeholder using the pipe (|) syntax:

    • Separators: Use separated-by:<char>, to change the delimiter between files (defaults to a space).
    • Directory Filtering: Use in-dir:<path> to only include files within a specific directory.
    • File Type Filtering: Use of-type:<extension> to only include files with a specific extension.

    Example usage in a configuration file:

    • {$CHANGED_FILES|separated-by:,}
    • {$CHANGED_FILES|in-dir:foo/bar}
    • {$CHANGED_FILES|of-type:php}
    {$CHANGED_FILES|separated-by:,}
    {$CHANGED_FILES|in-dir:foo/bar}
    {$CHANGED_FILES|of-type:php}
  10. Use environment variable placeholders in CaptainHook commands

    main

    CaptainHook supports placeholders in command configurations that can resolve environment variables. When using the Env placeholder processor, you can inject the value of an environment variable into your command string using specific options.

    To resolve an environment variable, provide the following options in your configuration:

    • value-of: The name of the environment variable to retrieve.
    • default: (Optional) The fallback value to use if the environment variable is not set. If not provided, it defaults to an empty string.
    {
        "value-of": "MY_ENV_VAR",
        "default": "fallback_value"
    }
  11. Use placeholders in CLI commands

    main

    CaptainHook allows the use of placeholders within CLI command configurations to inject dynamic values. Placeholders follow a specific syntax using the pipe (|) character to separate the placeholder name from its options.

    Syntax

    {name}|option1:value1|option2:value2

    • name: The identifier for the placeholder (case-insensitive).
    • options: A list of key-value pairs separated by pipes, where each pair uses a colon (:) to separate the option name from its value (e.g., key:value).

    Features

    • Caching: You can control whether a placeholder's resolved value should be cached by using the cache option. By default, placeholders are cacheable. Setting cache:false disables caching for that specific placeholder.
    • Option Parsing: Options are parsed using the pattern name:value. If a value is omitted (e.g., |option|), the value defaults to an empty string.
    <!-- Example of placeholder syntax in a configuration file -->
    {git_branch}|cache:false|prefix:feature/
  12. Use configuration placeholders in CaptainHook

    main

    CaptainHook allows you to use placeholders in your configuration to dynamically resolve values. These placeholders are processed during command execution and can refer to core configuration settings, custom settings, or plugin-specific options.

    Supported Placeholder Prefixes

    • Core Settings: Direct access to core configuration keys.
    • custom>>: Accesses values defined in your custom settings.
    • plugin>>: Accesses specific options from a plugin using the format plugin>>PluginClassName.optionKey.

    Core Configuration Keys

    You can use the following core keys as placeholders:

    • bootstrap
    • git-directory
    • php-path
    <!-- Example usage in a configuration file (conceptual) -->
    {
        "actions": {
            "pre-commit": {
                "command": "php {{php-path}} {{custom>>my-script.path}}"
            }
        },
        "custom-settings": {
            "my-script": {
                "path": "scripts/test.php"
            }
        }
    }