├── LICENSE
├── bin
└── captainhook
├── composer.json
├── phive.xml
├── phpcs.xml
└── src
├── CH.php
├── Config.php
├── Config
├── Action.php
├── Condition.php
├── Factory.php
├── Hook.php
├── Options.php
├── Plugin.php
├── Run.php
└── Util.php
├── Console
├── Application.php
├── Command.php
├── Command
│ ├── Add.php
│ ├── ConfigAware.php
│ ├── Configuration.php
│ ├── Disable.php
│ ├── Enable.php
│ ├── Hook.php
│ ├── Hook
│ │ ├── CommitMsg.php
│ │ ├── PostCheckout.php
│ │ ├── PostCommit.php
│ │ ├── PostMerge.php
│ │ ├── PostRewrite.php
│ │ ├── PreCommit.php
│ │ ├── PrePush.php
│ │ └── PrepareCommitMsg.php
│ ├── Info.php
│ ├── Install.php
│ ├── RepositoryAware.php
│ └── Uninstall.php
├── IO.php
├── IO
│ ├── Base.php
│ ├── CollectorIO.php
│ ├── ComposerIO.php
│ ├── DefaultIO.php
│ ├── Message.php
│ └── NullIO.php
├── IOUtil.php
└── Runtime
│ └── Resolver.php
├── Event.php
├── Event
├── Dispatcher.php
├── Factory.php
├── Handler.php
├── Hook.php
├── HookFailed.php
└── HookSucceeded.php
├── Exception
├── ActionFailed.php
├── CaptainHookException.php
├── InvalidHookName.php
└── InvalidPlugin.php
├── Git
├── ChangedFiles
│ ├── Detecting.php
│ ├── Detector.php
│ └── Detector
│ │ ├── Factory.php
│ │ ├── Fallback.php
│ │ ├── PostRewrite.php
│ │ └── PrePush.php
├── Diff
│ └── FilterUtil.php
├── Range.php
├── Range
│ ├── Detecting.php
│ ├── Detector
│ │ ├── Fallback.php
│ │ ├── PostRewrite.php
│ │ └── PrePush.php
│ ├── Generic.php
│ └── PrePush.php
├── Rev.php
└── Rev
│ ├── Generic.php
│ ├── PrePush.php
│ └── Util.php
├── Hook
├── Action.php
├── Branch
│ └── Action
│ │ ├── BlockFixupAndSquashCommits.php
│ │ └── EnsureNaming.php
├── Cli
│ └── Command.php
├── Composer
│ └── Action
│ │ └── CheckLockFile.php
├── Condition.php
├── Condition
│ ├── Branch
│ │ ├── Files.php
│ │ ├── Name.php
│ │ ├── NotOn.php
│ │ ├── NotOnMatching.php
│ │ ├── On.php
│ │ └── OnMatching.php
│ ├── Cli.php
│ ├── Config.php
│ ├── Config
│ │ ├── CustomValueIsFalsy.php
│ │ └── CustomValueIsTruthy.php
│ ├── ConfigDependant.php
│ ├── File.php
│ ├── FileChanged.php
│ ├── FileChanged
│ │ ├── All.php
│ │ ├── Any.php
│ │ └── OfType.php
│ ├── FileStaged.php
│ ├── FileStaged
│ │ ├── All.php
│ │ ├── Any.php
│ │ ├── InDirectory.php
│ │ ├── OfType.php
│ │ └── ThatIs.php
│ ├── Logic.php
│ ├── Logic
│ │ ├── LogicAnd.php
│ │ └── LogicOr.php
│ └── OnBranch.php
├── Constrained.php
├── Debug.php
├── Debug
│ ├── Failure.php
│ └── Success.php
├── Diff
│ └── Action
│ │ └── BlockSecrets.php
├── EventSubscriber.php
├── File
│ └── Action
│ │ ├── Check.php
│ │ ├── DoesNotContainRegex.php
│ │ ├── Emptiness.php
│ │ ├── Exists.php
│ │ ├── IsEmpty.php
│ │ ├── IsNotEmpty.php
│ │ └── MaxSize.php
├── FileList.php
├── Message
│ ├── Action
│ │ ├── Beams.php
│ │ ├── Book.php
│ │ ├── CacheOnFail.php
│ │ ├── InjectIssueKeyFromBranch.php
│ │ ├── Prepare.php
│ │ ├── PrepareFromFile.php
│ │ ├── Regex.php
│ │ └── Rules.php
│ ├── EventHandler
│ │ └── WriteCacheFile.php
│ ├── Rule.php
│ ├── Rule
│ │ ├── Base.php
│ │ ├── Blacklist.php
│ │ ├── CapitalizeSubject.php
│ │ ├── LimitBodyLineLength.php
│ │ ├── LimitSubjectLength.php
│ │ ├── MsgNotEmpty.php
│ │ ├── NoPeriodOnSubjectEnd.php
│ │ ├── SeparateSubjectFromBodyWithBlankLine.php
│ │ └── UseImperativeMood.php
│ ├── RuleBook.php
│ └── RuleBook
│ │ └── RuleSet.php
├── Notify
│ ├── Action
│ │ ├── IntegrateBeforePush.php
│ │ └── Notify.php
│ ├── Extractor.php
│ └── Notification.php
├── PHP
│ ├── Action
│ │ ├── Linting.php
│ │ └── TestCoverage.php
│ ├── CoverageResolver.php
│ └── CoverageResolver
│ │ ├── CloverXML.php
│ │ └── PHPUnit.php
├── Restriction.php
├── Template.php
├── Template
│ ├── Builder.php
│ ├── Docker.php
│ ├── Inspector.php
│ ├── Local.php
│ ├── Local
│ │ ├── PHP.php
│ │ ├── Shell.php
│ │ └── WSL.php
│ └── PathInfo.php
├── UserInput
│ ├── AskConfirmation.php
│ └── EventHandler
│ │ └── AskConfirmation.php
└── Util.php
├── Hooks.php
├── Plugin
├── CaptainHook.php
├── Hook.php
└── Hook
│ ├── Base.php
│ └── PreserveWorkingTree.php
├── Runner.php
├── Runner
├── Action.php
├── Action
│ ├── Cli.php
│ ├── Cli
│ │ └── Command
│ │ │ ├── Formatter.php
│ │ │ ├── Placeholder.php
│ │ │ └── Placeholder
│ │ │ ├── Arg.php
│ │ │ ├── BranchFiles.php
│ │ │ ├── ChangedFiles.php
│ │ │ ├── Config.php
│ │ │ ├── Env.php
│ │ │ ├── Foundation.php
│ │ │ ├── StagedFiles.php
│ │ │ └── StdIn.php
│ ├── Log.php
│ └── PHP.php
├── Bootstrap
│ └── Util.php
├── Condition.php
├── Config
│ ├── Change.php
│ ├── Change
│ │ ├── AddAction.php
│ │ ├── DisableHook.php
│ │ ├── EnableHook.php
│ │ └── Hook.php
│ ├── Creator.php
│ ├── Editor.php
│ ├── Reader.php
│ ├── Setup.php
│ └── Setup
│ │ ├── Advanced.php
│ │ ├── Express.php
│ │ └── Guided.php
├── Files.php
├── Hook.php
├── Hook
│ ├── Arg.php
│ ├── CommitMsg.php
│ ├── Log.php
│ ├── PostCheckout.php
│ ├── PostCommit.php
│ ├── PostMerge.php
│ ├── PostRewrite.php
│ ├── PreCommit.php
│ ├── PrePush.php
│ ├── PrepareCommitMsg.php
│ └── Printer.php
├── Installer.php
├── RepositoryAware.php
├── Uninstaller.php
└── Util.php
└── Storage
├── File.php
└── File
├── Json.php
└── Xml.php
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Sebastian Feldmann
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "captainhook/captainhook",
3 | "type": "library",
4 | "description": "PHP git hook manager",
5 | "keywords": ["git", "hooks", "pre-commit", "pre-push", "commit-msg", "prepare-commit-msg", "post-merge"],
6 | "homepage": "http://php.captainhook.info/",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "Sebastian Feldmann",
11 | "email": "sf@sebastian-feldmann.info"
12 | }
13 | ],
14 | "support": {
15 | "issues": "https://github.com/captainhook-git/captainhook/issues"
16 | },
17 | "funding": [
18 | {
19 | "type": "github",
20 | "url": "https://github.com/sponsors/sebastianfeldmann"
21 | }
22 | ],
23 | "autoload": {
24 | "psr-4": {
25 | "CaptainHook\\App\\": "src/"
26 | }
27 | },
28 | "autoload-dev": {
29 | "psr-4": {
30 | "CaptainHook\\App\\": "tests/unit/",
31 | "CaptainHook\\App\\Integration\\": "tests/integration/"
32 | }
33 | },
34 | "require": {
35 | "php": ">=8.0",
36 | "ext-json": "*",
37 | "ext-spl": "*",
38 | "ext-xml": "*",
39 | "captainhook/secrets": "^0.9.4",
40 | "sebastianfeldmann/camino": "^0.9.2",
41 | "sebastianfeldmann/cli": "^3.3",
42 | "sebastianfeldmann/git": "^3.14",
43 | "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
44 | "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
45 | "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
46 | },
47 | "require-dev": {
48 | "composer/composer": "~1 || ^2.0",
49 | "mikey179/vfsstream": "~1"
50 | },
51 | "bin": [
52 | "bin/captainhook"
53 | ],
54 | "extra": {
55 | "branch-alias": {
56 | "dev-main": "6.0.x-dev"
57 | },
58 | "captainhook": {
59 | "config": "captainhook.json"
60 | }
61 | },
62 | "replace" : {
63 | "sebastianfeldmann/captainhook": "*"
64 | },
65 | "config": {
66 | "sort-packages": true
67 | },
68 | "scripts": {
69 | "post-install-cmd": "tools/phive install --force-accept-unsigned",
70 | "tools": "tools/phive install --force-accept-unsigned",
71 | "compile": "tools/box compile",
72 | "test": "tools/phpunit --testsuite UnitTests",
73 | "test:integration": "tools/phpunit --testsuite IntegrationTests --no-coverage",
74 | "static": "tools/phpstan analyse",
75 | "style": "tools/phpcs --standard=psr12 src tests"
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/phive.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | src
9 | tests
10 |
11 |
--------------------------------------------------------------------------------
/src/CH.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App;
15 |
16 | /**
17 | * Class CH
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | final class CH
25 | {
26 | /**
27 | * Current CaptainHook version
28 | */
29 | public const VERSION = '5.25.4';
30 |
31 | /**
32 | * Release date of the current version
33 | */
34 | public const RELEASE_DATE = '2025-06-01';
35 |
36 | /**
37 | * Default configuration file
38 | */
39 | public const CONFIG = 'captainhook.json';
40 |
41 | /**
42 | * Minimal required version for the installer
43 | */
44 | public const MIN_REQ_INSTALLER = '5.22.0';
45 | }
46 |
--------------------------------------------------------------------------------
/src/Config/Condition.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Config;
13 |
14 | /**
15 | * Class Action
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 4.2.0
21 | * @internal
22 | */
23 | class Condition
24 | {
25 | /**
26 | * Condition executable
27 | *
28 | * @var string
29 | */
30 | private $exec;
31 |
32 | /**
33 | * Condition arguments
34 | *
35 | * @var array
36 | */
37 | private $args;
38 |
39 | /**
40 | * Condition constructor
41 | *
42 | * @param string $exec
43 | * @param array $args
44 | */
45 | public function __construct(string $exec, array $args = [])
46 | {
47 | $this->exec = $exec;
48 | $this->args = $args;
49 | }
50 |
51 | /**
52 | * Exec getter
53 | *
54 | * @return string
55 | */
56 | public function getExec(): string
57 | {
58 | return $this->exec;
59 | }
60 |
61 | /**
62 | * Args getter
63 | *
64 | * @return array
65 | */
66 | public function getArgs(): array
67 | {
68 | return $this->args;
69 | }
70 |
71 | /**
72 | * Return config data
73 | *
74 | * @return array
75 | */
76 | public function getJsonData(): array
77 | {
78 | return [
79 | 'exec' => $this->exec,
80 | 'args' => $this->args,
81 | ];
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/Config/Options.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Config;
13 |
14 | /**
15 | * Class Options
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 1.0.0
21 | */
22 | class Options
23 | {
24 | /**
25 | * Map of options
26 | *
27 | * @var array
28 | */
29 | private $options;
30 |
31 | /**
32 | * Options constructor
33 | *
34 | * @param array $options
35 | */
36 | public function __construct(array $options)
37 | {
38 | $this->options = $options;
39 | }
40 |
41 | /**
42 | * Return a option value
43 | *
44 | * @template ProvidedDefault
45 | * @param string $name
46 | * @param ProvidedDefault $default
47 | * @return ProvidedDefault|mixed
48 | */
49 | public function get(string $name, $default = null)
50 | {
51 | return $this->options[$name] ?? $default;
52 | }
53 |
54 | /**
55 | * Return all options
56 | *
57 | * @return array
58 | */
59 | public function getAll(): array
60 | {
61 | return $this->options;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Config/Plugin.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Config;
13 |
14 | use CaptainHook\App\Exception\InvalidPlugin;
15 | use CaptainHook\App\Plugin\CaptainHook;
16 |
17 | /**
18 | * Class Plugin
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 5.9.0
24 | */
25 | class Plugin
26 | {
27 | /**
28 | * Plugin class
29 | *
30 | * @var string
31 | */
32 | private $plugin;
33 |
34 | /**
35 | * Map of options name => value
36 | *
37 | * @var Options
38 | */
39 | private $options;
40 |
41 | /**
42 | * Plugin constructor
43 | *
44 | * @param string $plugin
45 | * @param array $options
46 | */
47 | public function __construct(string $plugin, array $options = [])
48 | {
49 | if (!is_a($plugin, CaptainHook::class, true)) {
50 | throw new InvalidPlugin("{$plugin} is not a valid CaptainHook plugin.");
51 | }
52 |
53 | $this->plugin = $plugin;
54 | $this->setupOptions($options);
55 | }
56 |
57 | /**
58 | * Setup options
59 | *
60 | * @param array $options
61 | */
62 | private function setupOptions(array $options): void
63 | {
64 | $this->options = new Options($options);
65 | }
66 |
67 | /**
68 | * Plugin class name getter
69 | *
70 | * @return string
71 | */
72 | public function getPlugin(): string
73 | {
74 | return $this->plugin;
75 | }
76 |
77 | /**
78 | * Return option map
79 | *
80 | * @return Options
81 | */
82 | public function getOptions(): Options
83 | {
84 | return $this->options;
85 | }
86 |
87 | /**
88 | * Return config data
89 | *
90 | * @return array
91 | */
92 | public function getJsonData(): array
93 | {
94 | return [
95 | 'plugin' => $this->plugin,
96 | 'options' => $this->options->getAll(),
97 | ];
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/Console/Command.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console;
13 |
14 | use CaptainHook\App\Console\Runtime\Resolver;
15 | use Symfony\Component\Console\Command\Command as SymfonyCommand;
16 | use Symfony\Component\Console\Input\InputInterface;
17 | use Symfony\Component\Console\Output\OutputInterface;
18 |
19 | /**
20 | * Class Command
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.0.0
26 | */
27 | abstract class Command extends SymfonyCommand
28 | {
29 | /**
30 | * Input output handler
31 | *
32 | * @var \CaptainHook\App\Console\IO
33 | */
34 | private $io;
35 |
36 | /**
37 | * Runtime resolver
38 | *
39 | * @var \CaptainHook\App\Console\Runtime\Resolver
40 | */
41 | protected Resolver $resolver;
42 |
43 | /**
44 | * Command constructor
45 | *
46 | * @param \CaptainHook\App\Console\Runtime\Resolver $resolver
47 | */
48 | public function __construct(Resolver $resolver)
49 | {
50 | $this->resolver = $resolver;
51 | parent::__construct();
52 | }
53 |
54 | /**
55 | * IO setter
56 | *
57 | * @param \CaptainHook\App\Console\IO $io
58 | */
59 | public function setIO(IO $io): void
60 | {
61 | $this->io = $io;
62 | }
63 |
64 | /**
65 | * IO interface getter
66 | *
67 | * @param \Symfony\Component\Console\Input\InputInterface $input
68 | * @param \Symfony\Component\Console\Output\OutputInterface $output
69 | * @return \CaptainHook\App\Console\IO
70 | */
71 | public function getIO(InputInterface $input, OutputInterface $output): IO
72 | {
73 | if (null === $this->io) {
74 | $this->io = new IO\DefaultIO($input, $output, $this->getHelperSet());
75 | }
76 | return $this->io;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/Console/Command/Add.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command;
13 |
14 | use CaptainHook\App\Console\IOUtil;
15 | use CaptainHook\App\Runner\Config\Editor;
16 | use Symfony\Component\Console\Input\InputArgument;
17 | use Symfony\Component\Console\Input\InputInterface;
18 | use Symfony\Component\Console\Output\OutputInterface;
19 |
20 | /**
21 | * Class Add
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 4.2.0
27 | */
28 | class Add extends ConfigAware
29 | {
30 | /**
31 | * Configure the command
32 | *
33 | * @return void
34 | */
35 | protected function configure(): void
36 | {
37 | parent::configure();
38 | $this->setName('config:add')
39 | ->setAliases(['add'])
40 | ->setDescription('Add an action to your hook configuration')
41 | ->setHelp('Add an action to your hook configuration')
42 | ->addArgument('hook', InputArgument::REQUIRED, 'Hook you want to add the action to');
43 | }
44 |
45 | /**
46 | * Execute the command
47 | *
48 | * @param \Symfony\Component\Console\Input\InputInterface $input
49 | * @param \Symfony\Component\Console\Output\OutputInterface $output
50 | * @return int
51 | * @throws \CaptainHook\App\Exception\InvalidHookName
52 | * @throws \Exception
53 | */
54 | protected function execute(InputInterface $input, OutputInterface $output): int
55 | {
56 | $io = $this->getIO($input, $output);
57 | $config = $this->createConfig($input, true);
58 |
59 | $editor = new Editor($io, $config);
60 | $editor->setHook(IOUtil::argToString($input->getArgument('hook')))
61 | ->setChange('AddAction')
62 | ->run();
63 |
64 | return 0;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Console/Command/Disable.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command;
13 |
14 | use CaptainHook\App\Console\IOUtil;
15 | use CaptainHook\App\Runner\Config\Editor;
16 | use Symfony\Component\Console\Input\InputArgument;
17 | use Symfony\Component\Console\Input\InputInterface;
18 | use Symfony\Component\Console\Output\OutputInterface;
19 |
20 | /**
21 | * Class Add
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 4.2.0
27 | */
28 | class Disable extends ConfigAware
29 | {
30 | /**
31 | * Configure the command
32 | *
33 | * @return void
34 | */
35 | protected function configure(): void
36 | {
37 | parent::configure();
38 | $this->setName('config:disable')
39 | ->setAliases(['disable'])
40 | ->setDescription('Disable the handling for a hook in your configuration')
41 | ->setHelp('Disable the handling for a hook in your configuration')
42 | ->addArgument('hook', InputArgument::REQUIRED, 'Hook you want to disable');
43 | }
44 |
45 | /**
46 | * Execute the command
47 | *
48 | * @param \Symfony\Component\Console\Input\InputInterface $input
49 | * @param \Symfony\Component\Console\Output\OutputInterface $output
50 | * @return int
51 | * @throws \CaptainHook\App\Exception\InvalidHookName
52 | * @throws \Exception
53 | */
54 | protected function execute(InputInterface $input, OutputInterface $output): int
55 | {
56 | $io = $this->getIO($input, $output);
57 | $config = $this->createConfig($input, true);
58 |
59 | $editor = new Editor($io, $config);
60 | $editor->setHook(IOUtil::argToString($input->getArgument('hook')))
61 | ->setChange('DisableHook')
62 | ->run();
63 |
64 | return 0;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Console/Command/Enable.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command;
13 |
14 | use CaptainHook\App\Console\IOUtil;
15 | use CaptainHook\App\Runner\Config\Editor;
16 | use Symfony\Component\Console\Input\InputArgument;
17 | use Symfony\Component\Console\Input\InputInterface;
18 | use Symfony\Component\Console\Output\OutputInterface;
19 |
20 | /**
21 | * Class Add
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 4.2.0
27 | */
28 | class Enable extends ConfigAware
29 | {
30 | /**
31 | * Configure the command
32 | *
33 | * @return void
34 | */
35 | protected function configure(): void
36 | {
37 | parent::configure();
38 | $this->setName('config:enable')
39 | ->setAliases(['enable'])
40 | ->setDescription('Enable the handling for a hook in your configuration')
41 | ->setHelp('Enable the handling for a hook in your configuration')
42 | ->addArgument('hook', InputArgument::REQUIRED, 'Hook you want to enable');
43 | }
44 |
45 | /**
46 | * Execute the command
47 | *
48 | * @param \Symfony\Component\Console\Input\InputInterface $input
49 | * @param \Symfony\Component\Console\Output\OutputInterface $output
50 | * @return int
51 | * @throws \CaptainHook\App\Exception\InvalidHookName
52 | * @throws \Exception
53 | */
54 | protected function execute(InputInterface $input, OutputInterface $output): int
55 | {
56 | $io = $this->getIO($input, $output);
57 | $config = $this->createConfig($input, true);
58 |
59 | $editor = new Editor($io, $config);
60 | $editor->setHook(IOUtil::argToString($input->getArgument('hook')))
61 | ->setChange('EnableHook')
62 | ->run();
63 |
64 | return 0;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/CommitMsg.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 | use Symfony\Component\Console\Input\InputArgument;
17 |
18 | /**
19 | * Class CommitMessage
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 0.9.0
25 | */
26 | class CommitMsg extends Hook
27 | {
28 | /**
29 | * Hook to execute
30 | *
31 | * @var string
32 | */
33 | protected string $hookName = Hooks::COMMIT_MSG;
34 |
35 | /**
36 | * Configure the command
37 | *
38 | * @return void
39 | */
40 | protected function configure(): void
41 | {
42 | parent::configure();
43 | $this->addArgument(Hooks::ARG_MESSAGE_FILE, InputArgument::REQUIRED, 'File containing the commit message.');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/PostCheckout.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 | use Symfony\Component\Console\Input\InputArgument;
17 |
18 | /**
19 | * Class PostCheckout
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 4.1.0
25 | */
26 | class PostCheckout extends Hook
27 | {
28 | /**
29 | * Hook to execute.
30 | *
31 | * @var string
32 | */
33 | protected string $hookName = Hooks::POST_CHECKOUT;
34 |
35 | /**
36 | * Configure the command
37 | *
38 | * @return void
39 | */
40 | protected function configure(): void
41 | {
42 | parent::configure();
43 | $this->addArgument(Hooks::ARG_PREVIOUS_HEAD, InputArgument::OPTIONAL, 'Previous HEAD');
44 | $this->addArgument(Hooks::ARG_NEW_HEAD, InputArgument::OPTIONAL, 'New HEAD');
45 | $this->addArgument(Hooks::ARG_MODE, InputArgument::OPTIONAL, 'Checkout mode 1 branch 0 file');
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/PostCommit.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 |
17 | /**
18 | * Class PostCommit
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 0.9.0
24 | */
25 | class PostCommit extends Hook
26 | {
27 | /**
28 | * Hook to execute.
29 | *
30 | * @var string
31 | */
32 | protected string $hookName = Hooks::POST_COMMIT;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/PostMerge.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 | use Symfony\Component\Console\Input\InputArgument;
17 |
18 | /**
19 | * Class PostMerge
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 4.0.1
25 | */
26 | class PostMerge extends Hook
27 | {
28 | /**
29 | * Hook to execute.
30 | *
31 | * @var string
32 | */
33 | protected string $hookName = Hooks::POST_MERGE;
34 |
35 | /**
36 | * Configure the command
37 | *
38 | * @return void
39 | */
40 | protected function configure(): void
41 | {
42 | parent::configure();
43 | $this->addArgument(Hooks::ARG_SQUASH, InputArgument::OPTIONAL, 'Merge was done with a squash merge.');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/PostRewrite.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 | use Symfony\Component\Console\Input\InputArgument;
17 |
18 | /**
19 | * Class PostRewrite
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 5.4.0
25 | */
26 | class PostRewrite extends Hook
27 | {
28 | /**
29 | * Hook to execute.
30 | *
31 | * @var string
32 | */
33 | protected string $hookName = Hooks::POST_REWRITE;
34 |
35 | /**
36 | * Configure the command
37 | *
38 | * @return void
39 | */
40 | protected function configure(): void
41 | {
42 | parent::configure();
43 | $this->addArgument(Hooks::ARG_GIT_COMMAND, InputArgument::OPTIONAL, 'Executed command');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/PreCommit.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 |
17 | /**
18 | * Class PreCommit
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 0.9.0
24 | */
25 | class PreCommit extends Hook
26 | {
27 | /**
28 | * Hook to execute.
29 | *
30 | * @var string
31 | */
32 | protected string $hookName = Hooks::PRE_COMMIT;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/PrePush.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 | use Symfony\Component\Console\Input\InputArgument;
17 |
18 | /**
19 | * Class PrePush
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 0.9.0
25 | */
26 | class PrePush extends Hook
27 | {
28 | /**
29 | * Hook to execute.
30 | *
31 | * @var string
32 | */
33 | protected string $hookName = Hooks::PRE_PUSH;
34 |
35 | /**
36 | * Configure the command
37 | *
38 | * @return void
39 | */
40 | protected function configure(): void
41 | {
42 | parent::configure();
43 | $this->addArgument(Hooks::ARG_TARGET, InputArgument::OPTIONAL, 'Target repository name');
44 | $this->addArgument(Hooks::ARG_URL, InputArgument::OPTIONAL, 'Target repository url');
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Console/Command/Hook/PrepareCommitMsg.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command\Hook;
13 |
14 | use CaptainHook\App\Console\Command\Hook;
15 | use CaptainHook\App\Hooks;
16 | use Symfony\Component\Console\Input\InputArgument;
17 |
18 | /**
19 | * Class PrepareCommitMessage
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 3.1.0
25 | */
26 | class PrepareCommitMsg extends Hook
27 | {
28 | /**
29 | * Hook to execute
30 | *
31 | * @var string
32 | */
33 | protected string $hookName = Hooks::PREPARE_COMMIT_MSG;
34 |
35 | /**
36 | * Configure the command
37 | *
38 | * @return void
39 | */
40 | protected function configure(): void
41 | {
42 | parent::configure();
43 | $this->addArgument(Hooks::ARG_MESSAGE_FILE, InputArgument::REQUIRED, 'File containing the commit log message');
44 | $this->addArgument(Hooks::ARG_MODE, InputArgument::OPTIONAL, 'Current commit mode');
45 | $this->addArgument(Hooks::ARG_HASH, InputArgument::OPTIONAL, 'Given commit hash');
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Console/Command/RepositoryAware.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Command;
13 |
14 | use CaptainHook\App\Console\Runtime\Resolver;
15 | use SebastianFeldmann\Git\Repository;
16 | use Symfony\Component\Console\Input\InputOption;
17 |
18 | /**
19 | * Trait RepositoryAware
20 | *
21 | * Trait for all commands that needs to be aware of the git repository.
22 | *
23 | * @package CaptainHook\App\Console\Command
24 | */
25 | class RepositoryAware extends ConfigAware
26 | {
27 | /**
28 | * Configure method to set up the git-directory command option
29 | *
30 | * @return void
31 | */
32 | protected function configure(): void
33 | {
34 | parent::configure();
35 |
36 | $this->addOption(
37 | 'git-directory',
38 | 'g',
39 | InputOption::VALUE_OPTIONAL,
40 | 'Path to your .git directory'
41 | );
42 | }
43 |
44 | /**
45 | * Create a new git repository representation
46 | *
47 | * @param string $path
48 | * @return \SebastianFeldmann\Git\Repository
49 | */
50 | protected function createRepository(string $path): Repository
51 | {
52 | return Repository::createVerified($path);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Console/IO/Base.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\IO;
13 |
14 | use CaptainHook\App\Console\IO;
15 |
16 | /**
17 | * Class Base
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | abstract class Base implements IO
25 | {
26 | /**
27 | * Return the original cli arguments
28 | *
29 | * @return array
30 | */
31 | public function getArguments(): array
32 | {
33 | return [];
34 | }
35 |
36 | /**
37 | * Return the original cli argument or a given default
38 | *
39 | * @param string $name
40 | * @param string $default
41 | * @return string
42 | */
43 | public function getArgument(string $name, string $default = ''): string
44 | {
45 | return $default;
46 | }
47 |
48 | /**
49 | * Return the piped in standard input
50 | *
51 | * @return string[]
52 | */
53 | public function getStandardInput(): array
54 | {
55 | return [];
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Console/IO/Message.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\IO;
13 |
14 | /**
15 | * Class Message
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.19.0
21 | */
22 | class Message
23 | {
24 | /**
25 | * Message, either a string or list of string for multiple lines
26 | *
27 | * @var string|array
28 | */
29 | private string|array $message;
30 |
31 | /**
32 | * Should message be ended with a new line character
33 | *
34 | * @var bool
35 | */
36 | private bool $newLine;
37 |
38 | /**
39 | * Current application verbosity
40 | *
41 | * @var int
42 | */
43 | private int $verbosity;
44 |
45 | /**
46 | * Constructor
47 | *
48 | * @param string|array $message
49 | * @param bool $newLine
50 | * @param int $verbosity
51 | */
52 | public function __construct(string|array $message, bool $newLine, int $verbosity)
53 | {
54 | $this->message = $message;
55 | $this->newLine = $newLine;
56 | $this->verbosity = $verbosity;
57 | }
58 |
59 | /**
60 | * Returns the message to print
61 | *
62 | * @return string|array
63 | */
64 | public function message(): string|array
65 | {
66 | return $this->message;
67 | }
68 |
69 | /**
70 | * If true message should end with a new line
71 | *
72 | * @return bool
73 | */
74 | public function newLine(): bool
75 | {
76 | return $this->newLine;
77 | }
78 |
79 | /**
80 | * Minimum verbosity this message should be displayed at
81 | *
82 | * @return int
83 | */
84 | public function verbosity(): int
85 | {
86 | return $this->verbosity;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/Console/IO/NullIO.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\IO;
13 |
14 | /**
15 | * Class NullIO
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 0.9.0
21 | */
22 | class NullIO extends Base
23 | {
24 | /**
25 | * {@inheritDoc}
26 | */
27 | public function isInteractive()
28 | {
29 | return false;
30 | }
31 |
32 | /**
33 | * {@inheritDoc}
34 | */
35 | public function isVerbose()
36 | {
37 | return false;
38 | }
39 |
40 | /**
41 | * {@inheritDoc}
42 | */
43 | public function isVeryVerbose()
44 | {
45 | return false;
46 | }
47 |
48 | /**
49 | * {@inheritDoc}
50 | */
51 | public function isDebug()
52 | {
53 | return false;
54 | }
55 |
56 | /**
57 | * {@inheritDoc}
58 | */
59 | public function write($messages, $newline = true, $verbosity = self::NORMAL)
60 | {
61 | }
62 |
63 | /**
64 | * {@inheritDoc}
65 | */
66 | public function writeError($messages, $newline = true, $verbosity = self::NORMAL)
67 | {
68 | }
69 |
70 | /**
71 | * {@inheritDoc}
72 | */
73 | public function ask($question, $default = null)
74 | {
75 | return (string) $default;
76 | }
77 |
78 | /**
79 | * {@inheritDoc}
80 | */
81 | public function askConfirmation($question, $default = true)
82 | {
83 | return $default;
84 | }
85 |
86 | /**
87 | * {@inheritDoc}
88 | */
89 | public function askAndValidate($question, $validator, $attempts = null, $default = null)
90 | {
91 | return $default;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Console/Runtime/Resolver.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Console\Runtime;
13 |
14 | /**
15 | * Class Resolver
16 | *
17 | * @package CaptainHook\App
18 | */
19 | class Resolver
20 | {
21 | /**
22 | * PHAR flag, replaced by box during PHAR building
23 | *
24 | * @var string
25 | */
26 | private string $runtime = '@runtime@';
27 |
28 | /**
29 | * Path to the currently executed 'binary'
30 | *
31 | * @var string
32 | */
33 | private string $executable;
34 |
35 | /**
36 | * Resolver constructor.
37 | *
38 | * @param string $executable
39 | */
40 | public function __construct(string $executable = 'bin/vendor/captainhook')
41 | {
42 | $this->executable = $executable;
43 | }
44 |
45 | /**
46 | * Return current executed 'binary'
47 | *
48 | * @return string
49 | */
50 | public function getExecutable(): string
51 | {
52 | return $this->executable;
53 | }
54 |
55 | /**
56 | * Check if the current runtime is executed via PHAR
57 | *
58 | * @return bool
59 | */
60 | public function isPharRelease(): bool
61 | {
62 | return $this->runtime === 'PHAR';
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Event.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use SebastianFeldmann\Git\Repository;
16 |
17 | /**
18 | * Event interface
19 | *
20 | * Allows event handlers to do output access the app setup or the repository.
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.11.0
26 | */
27 | interface Event
28 | {
29 | /**
30 | * Returns the event trigger name
31 | *
32 | * @return string
33 | */
34 | public function name(): string;
35 |
36 | /**
37 | * Returns the captainhook config, most likely needed to access any original command line arguments
38 | *
39 | * @return \CaptainHook\App\Config
40 | */
41 | public function config(): Config;
42 |
43 | /**
44 | * Returns IO to do some output
45 | *
46 | * @return \CaptainHook\App\Console\IO
47 | */
48 | public function io(): IO;
49 |
50 | /**
51 | * Returns the git repository
52 | *
53 | * @return \SebastianFeldmann\Git\Repository
54 | */
55 | public function repository(): Repository;
56 | }
57 |
--------------------------------------------------------------------------------
/src/Event/Handler.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Event;
13 |
14 | use CaptainHook\App\Event;
15 |
16 | /**
17 | * Interface EventListener
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.11.0
23 | */
24 | interface Handler
25 | {
26 | /**
27 | * Executes the handler to handle the given event
28 | *
29 | * @param \CaptainHook\App\Event $event
30 | * @return void
31 | * @throws \Exception
32 | */
33 | public function handle(Event $event);
34 | }
35 |
--------------------------------------------------------------------------------
/src/Event/Hook.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Event;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Event;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Basic event class
21 | *
22 | * Makes sure the handler has access to the output the current app setup and the repository.
23 | *
24 | * @package CaptainHook
25 | * @author Sebastian Feldmann
26 | * @link https://github.com/captainhook-git/captainhook
27 | * @since Class available since Release 5.11.0
28 | */
29 | abstract class Hook implements Event
30 | {
31 | /**
32 | * @var string
33 | */
34 | protected $name;
35 |
36 | /**
37 | * @var \CaptainHook\App\Console\IO
38 | */
39 | protected $io;
40 |
41 | /**
42 | * @var \CaptainHook\App\Config
43 | */
44 | protected $config;
45 |
46 | /**
47 | * @var \SebastianFeldmann\Git\Repository
48 | */
49 | protected $repository;
50 |
51 | /**
52 | * Event
53 | *
54 | * @param \CaptainHook\App\Console\IO $io
55 | * @param \CaptainHook\App\Config $config
56 | * @param \SebastianFeldmann\Git\Repository $repository
57 | */
58 | public function __construct(IO $io, Config $config, Repository $repository)
59 | {
60 | $this->io = $io;
61 | $this->config = $config;
62 | $this->repository = $repository;
63 | }
64 |
65 | /**
66 | * @return string
67 | */
68 | public function name(): string
69 | {
70 | return $this->name;
71 | }
72 |
73 | /**
74 | * @return \CaptainHook\App\Config
75 | */
76 | public function config(): Config
77 | {
78 | return $this->config;
79 | }
80 |
81 | /**
82 | * @return \CaptainHook\App\Console\IO
83 | */
84 | public function io(): IO
85 | {
86 | return $this->io;
87 | }
88 |
89 | /**
90 | * @return \SebastianFeldmann\Git\Repository
91 | */
92 | public function repository(): Repository
93 | {
94 | return $this->repository;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/Event/HookFailed.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Event;
13 |
14 | /**
15 | * Hook failed event
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.11.0
21 | */
22 | class HookFailed extends Hook
23 | {
24 | protected $name = 'onHookFailure';
25 | }
26 |
--------------------------------------------------------------------------------
/src/Event/HookSucceeded.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Event;
13 |
14 | /**
15 | * Hook succeeded event
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.11.0
21 | */
22 | class HookSucceeded extends Hook
23 | {
24 | protected $name = 'onHookSuccess';
25 | }
26 |
--------------------------------------------------------------------------------
/src/Exception/ActionFailed.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Exception;
13 |
14 | use Exception;
15 |
16 | /**
17 | * Class ActionFailed
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class ActionFailed extends Exception implements CaptainHookException
25 | {
26 | }
27 |
--------------------------------------------------------------------------------
/src/Exception/CaptainHookException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Exception;
13 |
14 | use Throwable;
15 |
16 | /**
17 | * CaptainHookException interface
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.9.0.
23 | */
24 | interface CaptainHookException extends Throwable
25 | {
26 | }
27 |
--------------------------------------------------------------------------------
/src/Exception/InvalidHookName.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Exception;
13 |
14 | use Exception;
15 |
16 | /**
17 | * Class InvalidHookName
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class InvalidHookName extends Exception implements CaptainHookException
25 | {
26 | }
27 |
--------------------------------------------------------------------------------
/src/Exception/InvalidPlugin.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Exception;
13 |
14 | use RuntimeException;
15 |
16 | /**
17 | * Class InvalidPlugin
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.9.0
23 | */
24 | class InvalidPlugin extends RuntimeException implements CaptainHookException
25 | {
26 | }
27 |
--------------------------------------------------------------------------------
/src/Git/ChangedFiles/Detecting.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\ChangedFiles;
13 |
14 | /**
15 | * Detector interface
16 | *
17 | * Interface to detect changed files for the different hooks.
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.20.0
23 | */
24 | interface Detecting
25 | {
26 | /**
27 | * Returns a list of changed files
28 | *
29 | * @param array $filter
30 | * @return array
31 | */
32 | public function getChangedFiles(array $filter = []): array;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Git/ChangedFiles/Detector.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\ChangedFiles;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use SebastianFeldmann\Git\Repository;
16 |
17 | /**
18 | * Class Detector
19 | *
20 | * Base class for all ChangedFiles Detecting implementations.
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.20.0
26 | */
27 | abstract class Detector implements Detecting
28 | {
29 | /**
30 | * Input output handling
31 | *
32 | * @var \CaptainHook\App\Console\IO
33 | */
34 | protected IO $io;
35 |
36 | /**
37 | * Git repository
38 | *
39 | * @var \SebastianFeldmann\Git\Repository
40 | */
41 | protected Repository $repository;
42 |
43 | /**
44 | * Constructor
45 | *
46 | * @param \CaptainHook\App\Console\IO $io
47 | * @param \SebastianFeldmann\Git\Repository $repository
48 | */
49 | public function __construct(IO $io, Repository $repository)
50 | {
51 | $this->io = $io;
52 | $this->repository = $repository;
53 | }
54 |
55 | /**
56 | * Returns a list of changed files
57 | *
58 | * @param array $filter
59 | * @return array
60 | */
61 | abstract public function getChangedFiles(array $filter = []): array;
62 | }
63 |
--------------------------------------------------------------------------------
/src/Git/ChangedFiles/Detector/Factory.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\ChangedFiles\Detector;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Git\ChangedFiles\Detecting;
16 | use CaptainHook\App\Hooks;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Factory class
21 | *
22 | * Responsible for finding the previous - current ranges in every scenario
23 | *
24 | * @package CaptainHook
25 | * @author Sebastian Feldmann
26 | * @link https://github.com/captainhook-git/captainhook
27 | * @since Class available since Release 5.15.0
28 | */
29 | class Factory
30 | {
31 | /**
32 | * List of available range detectors
33 | *
34 | * @var array
35 | */
36 | private static array $detectors = [
37 | 'hook:pre-push' => '\\CaptainHook\\App\\Git\\ChangedFiles\\Detector\\PrePush',
38 | 'hook:post-rewrite' => '\\CaptainHook\\App\\Git\\ChangedFiles\\Detector\\PostRewrite',
39 | ];
40 |
41 | /**
42 | * Returns a ChangedFiles Detector
43 | *
44 | * @param \CaptainHook\App\Console\IO $io
45 | * @param \SebastianFeldmann\Git\Repository $repository
46 | * @return \CaptainHook\App\Git\ChangedFiles\Detecting
47 | */
48 | public function getDetector(IO $io, Repository $repository): Detecting
49 | {
50 | $command = $io->getArgument(Hooks::ARG_COMMAND);
51 |
52 | /** @var \CaptainHook\App\Git\ChangedFiles\Detecting $class */
53 | $class = self::$detectors[$command] ?? '\\CaptainHook\\App\\Git\\ChangedFiles\\Detector\\Fallback';
54 | return new $class($io, $repository);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Git/ChangedFiles/Detector/Fallback.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\ChangedFiles\Detector;
13 |
14 | use CaptainHook\App\Git\ChangedFiles\Detector;
15 | use CaptainHook\App\Hooks;
16 |
17 | /**
18 | * Class Fallback
19 | *
20 | * This class should not be used it is just a fallback if the `pre-push` or `post-rewrite`
21 | * variants are somehow not applicable.
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.20.0
27 | */
28 | class Fallback extends Detector
29 | {
30 | /**
31 | * Returns the list of changed files in a best-guess kind of way
32 | *
33 | * @param array $filter
34 | * @return array
35 | */
36 | public function getChangedFiles(array $filter = []): array
37 | {
38 | return $this->repository->getDiffOperator()->getChangedFiles(
39 | $this->io->getArgument(Hooks::ARG_PREVIOUS_HEAD, 'HEAD@{1}'),
40 | 'HEAD',
41 | $filter
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Git/ChangedFiles/Detector/PostRewrite.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\ChangedFiles\Detector;
13 |
14 | use CaptainHook\App\Git\ChangedFiles\Detector;
15 | use CaptainHook\App\Git\Range\Detector\PostRewrite as RangeDetector;
16 |
17 | /**
18 | * Class PostRewrite
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 5.20.0
24 | */
25 | class PostRewrite extends Detector
26 | {
27 | /**
28 | * Returns a list of changed files
29 | *
30 | * @param array $filter
31 | * @return array
32 | */
33 | public function getChangedFiles(array $filter = []): array
34 | {
35 | $detector = new RangeDetector();
36 | $ranges = $detector->getRanges($this->io);
37 | $old = $ranges[0]->from()->id();
38 | $new = $ranges[0]->to()->id();
39 |
40 | return $this->repository->getDiffOperator()->getChangedFiles($old, $new, $filter);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Git/Diff/FilterUtil.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Diff;
13 |
14 | abstract class FilterUtil
15 | {
16 | /**
17 | * Converts a value into a valid diff filter array
18 | *
19 | * @param mixed $value
20 | * @return array
21 | */
22 | public static function filterFromConfigValue($value): array
23 | {
24 | return self::sanitize(
25 | is_array($value) ? $value : str_split((string) strtoupper($value === null ? '' : $value))
26 | );
27 | }
28 |
29 | /**
30 | * Remove all invalid filter options
31 | *
32 | * @param array $data
33 | * @return array
34 | */
35 | public static function sanitize(array $data): array
36 | {
37 | return array_filter($data, fn($e) => in_array($e, ['A', 'C', 'D', 'M', 'R', 'T', 'U', 'X', 'B', '*']));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Git/Range.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git;
13 |
14 | /**
15 | * Range class
16 | *
17 | * Represents a git range with a starting ref and an end ref.
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.15.0
23 | */
24 | interface Range
25 | {
26 | /**
27 | * Returns the start ref
28 | *
29 | * @return \CaptainHook\App\Git\Rev
30 | */
31 | public function from(): Rev;
32 |
33 | /**
34 | * Returns the end ref
35 | *
36 | * @return \CaptainHook\App\Git\Rev
37 | */
38 | public function to(): Rev;
39 | }
40 |
--------------------------------------------------------------------------------
/src/Git/Range/Detecting.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Range;
13 |
14 | use CaptainHook\App\Console\IO;
15 |
16 | /**
17 | * Detecting interface
18 | *
19 | * Interface to gathering the previous state to current state ranges.
20 | * To handle gathering the ranges for pre-push, post-rewrite, post-checkout separately.
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.15.0
26 | */
27 | interface Detecting
28 | {
29 | /**
30 | * Returns a list of ranges marking before and after points to collect the changes happening in between
31 | *
32 | * @param \CaptainHook\App\Console\IO $io
33 | * @return array<\CaptainHook\App\Git\Range>
34 | */
35 | public function getRanges(IO $io): array;
36 | }
37 |
--------------------------------------------------------------------------------
/src/Git/Range/Detector/Fallback.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Range\Detector;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Git\Range;
16 | use CaptainHook\App\Git\Range\Detecting;
17 | use CaptainHook\App\Git\Rev;
18 | use CaptainHook\App\Hooks;
19 |
20 | /**
21 | * Fallback Detector
22 | *
23 | * If no detection strategy matches the fallback detector is used to find the right range.
24 | *
25 | * @package CaptainHook
26 | * @author Sebastian Feldmann
27 | * @link https://github.com/captainhook-git/captainhook
28 | * @since Class available since Release 5.15.0
29 | */
30 | class Fallback implements Detecting
31 | {
32 | /**
33 | * Returns the fallback range
34 | *
35 | * @param \CaptainHook\App\Console\IO $io
36 | * @return \CaptainHook\App\Git\Range\Generic[]
37 | */
38 | public function getRanges(IO $io): array
39 | {
40 | return [
41 | new Range\Generic(
42 | new Rev\Generic($io->getArgument(Hooks::ARG_PREVIOUS_HEAD, 'HEAD@{1}')),
43 | new Rev\Generic('HEAD')
44 | )
45 | ];
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Git/Range/Detector/PostRewrite.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Range\Detector;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Git\Range\Detecting;
16 | use CaptainHook\App\Git\Range\Generic as Range;
17 | use CaptainHook\App\Git\Rev\Generic as Rev;
18 |
19 | /**
20 | * Class to access the pre-push stdIn data
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.15.0
26 | */
27 | class PostRewrite implements Detecting
28 | {
29 | /**
30 | * Returns list of refs
31 | *
32 | * @param \CaptainHook\App\Console\IO $io
33 | * @return \CaptainHook\App\Git\Range[]
34 | */
35 | public function getRanges(IO $io): array
36 | {
37 | return $this->createFromStdIn($io->getStandardInput());
38 | }
39 |
40 | /**
41 | * Create ranges from stdIn
42 | *
43 | * @param array $stdIn
44 | * @return array<\CaptainHook\App\Git\Range>
45 | */
46 | private function createFromStdIn(array $stdIn): array
47 | {
48 | $ranges = [];
49 | foreach ($stdIn as $line) {
50 | if (!empty($line)) {
51 | $parts = explode(' ', trim($line));
52 | $from = new Rev(!empty($parts[1]) ? $parts[1] . '^' : 'HEAD@{1}');
53 | $to = new Rev('HEAD');
54 | $ranges[] = new Range($from, $to);
55 | }
56 | }
57 | return $ranges;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Git/Range/Detector/PrePush.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Range\Detector;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Git\Range\Detecting;
16 | use CaptainHook\App\Git\Range\PrePush as Range;
17 | use CaptainHook\App\Git\Rev\PrePush as Rev;
18 | use CaptainHook\App\Git\Rev\Util;
19 |
20 | /**
21 | * Class to access the pre-push stdIn data
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.15.0
27 | */
28 | class PrePush implements Detecting
29 | {
30 | /**
31 | * Returns list of refs
32 | *
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @return array<\CaptainHook\App\Git\Range\PrePush>
35 | */
36 | public function getRanges(IO $io): array
37 | {
38 | return $this->createFromStdIn($io->getStandardInput());
39 | }
40 |
41 | /**
42 | * Factory method
43 | *
44 | * @param array $stdIn
45 | * @return array<\CaptainHook\App\Git\Range\PrePush>
46 | */
47 | private function createFromStdIn(array $stdIn): array
48 | {
49 | $ranges = [];
50 | foreach ($stdIn as $line) {
51 | if (empty($line)) {
52 | continue;
53 | }
54 |
55 | [$localRef, $localHash, $remoteRef, $remoteHash] = explode(' ', trim($line));
56 |
57 | $from = new Rev($remoteRef, $remoteHash, Util::extractBranchInfo($remoteRef)['branch']);
58 | $to = new Rev($localRef, $localHash, Util::extractBranchInfo($localRef)['branch']);
59 | $ranges[] = new Range($from, $to);
60 | }
61 | return $ranges;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Git/Range/Generic.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Range;
13 |
14 | use CaptainHook\App\Git\Range;
15 | use CaptainHook\App\Git\Rev;
16 |
17 | /**
18 | * Generic range implementation
19 | *
20 | * Most simple range implementation
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.15.0
26 | */
27 | class Generic implements Range
28 | {
29 | /**
30 | * Starting reference
31 | *
32 | * @var \CaptainHook\App\Git\Rev
33 | */
34 | private Rev $from;
35 |
36 | /**
37 | * Ending reference
38 | *
39 | * @var \CaptainHook\App\Git\Rev
40 | */
41 | private Rev $to;
42 |
43 | /**
44 | * Constructor
45 | *
46 | */
47 | public function __construct(Rev $from, Rev $to)
48 | {
49 | $this->from = $from;
50 | $this->to = $to;
51 | }
52 |
53 | /**
54 | * Return the git reference
55 | *
56 | * @return \CaptainHook\App\Git\Rev
57 | */
58 | public function from(): Rev
59 | {
60 | return $this->from;
61 | }
62 |
63 | /**
64 | * @return \CaptainHook\App\Git\Rev
65 | */
66 | public function to(): Rev
67 | {
68 | return $this->to;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/Git/Range/PrePush.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Range;
13 |
14 | use CaptainHook\App\Git;
15 | use CaptainHook\App\Git\Rev\PrePush as Rev;
16 |
17 | /**
18 | * Class
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 5.15.0
24 | */
25 | class PrePush implements Git\Range
26 | {
27 | /**
28 | * @var \CaptainHook\App\Git\Rev\PrePush
29 | */
30 | private Rev $from;
31 |
32 | /**
33 | * @var \CaptainHook\App\Git\Rev\PrePush
34 | */
35 | private Rev $to;
36 |
37 | /**
38 | * Constructor
39 | *
40 | * @param \CaptainHook\App\Git\Rev\PrePush $from
41 | * @param \CaptainHook\App\Git\Rev\PrePush $to
42 | */
43 | public function __construct(Rev $from, Rev $to)
44 | {
45 | $this->from = $from;
46 | $this->to = $to;
47 | }
48 |
49 | /**
50 | * Returns the start ref
51 | *
52 | * @return \CaptainHook\App\Git\Rev\PrePush
53 | */
54 | public function from(): Rev
55 | {
56 | return $this->from;
57 | }
58 |
59 | /**
60 | * Returns the end ref
61 | *
62 | * @return \CaptainHook\App\Git\Rev\PrePush
63 | */
64 | public function to(): Rev
65 | {
66 | return $this->to;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Git/Rev.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git;
13 |
14 | /**
15 | * Ref interface
16 | *
17 | * Git references can be used in git commands to identify positions in the git history.
18 | * For example: HEAD, 4FD60E21,
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 5.15.0
24 | */
25 | interface Rev
26 | {
27 | /**
28 | * Returns the ref id that can be used in a git command
29 | *
30 | * This can be completely a hash, branch name, ref-log position...
31 | *
32 | * @return string
33 | */
34 | public function id(): string;
35 | }
36 |
--------------------------------------------------------------------------------
/src/Git/Rev/Generic.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Rev;
13 |
14 | use CaptainHook\App\Git\Rev;
15 |
16 | /**
17 | * Generic range implementation
18 | *
19 | * The simplest imaginable range implementation without any extra information.
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 5.15.0
25 | */
26 | class Generic implements Rev
27 | {
28 | /**
29 | * Referencing a git state
30 | *
31 | * @var string
32 | */
33 | private string $id;
34 |
35 | /**
36 | * Constructor
37 | *
38 | * @param string $id
39 | */
40 | public function __construct(string $id)
41 | {
42 | $this->id = $id;
43 | }
44 |
45 | /**
46 | * Return the git reference
47 | *
48 | * @return string
49 | */
50 | public function id(): string
51 | {
52 | return $this->id;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Git/Rev/PrePush.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Rev;
13 |
14 | use CaptainHook\App\Git\Rev;
15 |
16 | /**
17 | * Git pre-push reference
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.15.0
23 | */
24 | class PrePush implements Rev
25 | {
26 | /**
27 | * Head path - refs/heads/main
28 | *
29 | * @var string
30 | */
31 | private string $head;
32 |
33 | /**
34 | * Git hash
35 | *
36 | * @var string
37 | */
38 | private string $hash;
39 |
40 | /**
41 | * Branch name
42 | *
43 | * @var string
44 | */
45 | private string $branch;
46 |
47 | /**
48 | * Constructor
49 | *
50 | * @param string $head
51 | * @param string $hash
52 | * @param string $branch
53 | */
54 | public function __construct(string $head, string $hash, string $branch)
55 | {
56 | $this->head = $head;
57 | $this->hash = $hash;
58 | $this->branch = $branch;
59 | }
60 |
61 | /**
62 | * Head getter
63 | *
64 | * @return string
65 | */
66 | public function head(): string
67 | {
68 | return $this->head;
69 | }
70 |
71 | /**
72 | * Hash getter
73 | *
74 | * @return string
75 | */
76 | public function hash(): string
77 | {
78 | return $this->hash;
79 | }
80 |
81 | /**
82 | * Branch getter
83 | *
84 | * @return string
85 | */
86 | public function branch(): string
87 | {
88 | return $this->branch;
89 | }
90 |
91 | /**
92 | * Returns the ref id that can be used in a git command
93 | *
94 | * This can be completely different thing hash, branch name, ref-log position...
95 | *
96 | * @return string
97 | */
98 | public function id(): string
99 | {
100 | return $this->hash;
101 | }
102 |
103 | /**
104 | * Is this a git dummy hash
105 | *
106 | * @return bool
107 | */
108 | public function isZeroRev(): bool
109 | {
110 | return Util::isZeroHash($this->hash);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/Git/Rev/Util.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Git\Rev;
13 |
14 | /**
15 | * Util class
16 | *
17 | * Does some simple format and validation stuff
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.15.0
23 | */
24 | abstract class Util
25 | {
26 | /**
27 | * Indicates if commit hash is a zero hash 0000000000000000000000000000000000000000
28 | *
29 | * @param string $hash
30 | * @return bool
31 | */
32 | public static function isZeroHash(string $hash): bool
33 | {
34 | return (bool) preg_match('/^0+$/', $hash);
35 | }
36 |
37 | /**
38 | * Splits remote and branch
39 | *
40 | * origin/main => ['remote' => 'origin', 'branch' => 'main']
41 | * main => ['remote' => 'origin', 'branch' => 'main']
42 | * ref/origin/main => ['remote' => 'origin', 'branch' => 'main']
43 | *
44 | * @param string $ref
45 | * @return array
46 | */
47 | public static function extractBranchInfo(string $ref): array
48 | {
49 | $ref = (string) preg_replace('#^refs/#', '', $ref);
50 | $parts = explode('/', $ref);
51 |
52 | return [
53 | 'remote' => count($parts) > 1 ? array_shift($parts) : 'origin',
54 | 'branch' => implode('/', $parts),
55 | ];
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Hook/Action.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use SebastianFeldmann\Git\Repository;
17 |
18 | /**
19 | * Interface Action
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 0.9.0
25 | */
26 | interface Action
27 | {
28 | /**
29 | * Executes the action
30 | *
31 | * @param \CaptainHook\App\Config $config
32 | * @param \CaptainHook\App\Console\IO $io
33 | * @param \SebastianFeldmann\Git\Repository $repository
34 | * @param \CaptainHook\App\Config\Action $action
35 | * @return void
36 | * @throws \Exception
37 | */
38 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void;
39 | }
40 |
--------------------------------------------------------------------------------
/src/Hook/Cli/Command.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Cli;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Hook\Action;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Class Notify
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.23.1
26 | */
27 | class Command implements Action
28 | {
29 | /**
30 | * Executes the action
31 | *
32 | * @param \CaptainHook\App\Config $config
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @param \SebastianFeldmann\Git\Repository $repository
35 | * @param \CaptainHook\App\Config\Action $action
36 | * @return void
37 | * @throws \Exception
38 | */
39 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
40 | {
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Hook/Condition.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use SebastianFeldmann\Git\Repository;
16 |
17 | /**
18 | * Interface Conditions
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 4.2.0
24 | */
25 | interface Condition
26 | {
27 | /**
28 | * Evaluates a condition
29 | *
30 | * @param \CaptainHook\App\Console\IO $io
31 | * @param \SebastianFeldmann\Git\Repository $repository
32 | * @return bool
33 | */
34 | public function isTrue(IO $io, Repository $repository): bool;
35 | }
36 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Branch/Files.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Branch;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition;
18 | use CaptainHook\App\Hook\FileList;
19 | use SebastianFeldmann\Git\Repository;
20 |
21 | /**
22 | * Files condition
23 | *
24 | * Example configuration:
25 | *
26 | * "action": "some-action"
27 | * "conditions": [
28 | * {"exec": "\\CaptainHook\\App\\Hook\\Condition\\Branch\\Files",
29 | * "args": [
30 | * {"compare-to": "main", "of-type": "php"}
31 | * ]}
32 | * ]
33 | *
34 | * @package CaptainHook
35 | * @author Sebastian Feldmann
36 | * @link https://github.com/captainhook-git/captainhook
37 | * @since Class available since Release 5.21.0
38 | */
39 | class Files implements Condition
40 | {
41 | /**
42 | * Options
43 | * - compare-to: source branch if known, otherwise the reflog is used to figure it out
44 | * - in-directory: only check for files in given directory
45 | * - of-type: only check for files of given type
46 | *
47 | * @var array
48 | */
49 | private array $options;
50 |
51 | /**
52 | * Constructor
53 | *
54 | * @param array $options
55 | */
56 | public function __construct(array $options = [])
57 | {
58 | $this->options = $options;
59 | }
60 |
61 | /**
62 | * Check if the current branch contains changes to files
63 | *
64 | * @param \CaptainHook\App\Console\IO $io
65 | * @param \SebastianFeldmann\Git\Repository $repository
66 | * @return bool
67 | */
68 | public function isTrue(IO $io, Repository $repository): bool
69 | {
70 | $branch = $repository->getInfoOperator()->getCurrentBranch();
71 | $start = $this->options['compared-to'] ?? $repository->getLogOperator()->getBranchRevFromRefLog($branch);
72 |
73 | if (empty($start)) {
74 | return false;
75 | }
76 |
77 | $files = $repository->getLogOperator()->getChangedFilesSince($start, ['A', 'C', 'M', 'R']);
78 |
79 | return count(FileList::filter($files, $this->options)) > 0;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Branch/Name.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Branch;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * OnBranch condition
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.0.0
27 | */
28 | abstract class Name implements Condition
29 | {
30 | /**
31 | * Branch name to compare
32 | *
33 | * @var string
34 | */
35 | protected string $name;
36 |
37 | /**
38 | * OnBranch constructor.
39 | *
40 | * @param string $name
41 | */
42 | public function __construct(string $name)
43 | {
44 | $this->name = $name;
45 | }
46 |
47 | /**
48 | * Check is the current branch is equal to the configured one
49 | *
50 | * @param \CaptainHook\App\Console\IO $io
51 | * @param \SebastianFeldmann\Git\Repository $repository
52 | * @return bool
53 | */
54 | abstract public function isTrue(IO $io, Repository $repository): bool;
55 | }
56 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Branch/NotOn.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Branch;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * NotOn condition
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.20.2
27 | */
28 | class NotOn extends Name
29 | {
30 | /**
31 | * Check is the current branch is not equal to the configured one
32 | *
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @param \SebastianFeldmann\Git\Repository $repository
35 | * @return bool
36 | */
37 | public function isTrue(IO $io, Repository $repository): bool
38 | {
39 | return trim($repository->getInfoOperator()->getCurrentBranch()) !== $this->name;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Branch/NotOnMatching.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Branch;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * NotOnMatching condition
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.20.2
27 | */
28 | class NotOnMatching extends Name
29 | {
30 | /**
31 | * Check is the current branch is not matched by the configured regex
32 | *
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @param \SebastianFeldmann\Git\Repository $repository
35 | * @return bool
36 | */
37 | public function isTrue(IO $io, Repository $repository): bool
38 | {
39 | return preg_match($this->name, trim($repository->getInfoOperator()->getCurrentBranch())) === 0;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Branch/On.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Branch;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * On condition
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.20.2
27 | */
28 | class On extends Name
29 | {
30 | /**
31 | * Check is the current branch is equal to the configured one
32 | *
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @param \SebastianFeldmann\Git\Repository $repository
35 | * @return bool
36 | */
37 | public function isTrue(IO $io, Repository $repository): bool
38 | {
39 | return trim($repository->getInfoOperator()->getCurrentBranch()) === $this->name;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Branch/OnMatching.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Branch;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * OnMatching condition
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.20.2
27 | */
28 | class OnMatching extends Name
29 | {
30 | /**
31 | * Check is the current branch is matched by the configured regex
32 | *
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @param \SebastianFeldmann\Git\Repository $repository
35 | * @return bool
36 | */
37 | public function isTrue(IO $io, Repository $repository): bool
38 | {
39 | return preg_match($this->name, trim($repository->getInfoOperator()->getCurrentBranch())) === 1;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Cli.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Hook\Condition;
16 | use SebastianFeldmann\Cli\Processor;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Class Cli
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 4.2.0
26 | */
27 | class Cli implements Condition
28 | {
29 | /**
30 | * Binary executor
31 | *
32 | * @var \SebastianFeldmann\Cli\Processor
33 | */
34 | private $processor;
35 |
36 | /**
37 | * @var string
38 | */
39 | private $command;
40 |
41 | /**
42 | * Cli constructor.
43 | *
44 | * @param \SebastianFeldmann\Cli\Processor $processor
45 | * @param string $command
46 | */
47 | public function __construct(Processor $processor, string $command)
48 | {
49 | $this->processor = $processor;
50 | $this->command = $command;
51 | }
52 |
53 | /**
54 | * Evaluates a condition
55 | *
56 | * @param \CaptainHook\App\Console\IO $io
57 | * @param \SebastianFeldmann\Git\Repository $repository
58 | * @return bool
59 | */
60 | public function isTrue(IO $io, Repository $repository): bool
61 | {
62 | $result = $this->processor->run($this->command);
63 |
64 | return $result->isSuccessful();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Config.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition;
13 |
14 | use CaptainHook\App\Config as AppConfig;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Hook\Condition;
17 | use RuntimeException;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * Class FileChange
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 4.2.0
27 | */
28 | abstract class Config implements ConfigDependant, Condition
29 | {
30 | /**
31 | * @var \CaptainHook\App\Config|null
32 | */
33 | protected ?AppConfig $config = null;
34 |
35 | /**
36 | * Config setter
37 | *
38 | * @param \CaptainHook\App\Config $config
39 | * @return void
40 | */
41 | public function setConfig(AppConfig $config): void
42 | {
43 | $this->config = $config;
44 | }
45 |
46 | /**
47 | * Check if the customer value exists and return izs boolish value
48 | *
49 | * @param string $value
50 | * @param bool $default
51 | * @return bool
52 | */
53 | protected function checkCustomValue(string $value, bool $default): bool
54 | {
55 | if (null === $this->config) {
56 | throw new RuntimeException('config not set');
57 | }
58 | $customSettings = $this->config->getCustomSettings();
59 | $valueToCheck = $customSettings[$value] ?? $default;
60 | return filter_var($valueToCheck, FILTER_VALIDATE_BOOL);
61 | }
62 |
63 | /**
64 | * Evaluates a condition
65 | *
66 | * @param \CaptainHook\App\Console\IO $io
67 | * @param \SebastianFeldmann\Git\Repository $repository
68 | * @return bool
69 | */
70 | abstract public function isTrue(IO $io, Repository $repository): bool;
71 | }
72 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Config/CustomValueIsFalsy.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition\Config;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Hook\Condition;
16 | use CaptainHook\App\Hooks;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Class CustomValueIsFalsy
21 | *
22 | * Example configuration:
23 | *
24 | * "action": "some-action"
25 | * "conditions": [
26 | * {"exec": "\\CaptainHook\\App\\Hook\\Condition\\Config\\CustomValueIsFalsy",
27 | * "args": [
28 | * "NAME_OF_CUSTOM_VALUE"
29 | * ]}
30 | * ]
31 | *
32 | * @package CaptainHook
33 | * @author Sebastian Feldmann
34 | * @link https://github.com/captainhook-git/captainhook
35 | * @since Class available since Release 5.17.2
36 | */
37 | class CustomValueIsFalsy extends Condition\Config
38 | {
39 | /**
40 | * Custom config value to check
41 | *
42 | * @var string
43 | */
44 | private string $value;
45 |
46 | /**
47 | * CustomValueIsFalsy constructor
48 | *
49 | * @param string $value
50 | */
51 | public function __construct(string $value)
52 | {
53 | $this->value = $value;
54 | }
55 |
56 | /**
57 | * Evaluates the condition
58 | *
59 | * @param \CaptainHook\App\Console\IO $io
60 | * @param \SebastianFeldmann\Git\Repository $repository
61 | * @return bool
62 | */
63 | public function isTrue(IO $io, Repository $repository): bool
64 | {
65 | return !$this->checkCustomValue($this->value, false);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Config/CustomValueIsTruthy.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition\Config;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Hook\Condition;
16 | use CaptainHook\App\Hooks;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Class CustomValueIsTruthy
21 | *
22 | * Example configuration:
23 | *
24 | * "action": "some-action"
25 | * "conditions": [
26 | * {"exec": "\\CaptainHook\\App\\Hook\\Condition\\Config\\CustomValueIsTruthy",
27 | * "args": [
28 | * "NAME_OF_CUSTOM_VALUE"
29 | * ]}
30 | * ]
31 | *
32 | * @package CaptainHook
33 | * @author Sebastian Feldmann
34 | * @link https://github.com/captainhook-git/captainhook
35 | * @since Class available since Release 5.17.2
36 | */
37 | class CustomValueIsTruthy extends Condition\Config
38 | {
39 | /**
40 | * Custom config value to check
41 | *
42 | * @var string
43 | */
44 | private string $value;
45 |
46 | /**
47 | * CustomValueIsTruthy constructor
48 | *
49 | * @param string $value
50 | */
51 | public function __construct(string $value)
52 | {
53 | $this->value = $value;
54 | }
55 |
56 | /**
57 | * Evaluates the condition
58 | *
59 | * @param \CaptainHook\App\Console\IO $io
60 | * @param \SebastianFeldmann\Git\Repository $repository
61 | * @return bool
62 | */
63 | public function isTrue(IO $io, Repository $repository): bool
64 | {
65 | return $this->checkCustomValue($this->value, false);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Hook/Condition/ConfigDependant.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition;
13 |
14 | use CaptainHook\App\Config;
15 |
16 | /**
17 | * Interface Conditions
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.17.2
23 | */
24 | interface ConfigDependant
25 | {
26 | /**
27 | * Evaluates a condition
28 | *
29 | * This will be deprecated in version 6.0.0
30 | * In version 6.0.0 the condition interface should change to include the Config
31 | *
32 | * @param \CaptainHook\App\Config $config
33 | * @return void
34 | */
35 | public function setConfig(Config $config): void;
36 | }
37 |
--------------------------------------------------------------------------------
/src/Hook/Condition/FileChanged/All.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition\FileChanged;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Hook\Condition\FileChanged;
16 | use SebastianFeldmann\Git\Repository;
17 |
18 | /**
19 | * Class All
20 | *
21 | * The FileChange condition is applicable for `post-merge` and `post-checkout` hooks.
22 | * It checks if all configured files are updated within the last change set.
23 | *
24 | * @package CaptainHook
25 | * @author Sebastian Feldmann
26 | * @link https://github.com/captainhook-git/captainhook
27 | * @since Class available since Release 4.2.0
28 | */
29 | class All extends FileChanged
30 | {
31 | /**
32 | * Check if all the configured files were changed within the applied change set
33 | *
34 | * IMPORTANT: If no files are configured this condition is always true.
35 | *
36 | * @param \CaptainHook\App\Console\IO $io
37 | * @param \SebastianFeldmann\Git\Repository $repository
38 | * @return bool
39 | */
40 | public function isTrue(IO $io, Repository $repository): bool
41 | {
42 | return $this->allFilesInHaystack($this->filesToWatch, $this->getChangedFiles($io, $repository));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Hook/Condition/FileChanged/Any.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition\FileChanged;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Hook\Condition\FileChanged;
16 | use SebastianFeldmann\Git\Repository;
17 |
18 | /**
19 | * Class Any
20 | *
21 | * The FileChange condition is applicable for `post-merge` and `post-checkout` hooks.
22 | * For example it can be used to trigger an automatic composer install if the composer.json
23 | * or composer.lock file is changed during a checkout or merge.
24 | *
25 | * Example configuration:
26 | *
27 | * "action": "composer install"
28 | * "conditions": [
29 | * {"exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChange\\Any",
30 | * "args": [
31 | * [
32 | * "composer.json",
33 | * "composer.lock"
34 | * ]
35 | * ]}
36 | * ]
37 | *
38 | * @package CaptainHook
39 | * @author Sebastian Feldmann
40 | * @link https://github.com/captainhook-git/captainhook
41 | * @since Class available since Release 4.2.0
42 | */
43 | class Any extends FileChanged
44 | {
45 | /**
46 | * Check if any of the configured files was changed within the applied change set
47 | *
48 | * IMPORTANT: If no files are configured this condition is always false.
49 | *
50 | * @param \CaptainHook\App\Console\IO $io
51 | * @param \SebastianFeldmann\Git\Repository $repository
52 | * @return bool
53 | */
54 | public function isTrue(IO $io, Repository $repository): bool
55 | {
56 | return $this->anyFileInHaystack($this->filesToWatch, $this->getChangedFiles($io, $repository));
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Hook/Condition/FileChanged/OfType.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition\FileChanged;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Git;
16 | use CaptainHook\App\Hook\Condition;
17 | use CaptainHook\App\Hook\Constrained;
18 | use CaptainHook\App\Hook\FileList;
19 | use CaptainHook\App\Hook\Restriction;
20 | use CaptainHook\App\Hooks;
21 | use SebastianFeldmann\Git\Repository;
22 |
23 | /**
24 | * Class OfType
25 | *
26 | * Example configuration:
27 | *
28 | * "action": "some-action"
29 | * "conditions": [
30 | * {"exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\OfType",
31 | * "args": [
32 | * "php"
33 | * ]}
34 | * ]
35 | *
36 | * @package CaptainHook
37 | * @author Sebastian Feldmann
38 | * @link https://github.com/captainhook-git/captainhook
39 | * @since Class available since Release 5.0.0
40 | */
41 | class OfType implements Condition, Constrained
42 | {
43 | /**
44 | * File type to check e.g. 'php' or 'html'
45 | *
46 | * @var string
47 | */
48 | private string $suffix;
49 |
50 | /**
51 | * OfType constructor
52 | *
53 | * @param string $type
54 | */
55 | public function __construct(string $type)
56 | {
57 | $this->suffix = $type;
58 | }
59 |
60 | /**
61 | * Return the hook restriction information
62 | *
63 | * @return \CaptainHook\App\Hook\Restriction
64 | */
65 | public static function getRestriction(): Restriction
66 | {
67 | return Restriction::fromArray([Hooks::PRE_PUSH, Hooks::POST_CHECKOUT, Hooks::POST_MERGE, Hooks::POST_REWRITE]);
68 | }
69 |
70 | /**
71 | * Evaluates the condition
72 | *
73 | * @param \CaptainHook\App\Console\IO $io
74 | * @param \SebastianFeldmann\Git\Repository $repository
75 | * @return bool
76 | */
77 | public function isTrue(IO $io, Repository $repository): bool
78 | {
79 | $factory = new Git\ChangedFiles\Detector\Factory();
80 | $detector = $factory->getDetector($io, $repository);
81 |
82 | $files = $detector->getChangedFiles(['A', 'C', 'M', 'R']);
83 | $files = FileList::filterByType($files, ['of-type' => $this->suffix]);
84 |
85 | if (count($files) > 0) {
86 | return true;
87 | }
88 | return false;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/Hook/Condition/FileStaged.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Git\Diff\FilterUtil;
16 | use CaptainHook\App\Hook\Restriction;
17 | use CaptainHook\App\Hooks;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * Class FileChange
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.2.0
27 | */
28 | abstract class FileStaged extends File
29 | {
30 | /**
31 | * List of file to watch
32 | *
33 | * @var array
34 | */
35 | protected array $filesToWatch;
36 |
37 | /**
38 | * --diff-filter options
39 | *
40 | * @var array
41 | */
42 | protected array $diffFilter;
43 |
44 | /**
45 | * FileStaged constructor
46 | *
47 | * @param mixed $files
48 | * @param mixed $diffFilter
49 | */
50 | public function __construct($files, $diffFilter = [])
51 | {
52 | $this->filesToWatch = is_array($files) ? $files : explode(',', (string) $files);
53 | $this->diffFilter = FilterUtil::filterFromConfigValue($diffFilter);
54 | }
55 |
56 | /**
57 | * Return the hook restriction information
58 | *
59 | * @return \CaptainHook\App\Hook\Restriction
60 | */
61 | public static function getRestriction(): Restriction
62 | {
63 | return Restriction::fromArray([Hooks::PRE_COMMIT]);
64 | }
65 |
66 | /**
67 | * Evaluates a condition
68 | *
69 | * @param \CaptainHook\App\Console\IO $io
70 | * @param \SebastianFeldmann\Git\Repository $repository
71 | * @return bool
72 | */
73 | abstract public function isTrue(IO $io, Repository $repository): bool;
74 |
75 | /**
76 | * Use 'diff-index --cached' to find the staged files before the commit
77 | *
78 | * @param \SebastianFeldmann\Git\Repository $repository
79 | * @return array
80 | */
81 | protected function getStagedFiles(Repository $repository): array
82 | {
83 | return $repository->getIndexOperator()->getStagedFiles($this->diffFilter);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Hook/Condition/FileStaged/All.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition\FileStaged;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Hook\Condition\FileStaged;
16 | use SebastianFeldmann\Git\Repository;
17 |
18 | /**
19 | * Class All
20 | *
21 | * The FileStaged condition is applicable for `pre-commit` hooks.
22 | * It checks if all configured files are staged for commit.
23 | *
24 | * Example configuration:
25 | *
26 | * "action": "some-action"
27 | * "conditions": [
28 | * {"exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\All",
29 | * "args": [
30 | * ["file1", "file2", "file3"]
31 | * ]}
32 | * ]
33 | *
34 | * The file list can also be defined as comma seperated string "file1,file2,file3"
35 | *
36 | * @package CaptainHook
37 | * @author Sebastian Feldmann
38 | * @link https://github.com/captainhook-git/captainhook
39 | * @since Class available since Release 5.2.0
40 | */
41 | class All extends FileStaged
42 | {
43 | /**
44 | * Check if all the configured files are staged for commit
45 | *
46 | * @param \CaptainHook\App\Console\IO $io
47 | * @param \SebastianFeldmann\Git\Repository $repository
48 | * @return bool
49 | */
50 | public function isTrue(IO $io, Repository $repository): bool
51 | {
52 | return $this->allFilesInHaystack($this->filesToWatch, $this->getStagedFiles($repository));
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Hook/Condition/FileStaged/Any.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Condition\FileStaged;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use CaptainHook\App\Hook\Condition\FileStaged;
16 | use SebastianFeldmann\Git\Repository;
17 |
18 | /**
19 | * Class Any
20 | *
21 | * The FileStaged condition is applicable for `pre-commit hooks.
22 | *
23 | * Example configuration:
24 | *
25 | * "action": "some-action"
26 | * "conditions": [
27 | * {"exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\Any",
28 | * "args": [
29 | * ["file1", "file2", "file3"]
30 | * ]}
31 | * ]
32 | *
33 | * The file list can also be defined as comma seperated string "file1,file2,file3"
34 | *
35 | * @package CaptainHook
36 | * @author Sebastian Feldmann
37 | * @link https://github.com/captainhook-git/captainhook
38 | * @since Class available since Release 5.2.0
39 | */
40 | class Any extends FileStaged
41 | {
42 | /**
43 | * Check if any of the configured files is staged for commit
44 | *
45 | * @param \CaptainHook\App\Console\IO $io
46 | * @param \SebastianFeldmann\Git\Repository $repository
47 | * @return bool
48 | */
49 | public function isTrue(IO $io, Repository $repository): bool
50 | {
51 | return $this->anyFileInHaystack($this->filesToWatch, $this->getStagedFiles($repository));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Logic.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition;
15 |
16 | use CaptainHook\App\Hook\Condition;
17 |
18 | /**
19 | * Logical condition base class
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @author Andreas Heigl
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.7.0
26 | */
27 | abstract class Logic implements Condition
28 | {
29 | /**
30 | * List of conditions to logically connect
31 | *
32 | * @var \CaptainHook\App\Hook\Condition[]
33 | */
34 | protected array $conditions = [];
35 |
36 | final private function __construct(Condition ...$conditions)
37 | {
38 | $this->conditions = $conditions;
39 | }
40 |
41 | /**
42 | * Create a logic condition
43 | *
44 | * @param array $conditions
45 | * @return \CaptainHook\App\Hook\Condition
46 | */
47 | public static function fromConditionsArray(array $conditions): Condition
48 | {
49 | $realConditions = [];
50 | foreach ($conditions as $condition) {
51 | if (! $condition instanceof Condition) {
52 | continue;
53 | }
54 | $realConditions[] = $condition;
55 | }
56 |
57 | return new static(...$realConditions);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Logic/LogicAnd.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Logic;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition\Logic;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * Connects multiple conditions with 'and'
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @author Andreas Heigl
26 | * @link https://github.com/captainhook-git/captainhook
27 | * @since Class available since Release 5.7.0
28 | */
29 | final class LogicAnd extends Logic
30 | {
31 | public function isTrue(IO $io, Repository $repository): bool
32 | {
33 | foreach ($this->conditions as $condition) {
34 | if (false === $condition->isTrue($io, $repository)) {
35 | return false;
36 | }
37 | }
38 | return true;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Hook/Condition/Logic/LogicOr.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition\Logic;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition\Logic;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * Connects multiple conditions with 'or'
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @author Andreas Heigl
26 | * @link https://github.com/captainhook-git/captainhook
27 | * @since Class available since Release 5.7.0
28 | */
29 | final class LogicOr extends Logic
30 | {
31 | public function isTrue(IO $io, Repository $repository): bool
32 | {
33 | foreach ($this->conditions as $condition) {
34 | if (true === $condition->isTrue($io, $repository)) {
35 | return true;
36 | }
37 | }
38 | return false;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Hook/Condition/OnBranch.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Condition;
15 |
16 | use CaptainHook\App\Console\IO;
17 | use CaptainHook\App\Hook\Condition;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * OnBranch condition
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.0.0
27 | * @deprecated Replaced be CaptainHook\App\Hook\Condition\Branch\CurrentlyOn
28 | */
29 | class OnBranch extends Condition\Branch\On
30 | {
31 | }
32 |
--------------------------------------------------------------------------------
/src/Hook/Constrained.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook;
15 |
16 | /**
17 | * Interface Constrained
18 | *
19 | * If your action is only applicable for a certain set of hooks you can limit its execution to specific hooks by
20 | * implementing this interface and returning a restriction value object.
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.0.0
26 | */
27 | interface Constrained
28 | {
29 | /**
30 | * Returns the list of hooks where this action is applicable
31 | *
32 | * @return \CaptainHook\App\Hook\Restriction
33 | */
34 | public static function getRestriction(): Restriction;
35 | }
36 |
--------------------------------------------------------------------------------
/src/Hook/Debug.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Exception\ActionFailed;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Debug hook to test hook triggering
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 4.0.4
26 | */
27 | abstract class Debug implements Action
28 | {
29 | /**
30 | * Executes the action
31 | *
32 | * @param \CaptainHook\App\Config $config
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @param \SebastianFeldmann\Git\Repository $repository
35 | * @param \CaptainHook\App\Config\Action $action
36 | * @return void
37 | * @throws \Exception
38 | */
39 | abstract public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void;
40 |
41 | /**
42 | * Generate some debug output
43 | *
44 | * @param \CaptainHook\App\Console\IO $io
45 | * @param \SebastianFeldmann\Git\Repository $repository
46 | * @return void
47 | */
48 | protected function debugOutput(IO $io, Repository $repository): void
49 | {
50 | $originalHookArguments = $io->getArguments();
51 | $currentGitTag = $repository->getInfoOperator()->getCurrentTag();
52 |
53 | $io->write(['', '']);
54 | $io->write('Executing Dummy action');
55 | $io->write($this->getArgumentOutput($originalHookArguments));
56 | $io->write(' Current git-tag: ' . $currentGitTag . '');
57 | $io->write(' StandardInput: ' . PHP_EOL . ' ' . implode(PHP_EOL . ' ', $io->getStandardInput()));
58 | }
59 |
60 | /**
61 | * Format output to display original hook arguments
62 | *
63 | * @param array $args
64 | * @return string
65 | */
66 | protected function getArgumentOutput(array $args): string
67 | {
68 | $out = ' Original arguments:' . PHP_EOL;
69 | foreach ($args as $name => $value) {
70 | $out .= ' ' . $name . ' => ' . $value . '' . PHP_EOL;
71 | }
72 | return trim($out);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Hook/Debug/Failure.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Debug;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Exception\ActionFailed;
17 | use CaptainHook\App\Hook\Debug;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * Debug hook to test hook triggering that fails the hook execution
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.20.1
27 | */
28 | class Failure extends Debug
29 | {
30 | /**
31 | * Executes the action
32 | *
33 | * @param \CaptainHook\App\Config $config
34 | * @param \CaptainHook\App\Console\IO $io
35 | * @param \SebastianFeldmann\Git\Repository $repository
36 | * @param \CaptainHook\App\Config\Action $action
37 | * @return void
38 | * @throws \Exception
39 | */
40 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
41 | {
42 | $this->debugOutput($io, $repository);
43 |
44 | throw new ActionFailed(
45 | 'The \'Debug\' action is only for debugging purposes, '
46 | . 'please remove the \'Debug\' action from your config'
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Hook/Debug/Success.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Debug;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Hook\Debug;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Debug hook to test hook triggering that allows the hook to pass
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 4.0.4
26 | */
27 | class Success extends Debug
28 | {
29 | /**
30 | * Executes the action
31 | *
32 | * @param \CaptainHook\App\Config $config
33 | * @param \CaptainHook\App\Console\IO $io
34 | * @param \SebastianFeldmann\Git\Repository $repository
35 | * @param \CaptainHook\App\Config\Action $action
36 | * @return void
37 | * @throws \Exception
38 | */
39 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
40 | {
41 | $this->debugOutput($io, $repository);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Hook/EventSubscriber.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook;
13 |
14 | use CaptainHook\App\Config\Action as ActionConfig;
15 |
16 | /**
17 | * Interface EventSubscriber
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.11.0
23 | */
24 | interface EventSubscriber
25 | {
26 | /**
27 | * Returns a list of event handlers
28 | *
29 | * @param \CaptainHook\App\Config\Action $action
30 | * @return array>
31 | * @throws \Exception
32 | */
33 | public static function getEventHandlers(ActionConfig $action): array;
34 | }
35 |
--------------------------------------------------------------------------------
/src/Hook/File/Action/IsEmpty.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\File\Action;
13 |
14 | use SebastianFeldmann\Git\Repository;
15 |
16 | /**
17 | * Class IsEmpty
18 | *
19 | * @package CaptainHook
20 | * @author Felix Edelmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.4.0
23 | */
24 | class IsEmpty extends Emptiness
25 | {
26 | /**
27 | * Actual action name for better error messages
28 | *
29 | * @var string
30 | */
31 | protected string $actionName = 'IsEmpty';
32 |
33 | /**
34 | * Checks if the file is valid or not
35 | *
36 | * @param \SebastianFeldmann\Git\Repository $repository
37 | * @param string $file
38 | * @return bool
39 | */
40 | protected function isValid(Repository $repository, string $file): bool
41 | {
42 | return $this->isEmpty($file);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Hook/File/Action/IsNotEmpty.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\File\Action;
13 |
14 | use SebastianFeldmann\Git\Repository;
15 |
16 | /**
17 | * Class IsNotEmpty
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.4.1
23 | */
24 | class IsNotEmpty extends Emptiness
25 | {
26 | /**
27 | * Actual action name for better error messages
28 | *
29 | * @var string
30 | */
31 | protected string $actionName = 'IsNotEmpty';
32 |
33 | /**
34 | * Checks if the file is valid or not
35 | *
36 | * @param \SebastianFeldmann\Git\Repository $repository
37 | * @param string $file
38 | * @return bool
39 | */
40 | protected function isValid(Repository $repository, string $file): bool
41 | {
42 | return !$this->isEmpty($file);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Hook/Message/Action/Beams.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Message\Action;
15 |
16 | use CaptainHook\App\Config;
17 | use CaptainHook\App\Console\IO;
18 | use CaptainHook\App\Hook\Message\RuleBook;
19 | use SebastianFeldmann\Git\Repository;
20 |
21 | /**
22 | * Class Beams
23 | *
24 | * @package CaptainHook
25 | * @author Sebastian Feldmann
26 | * @link https://github.com/captainhook-git/captainhook
27 | * @since Class available since Release 0.9.0
28 | */
29 | class Beams extends Book
30 | {
31 | /**
32 | * Execute the configured action
33 | *
34 | * @param \CaptainHook\App\Config $config
35 | * @param \CaptainHook\App\Console\IO $io
36 | * @param \SebastianFeldmann\Git\Repository $repository
37 | * @param \CaptainHook\App\Config\Action $action
38 | * @return void
39 | * @throws \Exception
40 | */
41 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
42 | {
43 | $options = $action->getOptions();
44 | $book = new RuleBook();
45 | $book->setRules(RuleBook\RuleSet::beams(
46 | (int) $options->get('subjectLength', 50),
47 | (int) $options->get('bodyLineLength', 72),
48 | (bool) $options->get('checkImperativeBeginningOnly', false)
49 | ));
50 |
51 | $this->validate($book, $repository, $io);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Hook/Message/Action/CacheOnFail.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Message\Action;
15 |
16 | use CaptainHook\App\Config;
17 | use CaptainHook\App\Console\IO;
18 | use CaptainHook\App\Exception\ActionFailed;
19 | use CaptainHook\App\Hook\Action;
20 | use CaptainHook\App\Hook\EventSubscriber;
21 | use CaptainHook\App\Hook\Message\EventHandler\WriteCacheFile;
22 | use SebastianFeldmann\Git\Repository;
23 |
24 | /**
25 | * Class FailedStore
26 | *
27 | * @package CaptainHook
28 | * @author Sebastian Feldmann
29 | * @link https://github.com/captainhook-git/captainhook
30 | * @since Class available since Release 5.11.0
31 | */
32 | class CacheOnFail implements Action, EventSubscriber
33 | {
34 | /**
35 | * Execute the configured action
36 | *
37 | * @param \CaptainHook\App\Config $config
38 | * @param \CaptainHook\App\Console\IO $io
39 | * @param \SebastianFeldmann\Git\Repository $repository
40 | * @param \CaptainHook\App\Config\Action $action
41 | * @return void
42 | * @throws \Exception
43 | */
44 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
45 | {
46 | // this action is just registering some event handler, so nothing to see here
47 | }
48 |
49 | /**
50 | * Returns a list of event handlers
51 | *
52 | * @param \CaptainHook\App\Config\Action $action
53 | * @return array>
54 | * @throws \Exception
55 | */
56 | public static function getEventHandlers(Config\Action $action): array
57 | {
58 | // make sure the cache file is configured
59 | if (empty($action->getOptions()->get('file', ''))) {
60 | throw new ActionFailed('CacheOnFail requires \'file\' option');
61 | }
62 | return [
63 | 'onHookFailure' => [new WriteCacheFile($action->getOptions()->get('file', ''))]
64 | ];
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Hook/Message/Action/Prepare.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Action;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Hook\Action;
17 | use SebastianFeldmann\Git\CommitMessage;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * Class Prepare
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 3.1.0
27 | */
28 | class Prepare implements Action
29 | {
30 | /**
31 | * Executes the action
32 | *
33 | * @param \CaptainHook\App\Config $config
34 | * @param \CaptainHook\App\Console\IO $io
35 | * @param \SebastianFeldmann\Git\Repository $repository
36 | * @param \CaptainHook\App\Config\Action $action
37 | * @return void
38 | * @throws \Exception
39 | */
40 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
41 | {
42 | $options = $action->getOptions();
43 | $oldMsg = $repository->getCommitMsg();
44 |
45 | if (!$repository->isMerging()) {
46 | $repository->setCommitMsg(new CommitMessage($options->get('message', ''), $oldMsg->getCommentCharacter()));
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Hook/Message/Action/PrepareFromFile.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Message\Action;
15 |
16 | use CaptainHook\App\Config;
17 | use CaptainHook\App\Console\IO;
18 | use CaptainHook\App\Exception\ActionFailed;
19 | use CaptainHook\App\Hook\Action;
20 | use SebastianFeldmann\Git\CommitMessage;
21 | use SebastianFeldmann\Git\Repository;
22 |
23 | /**
24 | * Class PrepareFromFile
25 | *
26 | * Example configuration:
27 | * {
28 | * "action": "\\CaptainHook\\App\\Hook\\Message\\Action\\PrepareFromFile"
29 | * "options": {
30 | * "file": ".git/CH_MSG_CACHE"
31 | * }
32 | * }
33 | *
34 | * @package CaptainHook
35 | * @author Sebastian Feldmann
36 | * @link https://github.com/captainhook-git/captainhook
37 | * @since Class available since Release 5.11.0
38 | */
39 | class PrepareFromFile implements Action
40 | {
41 | /**
42 | * Execute the configured action
43 | *
44 | * @param \CaptainHook\App\Config $config
45 | * @param \CaptainHook\App\Console\IO $io
46 | * @param \SebastianFeldmann\Git\Repository $repository
47 | * @param \CaptainHook\App\Config\Action $action
48 | * @return void
49 | * @throws \Exception
50 | */
51 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
52 | {
53 | $options = $action->getOptions();
54 | $cacheFile = $repository->getRoot() . '/' . $options->get('file', '');
55 | if (empty($options->get('file', ''))) {
56 | throw new ActionFailed('PrepareFromFile requires \'file\' option');
57 | }
58 |
59 | if (!is_file($cacheFile)) {
60 | return;
61 | }
62 |
63 | // if there is a commit message don't do anything just delete the file
64 | if ($repository->getCommitMsg()->isEmpty()) {
65 | $msg = (string)file_get_contents($cacheFile);
66 | $repository->setCommitMsg(
67 | new CommitMessage($msg, $repository->getCommitMsg()->getCommentCharacter())
68 | );
69 | }
70 |
71 | if (!$options->get('keep', false)) {
72 | unlink($cacheFile);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/Hook/Message/EventHandler/WriteCacheFile.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\EventHandler;
13 |
14 | use CaptainHook\App\Event;
15 | use CaptainHook\App\Event\Handler;
16 |
17 | /**
18 | * Writes to commit message cache file to load it for a later commit
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 5.11.0
24 | */
25 | class WriteCacheFile implements Handler
26 | {
27 | /**
28 | * Path to the commit message cache file
29 | *
30 | * @var string
31 | */
32 | private $file;
33 |
34 | /**
35 | * @param string $file
36 | */
37 | public function __construct(string $file)
38 | {
39 | $this->file = $file;
40 | }
41 | /**
42 | * Writes the commit message to a cache file to reuse it for the next commit
43 | *
44 | * @return void
45 | */
46 | public function handle(Event $event)
47 | {
48 | $msg = $event->repository()->getCommitMsg()->getRawContent();
49 | $path = $event->repository()->getRoot() . '/' . $this->file;
50 | file_put_contents($path, $msg);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Interface Rule
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | interface Rule
25 | {
26 | /**
27 | * Return a hint how to pass the rule.
28 | *
29 | * @return string
30 | */
31 | public function getHint(): string;
32 |
33 | /**
34 | * Checks if a commit message passes the rule.
35 | *
36 | * @param \SebastianFeldmann\Git\CommitMessage $msg
37 | * @return bool
38 | */
39 | public function pass(CommitMessage $msg): bool;
40 | }
41 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/Base.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 | use CaptainHook\App\Hook\Message\Rule;
16 |
17 | /**
18 | * Class Base
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 0.9.0
24 | */
25 | abstract class Base implements Rule
26 | {
27 | /**
28 | * Rule hint.
29 | *
30 | * @var string
31 | */
32 | protected $hint;
33 |
34 | /**
35 | * @return string
36 | */
37 | public function getHint(): string
38 | {
39 | return $this->hint;
40 | }
41 |
42 | /**
43 | * @param \SebastianFeldmann\Git\CommitMessage $msg
44 | * @return bool
45 | */
46 | abstract public function pass(CommitMessage $msg): bool;
47 | }
48 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/CapitalizeSubject.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Class CapitalizeSubject
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class CapitalizeSubject extends Base
25 | {
26 | /**
27 | * Constructor
28 | */
29 | public function __construct()
30 | {
31 | $this->hint = 'Subject line has to start with an upper case letter';
32 | }
33 |
34 | /**
35 | * Check if commit message starts with upper case letter
36 | *
37 | * @param \SebastianFeldmann\Git\CommitMessage $msg
38 | * @return bool
39 | */
40 | public function pass(CommitMessage $msg): bool
41 | {
42 | if (!$msg->isEmpty()) {
43 | $firstLetter = substr($msg->getSubject(), 0, 1);
44 | return $firstLetter === strtoupper($firstLetter);
45 | }
46 | return false;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/LimitBodyLineLength.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Class LimitBodyLineLength
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class LimitBodyLineLength extends Base
25 | {
26 | /**
27 | * Length limit
28 | *
29 | * @var int
30 | */
31 | protected $maxLength;
32 |
33 | /**
34 | * Constructor
35 | *
36 | * @param int $length
37 | */
38 | public function __construct($length = 72)
39 | {
40 | $this->hint = 'Body lines should not exceed ' . $length . ' characters';
41 | $this->maxLength = $length;
42 | }
43 |
44 | /**
45 | * Check if a body line doesn't exceed the max length limit
46 | *
47 | * @param \SebastianFeldmann\Git\CommitMessage $msg
48 | * @return bool
49 | */
50 | public function pass(CommitMessage $msg): bool
51 | {
52 | $lineNr = 1;
53 | foreach ($msg->getBodyLines() as $line) {
54 | if (mb_strlen($line) > $this->maxLength) {
55 | $this->hint .= PHP_EOL . 'Line ' . $lineNr . ' of your body exceeds the max line length';
56 | return false;
57 | }
58 | $lineNr++;
59 | }
60 | return true;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/LimitSubjectLength.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Class LimitSubjectLength
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class LimitSubjectLength extends Base
25 | {
26 | /**
27 | * Length limit
28 | *
29 | * @var int
30 | */
31 | protected $maxLength;
32 |
33 | /**
34 | * Constructor
35 | *
36 | * @param int $length
37 | */
38 | public function __construct(int $length = 50)
39 | {
40 | $this->hint = 'Subject line should not exceed ' . $length . ' characters';
41 | $this->maxLength = $length;
42 | }
43 |
44 | /**
45 | * Check if commit message doesn't exceeed the max length
46 | *
47 | * @param \SebastianFeldmann\Git\CommitMessage $msg
48 | * @return bool
49 | */
50 | public function pass(CommitMessage $msg): bool
51 | {
52 | $subjectLength = mb_strlen($msg->getSubject());
53 | if ($subjectLength > $this->maxLength) {
54 | $this->hint .= ' (' . $subjectLength . ')';
55 | return false;
56 | }
57 | return true;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/MsgNotEmpty.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Class MsgNotEmpty
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class MsgNotEmpty extends Base
25 | {
26 | /**
27 | * SubjectStartsUpperCase constructor
28 | */
29 | public function __construct()
30 | {
31 | $this->hint = 'Commit message can not be empty';
32 | }
33 |
34 | /**
35 | * Check if commit message is not empty
36 | *
37 | * @param \SebastianFeldmann\Git\CommitMessage $msg
38 | * @return bool
39 | */
40 | public function pass(CommitMessage $msg): bool
41 | {
42 | return !$msg->isEmpty();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/NoPeriodOnSubjectEnd.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Class NoPeriodOnSubjectEnd
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class NoPeriodOnSubjectEnd extends Base
25 | {
26 | /**
27 | * Constructor
28 | */
29 | public function __construct()
30 | {
31 | $this->hint = 'Subject should not end with a period';
32 | }
33 |
34 | /**
35 | * Check if commit message doesn't end with a period
36 | *
37 | * @param \SebastianFeldmann\Git\CommitMessage $msg
38 | * @return bool
39 | */
40 | public function pass(CommitMessage $msg): bool
41 | {
42 | return substr(trim($msg->getSubject()), -1) !== '.';
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/SeparateSubjectFromBodyWithBlankLine.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Class SeparateSubjectFromBodyWithBlankLine
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class SeparateSubjectFromBodyWithBlankLine extends Base
25 | {
26 | /**
27 | * Constructor
28 | */
29 | public function __construct()
30 | {
31 | $this->hint = 'Subject and body have to be separated by a blank line';
32 | }
33 |
34 | /**
35 | * Check if subject and body are separated by a blank line
36 | *
37 | * @param \SebastianFeldmann\Git\CommitMessage $msg
38 | * @return bool
39 | */
40 | public function pass(CommitMessage $msg): bool
41 | {
42 | return $msg->getContentLineCount() < 2 || empty($msg->getContentLine(1));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Hook/Message/Rule/UseImperativeMood.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\Rule;
13 |
14 | /**
15 | * Class UseImperativeMood
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 0.9.0
21 | */
22 | class UseImperativeMood extends Blacklist
23 | {
24 | /**
25 | * Constructor
26 | *
27 | * @param bool $checkOnlyBeginning
28 | */
29 | public function __construct(bool $checkOnlyBeginning = false)
30 | {
31 | parent::__construct();
32 |
33 | $this->hint = 'A commit message subject should always complete the following sentence.' . PHP_EOL .
34 | 'This commit will [YOUR COMMIT MESSAGE].';
35 |
36 | $this->setSubjectBlacklist(
37 | [
38 | 'added',
39 | 'changed',
40 | 'created',
41 | 'deleted',
42 | 'fixed',
43 | 'reformatted',
44 | 'removed',
45 | 'updated',
46 | 'uploaded'
47 | ]
48 | );
49 |
50 | if ($checkOnlyBeginning) {
51 | // overwrite the detection logic to only check the beginning og the string
52 | $this->stringDetection = function (string $content, string $term): bool {
53 | return strpos($content, $term) === 0;
54 | };
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Hook/Message/RuleBook.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message;
13 |
14 | use SebastianFeldmann\Git\CommitMessage;
15 |
16 | /**
17 | * Class RuleBook
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | class RuleBook
25 | {
26 | /**
27 | * List of rules to check
28 | *
29 | * @var \CaptainHook\App\Hook\Message\Rule[]
30 | */
31 | private $rules = [];
32 |
33 | /**
34 | * Set rules to check
35 | *
36 | * @param \CaptainHook\App\Hook\Message\Rule[] $rules
37 | * @return \CaptainHook\App\Hook\Message\RuleBook
38 | */
39 | public function setRules(array $rules): RuleBook
40 | {
41 | $this->rules = $rules;
42 | return $this;
43 | }
44 |
45 | /**
46 | * Add a rule to the list
47 | *
48 | * @param \CaptainHook\App\Hook\Message\Rule $rule
49 | * @return \CaptainHook\App\Hook\Message\RuleBook
50 | */
51 | public function addRule(Rule $rule): RuleBook
52 | {
53 | $this->rules[] = $rule;
54 | return $this;
55 | }
56 |
57 | /**
58 | * Validates all rules
59 | *
60 | * Returns a list of problems found checking the commit message.
61 | * If the list is empty the message is valid.
62 | *
63 | * @param \SebastianFeldmann\Git\CommitMessage $msg
64 | * @return array
65 | */
66 | public function validate(CommitMessage $msg): array
67 | {
68 | $problems = [];
69 | foreach ($this->rules as $rule) {
70 | if (!$rule->pass($msg)) {
71 | $problems[] = $rule->getHint();
72 | }
73 | }
74 | return $problems;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Hook/Message/RuleBook/RuleSet.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Message\RuleBook;
13 |
14 | use CaptainHook\App\Hook\Message\Rule;
15 |
16 | /**
17 | * Class RuleSet
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 2.1.0
23 | */
24 | abstract class RuleSet
25 | {
26 | /**
27 | * Return Beams rule set
28 | *
29 | * @param int $subjectLength
30 | * @param int $bodyLineLength
31 | * @param bool $checkImperativeBeginningOnly
32 | * @return \CaptainHook\App\Hook\Message\Rule[]
33 | */
34 | public static function beams(
35 | int $subjectLength = 50,
36 | int $bodyLineLength = 72,
37 | bool $checkImperativeBeginningOnly = false
38 | ): array {
39 | return [
40 | new Rule\CapitalizeSubject(),
41 | new Rule\LimitSubjectLength($subjectLength),
42 | new Rule\NoPeriodOnSubjectEnd(),
43 | new Rule\UseImperativeMood($checkImperativeBeginningOnly),
44 | new Rule\LimitBodyLineLength($bodyLineLength),
45 | new Rule\SeparateSubjectFromBodyWithBlankLine()
46 | ];
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Hook/Notify/Action/IntegrateBeforePush.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Notify\Action;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Exception\ActionFailed;
17 | use CaptainHook\App\Hook\Action;
18 | use CaptainHook\App\Hook\Constrained;
19 | use CaptainHook\App\Hook\Restriction;
20 | use CaptainHook\App\Git\Rev\Util as RevUtil;
21 | use CaptainHook\App\Hooks;
22 | use SebastianFeldmann\Git\Repository;
23 |
24 | /**
25 | * Class IntegrateBeforePush
26 | *
27 | * @package CaptainHook
28 | * @author Sebastian Feldmann
29 | * @link https://github.com/captainhook-git/captainhook
30 | * @since Class available since Release 5.19.1
31 | */
32 | class IntegrateBeforePush implements Action, Constrained
33 | {
34 | /**
35 | * Returns a list of applicable hooks
36 | *
37 | * @return \CaptainHook\App\Hook\Restriction
38 | */
39 | public static function getRestriction(): Restriction
40 | {
41 | return Restriction::fromArray([Hooks::PRE_PUSH]);
42 | }
43 |
44 | /**
45 | * Executes the action
46 | *
47 | * @param \CaptainHook\App\Config $config
48 | * @param \CaptainHook\App\Console\IO $io
49 | * @param \SebastianFeldmann\Git\Repository $repository
50 | * @param \CaptainHook\App\Config\Action $action
51 | * @return void
52 | * @throws \Exception
53 | */
54 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
55 | {
56 | $trigger = $action->getOptions()->get('trigger', '[merge]');
57 | $branchToWatch = $action->getOptions()->get('branch', 'origin/main');
58 | $branchInfo = RevUtil::extractBranchInfo($branchToWatch);
59 |
60 | $repository->getRemoteOperator()->fetchBranch($branchInfo['remote'], $branchInfo['branch']);
61 |
62 | foreach ($repository->getLogOperator()->getCommitsBetween('HEAD', $branchToWatch) as $commit) {
63 | $message = $commit->getSubject() . PHP_EOL . $commit->getBody();
64 | if (str_contains($message, $trigger)) {
65 | throw new ActionFailed('integrate ' . $branchInfo['branch'] . ' before you push!');
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Hook/Notify/Extractor.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\Notify;
13 |
14 | /**
15 | * Class Extractor
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.4.5
21 | */
22 | class Extractor
23 | {
24 | /**
25 | * Find the notification inside a commit message and return a Notification model
26 | *
27 | * @param string $message
28 | * @param string $prefix
29 | * @return \CaptainHook\App\Hook\Notify\Notification
30 | */
31 | public static function extractNotification(string $message, string $prefix = 'git-notify:'): Notification
32 | {
33 | return new Notification(self::getLines($message, $prefix));
34 | }
35 |
36 | /**
37 | * @param string $message
38 | * @param string $prefix
39 | * @return array
40 | */
41 | private static function getLines(string $message, string $prefix): array
42 | {
43 | $matches = [];
44 | if (preg_match('#' . $prefix . '(.*)#is', $message, $matches)) {
45 | $split = preg_split("/\r\n|\n|\r/", $matches[1]);
46 |
47 | return is_array($split) ? array_map('trim', $split) : [];
48 | }
49 | return [];
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Hook/PHP/CoverageResolver.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\PHP;
13 |
14 | /**
15 | * Interface CoverageResolver
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 1.2.0
21 | */
22 | interface CoverageResolver
23 | {
24 | /**
25 | * Return test coverage in percent.
26 | *
27 | * @return int
28 | */
29 | public function getCoverage(): int;
30 | }
31 |
--------------------------------------------------------------------------------
/src/Hook/PHP/CoverageResolver/PHPUnit.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\PHP\CoverageResolver;
13 |
14 | use RuntimeException;
15 | use CaptainHook\App\Hook\PHP\CoverageResolver;
16 | use SebastianFeldmann\Cli\Processor\ProcOpen as Processor;
17 |
18 | /**
19 | * Class PHPUnit
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 1.2.0
25 | */
26 | class PHPUnit implements CoverageResolver
27 | {
28 | /**
29 | * Path to phpunit
30 | *
31 | * @var string
32 | */
33 | private $phpUnit;
34 |
35 | /**
36 | * PHPUnit constructor.
37 | *
38 | * @param string $pathToPHPUnit
39 | */
40 | public function __construct(string $pathToPHPUnit)
41 | {
42 | $this->phpUnit = $pathToPHPUnit;
43 | }
44 |
45 | /**
46 | * Run PHPUnit to calculate code coverage.
47 | * Shamelessly ripped from bruli/php-git-hooks.
48 | *
49 | * @author Pablo Braulio
50 | * @return int
51 | */
52 | public function getCoverage(): int
53 | {
54 | $processor = new Processor();
55 | $result = $processor->run($this->phpUnit . ' --coverage-text|grep Classes|cut -d " " -f 4|cut -d "%" -f 1');
56 | $output = $result->getStdOut();
57 | if (!$result->isSuccessful() || empty($output)) {
58 | throw new RuntimeException('Error while executing PHPUnit: ' . $result->getStdErr());
59 | }
60 | return (int) ceil((float) $output);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Hook/Template.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook;
13 |
14 | /**
15 | * Template interface
16 | *
17 | * Templates generate the hook sourcecode to place in .git/hooks/* to execute CaptainHook.
18 | * There are 3 types of templates:
19 | * - SHELL Writes a shell script, this is the recommended way for all unix or linux based systems.
20 | * - PHP Writes a PHP script, this is useful if you are running windows and shell scripts aren't an option.
21 | * - DOCKER Writes a shell script that executes captainhook inside a docker container. This is useful if you
22 | * don't want to install PHP locally.
23 | *
24 | * @package CaptainHook
25 | * @author Sebastian Feldmann
26 | * @link https://github.com/captainhook-git/captainhook
27 | * @since Class available since Release 4.3.0
28 | */
29 | interface Template
30 | {
31 | public const SHELL = 'shell';
32 | public const PHP = 'php';
33 | public const DOCKER = 'docker';
34 | public const WSL = 'wsl';
35 |
36 | /**
37 | * Return the code for the git hook scripts
38 | *
39 | * @param string $hook Name of the hook to generate the sourcecode for
40 | * @return string
41 | */
42 | public function getCode(string $hook): string;
43 | }
44 |
--------------------------------------------------------------------------------
/src/Hook/Template/Builder.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Template;
15 |
16 | use CaptainHook\App\Config;
17 | use CaptainHook\App\Console\Runtime\Resolver;
18 | use CaptainHook\App\Hook\Template;
19 | use CaptainHook\App\Hook\Template\Local\PHP;
20 | use CaptainHook\App\Hook\Template\Local\Shell;
21 | use CaptainHook\App\Hook\Template\Local\WSL;
22 | use CaptainHook\App\Runner\Bootstrap\Util;
23 | use RuntimeException;
24 | use SebastianFeldmann\Git\Repository;
25 |
26 | /**
27 | * Builder class
28 | *
29 | * Creates git hook Template objects regarding some provided input.
30 | *
31 | * @package CaptainHook
32 | * @author Sebastian Feldmann
33 | * @link https://github.com/captainhook-git/captainhook
34 | * @since Class available since Release 4.3.0
35 | */
36 | abstract class Builder
37 | {
38 | /**
39 | * Creates a template that is responsible for the git hook sourcecode
40 | *
41 | * @param \CaptainHook\App\Config $config
42 | * @param \SebastianFeldmann\Git\Repository $repository
43 | * @param \CaptainHook\App\Console\Runtime\Resolver $resolver
44 | * @return \CaptainHook\App\Hook\Template
45 | */
46 | public static function build(Config $config, Repository $repository, Resolver $resolver): Template
47 | {
48 | $pathInfo = new PathInfo(
49 | $repository->getRoot(),
50 | $config->getPath(),
51 | $resolver->getExecutable(),
52 | $resolver->isPharRelease()
53 | );
54 | Util::validateBootstrapPath($resolver->isPharRelease(), $config);
55 |
56 | switch ($config->getRunConfig()->getMode()) {
57 | case Template::DOCKER:
58 | return new Docker($pathInfo, $config);
59 | case Template::PHP:
60 | return new PHP($pathInfo, $config);
61 | case Template::WSL:
62 | return new WSL($pathInfo, $config);
63 | default:
64 | return new Shell($pathInfo, $config);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Hook/Template/Local.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Template;
15 |
16 | use CaptainHook\App\Config;
17 | use CaptainHook\App\Hook\Template;
18 | use CaptainHook\App\Runner\Bootstrap\Util;
19 |
20 | abstract class Local implements Template
21 | {
22 | /**
23 | * All template related path information
24 | *
25 | * @var \CaptainHook\App\Hook\Template\PathInfo
26 | */
27 | protected PathInfo $pathInfo;
28 |
29 | /**
30 | * CaptainHook configuration
31 | *
32 | * @var \CaptainHook\App\Config
33 | */
34 | protected Config $config;
35 |
36 | /**
37 | * Local constructor
38 | *
39 | * @param \CaptainHook\App\Hook\Template\PathInfo $pathInfo
40 | * @param \CaptainHook\App\Config $config
41 | */
42 | public function __construct(PathInfo $pathInfo, Config $config)
43 | {
44 | $this->pathInfo = $pathInfo;
45 | $this->config = $config;
46 | }
47 |
48 | /**
49 | * Return the code for the git hook scripts
50 | *
51 | * @param string $hook Name of the hook to generate the sourcecode for
52 | * @return string
53 | */
54 | public function getCode(string $hook): string
55 | {
56 | return implode(PHP_EOL, $this->getHookLines($hook)) . PHP_EOL;
57 | }
58 |
59 | /**
60 | * Returns the bootstrap option depending on the current runtime (can be empty)
61 | *
62 | * @return string
63 | */
64 | public function getBootstrapCmdOption(): string
65 | {
66 | return Util::bootstrapCmdOption($this->pathInfo->isPhar(), $this->config);
67 | }
68 |
69 | /**
70 | * Return the code for the git hook scripts
71 | *
72 | * @param string $hook Name of the hook to generate the sourcecode for
73 | * @return array
74 | */
75 | abstract protected function getHookLines(string $hook): array;
76 | }
77 |
--------------------------------------------------------------------------------
/src/Hook/Template/Local/WSL.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace CaptainHook\App\Hook\Template\Local;
15 |
16 | /**
17 | * WSL class
18 | *
19 | * Generates the sourcecode for the php hook scripts in .git/hooks/*.
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @author Christoph Kappestein
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.23.0
26 | */
27 | class WSL extends Shell
28 | {
29 | protected function getExecutable(): string
30 | {
31 | return 'wsl.exe ' . parent::getExecutable();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Hook/UserInput/AskConfirmation.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\UserInput;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Hook\Action;
17 | use CaptainHook\App\Hook\EventSubscriber;
18 | use SebastianFeldmann\Git\Repository;
19 |
20 | /**
21 | * Debug hook to test hook triggering that fails the hook execution
22 | *
23 | * @package CaptainHook
24 | * @author Sebastian Feldmann
25 | * @link https://github.com/captainhook-git/captainhook
26 | * @since Class available since Release 5.20.1
27 | */
28 | class AskConfirmation implements Action, EventSubscriber
29 | {
30 | /**
31 | * Default question to ask the user
32 | *
33 | * @var string
34 | */
35 | private static string $defaultMessage = 'Do you want to continue? [yes|no]';
36 |
37 | /**
38 | * Executes the action
39 | *
40 | * @param \CaptainHook\App\Config $config
41 | * @param \CaptainHook\App\Console\IO $io
42 | * @param \SebastianFeldmann\Git\Repository $repository
43 | * @param \CaptainHook\App\Config\Action $action
44 | * @return void
45 | * @throws \Exception
46 | */
47 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void
48 | {
49 | // this action is just registering some event handler, so nothing to see here
50 | }
51 |
52 | /**
53 | * Returns a list of event handlers
54 | *
55 | * @param \CaptainHook\App\Config\Action $action
56 | * @return array>
57 | * @throws \Exception
58 | */
59 | public static function getEventHandlers(Config\Action $action): array
60 | {
61 | $msg = $action->getOptions()->get('message', self::$defaultMessage);
62 | $default = (bool) $action->getOptions()->get('default', false);
63 | return [
64 | 'onHookSuccess' => [new EventHandler\AskConfirmation($msg, $default)]
65 | ];
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Hook/UserInput/EventHandler/AskConfirmation.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Hook\UserInput\EventHandler;
13 |
14 | use CaptainHook\App\Console\IOUtil;
15 | use CaptainHook\App\Event;
16 | use CaptainHook\App\Event\Handler;
17 | use CaptainHook\App\Exception\ActionFailed;
18 |
19 | /**
20 | * Writes to commit message cache file to load it for a later commit
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.11.0
26 | */
27 | class AskConfirmation implements Handler
28 | {
29 | /**
30 | * Question to ask
31 | *
32 | * @var string
33 | */
34 | private string $question;
35 |
36 | /**
37 | * No input ok or not
38 | *
39 | * @var bool
40 | */
41 | private bool $default;
42 |
43 | /**
44 | * @param string $question
45 | * @param bool $default
46 | */
47 | public function __construct(string $question, bool $default = false)
48 | {
49 | $this->question = $question;
50 | $this->default = $default;
51 | }
52 |
53 | /**
54 | * Writes the commit message to a cache file to reuse it for the next commit
55 | *
56 | * @param \CaptainHook\App\Event $event
57 | * @return void
58 | * @throws \CaptainHook\App\Exception\ActionFailed
59 | */
60 | public function handle(Event $event): void
61 | {
62 | if (!IOUtil::answerToBool($event->io()->ask(PHP_EOL . $this->question . ' ', $this->default ? 'y' : 'n'))) {
63 | throw new ActionFailed('no confirmation, abort!');
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Plugin/CaptainHook.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Plugin;
13 |
14 | /**
15 | * CaptainHook plugin interface
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.9.0.
21 | */
22 | interface CaptainHook
23 | {
24 | }
25 |
--------------------------------------------------------------------------------
/src/Plugin/Hook.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Plugin;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Runner\Hook as RunnerHook;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Runner plugin interface
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.9.0.
26 | */
27 | interface Hook extends CaptainHook
28 | {
29 | /**
30 | * Configure the runner plugin.
31 | *
32 | * @param Config $config
33 | * @param IO $io
34 | * @param Repository $repository
35 | * @param Config\Plugin $plugin
36 | * @return void
37 | */
38 | public function configure(Config $config, IO $io, Repository $repository, Config\Plugin $plugin): void;
39 |
40 | /**
41 | * Execute before all actions
42 | *
43 | * @param RunnerHook $hook
44 | * @return void
45 | */
46 | public function beforeHook(RunnerHook $hook): void;
47 |
48 | /**
49 | * Execute before each action
50 | *
51 | * @param RunnerHook $hook
52 | * @param Config\Action $action
53 | * @return void
54 | */
55 | public function beforeAction(RunnerHook $hook, Config\Action $action): void;
56 |
57 | /**
58 | * Execute after each action
59 | *
60 | * @param RunnerHook $hook
61 | * @param Config\Action $action
62 | * @return void
63 | */
64 | public function afterAction(RunnerHook $hook, Config\Action $action): void;
65 |
66 | /**
67 | * Execute after all actions
68 | *
69 | * @param RunnerHook $hook
70 | * @return void
71 | */
72 | public function afterHook(RunnerHook $hook): void;
73 | }
74 |
--------------------------------------------------------------------------------
/src/Plugin/Hook/Base.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Plugin\Hook;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Plugin;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Base runner plugin abstract class
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.9.0.
26 | */
27 | abstract class Base implements Plugin\Hook
28 | {
29 | /**
30 | * @var Config
31 | */
32 | protected $config;
33 |
34 | /**
35 | * @var IO
36 | */
37 | protected $io;
38 |
39 | /**
40 | * @var Repository
41 | */
42 | protected $repository;
43 |
44 | /**
45 | * @var Config\Plugin
46 | */
47 | protected $plugin;
48 |
49 | public function configure(Config $config, IO $io, Repository $repository, Config\Plugin $plugin): void
50 | {
51 | $this->config = $config;
52 | $this->io = $io;
53 | $this->repository = $repository;
54 | $this->plugin = $plugin;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Runner.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App;
13 |
14 | use CaptainHook\App\Console\IO;
15 |
16 | /**
17 | * Class Runner
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 0.9.0
23 | */
24 | abstract class Runner
25 | {
26 | /**
27 | * @var \CaptainHook\App\Console\IO
28 | */
29 | protected $io;
30 |
31 | /**
32 | * @var \CaptainHook\App\Config
33 | */
34 | protected $config;
35 |
36 | /**
37 | * Installer constructor.
38 | *
39 | * @param \CaptainHook\App\Console\IO $io
40 | * @param \CaptainHook\App\Config $config
41 | */
42 | public function __construct(IO $io, Config $config)
43 | {
44 | $this->io = $io;
45 | $this->config = $config;
46 | }
47 |
48 | /**
49 | * Executes the Runner.
50 | */
51 | abstract public function run(): void;
52 | }
53 |
--------------------------------------------------------------------------------
/src/Runner/Action.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use SebastianFeldmann\Git\Repository;
17 |
18 | /**
19 | * Interface Action
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 5.19.0
25 | */
26 | interface Action
27 | {
28 | /**
29 | * Executes the action
30 | *
31 | * @param \CaptainHook\App\Config $config
32 | * @param \CaptainHook\App\Console\IO $io
33 | * @param \SebastianFeldmann\Git\Repository $repository
34 | * @param \CaptainHook\App\Config\Action $action
35 | * @return void
36 | * @throws \Exception
37 | */
38 | public function execute(Config $config, IO $io, Repository $repository, Config\Action $action): void;
39 | }
40 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use SebastianFeldmann\Git\Repository;
17 |
18 | /**
19 | * Interface Placeholder
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 5.0.0
25 | */
26 | interface Placeholder
27 | {
28 | /**
29 | * Placeholder constructor
30 | *
31 | * @param \CaptainHook\App\Console\IO $io
32 | * @param \CaptainHook\App\Config $config
33 | * @param \SebastianFeldmann\Git\Repository $repository
34 | */
35 | public function __construct(IO $io, Config $config, Repository $repository);
36 |
37 | /**
38 | * Return the replacement value for this placeholder
39 | *
40 | * @param array $options
41 | * @return string
42 | */
43 | public function replacement(array $options): string;
44 | }
45 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/Arg.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | /**
15 | * Class Arg
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.19.0
21 | */
22 | class Arg extends Foundation
23 | {
24 | /**
25 | * Return the requested command ARGUMENT or a given default, returns empty string by default
26 | *
27 | * @param array $options
28 | * @return string
29 | */
30 | public function replacement(array $options): string
31 | {
32 | $var = $options['value-of'] ?? '_';
33 | $default = $options['default'] ?? '';
34 |
35 | return $this->io->getArgument(self::toArgument($var), $default);
36 | }
37 |
38 | /**
39 | * Converts an argument name to a placeholder string
40 | *
41 | * @param string $arg
42 | * @return string
43 | */
44 | public static function toPlaceholder(string $arg): string
45 | {
46 | return str_replace('-', '_', strtoupper($arg));
47 | }
48 |
49 | /**
50 | * Converts a placeholder string to an argument name
51 | *
52 | * @param string $placeholder
53 | * @return string
54 | */
55 | public static function toArgument(string $placeholder): string
56 | {
57 | return str_replace('_', '-', strtolower($placeholder));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/BranchFiles.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | use CaptainHook\App\Git;
15 | use CaptainHook\App\Hook\FileList;
16 |
17 | /**
18 | * Changed Files Placeholder
19 | *
20 | * This placeholder only works for pre-push, post-rewrite, post-checkout and post-merge actions.
21 | * If it is used in a pre-push hook and multiple refs are pushed the placeholder will contain
22 | * all changed files for all refs.
23 | *
24 | * Usage examples:
25 | * - {$BRANCH_FILES|compare-to:main|separated-by:,}
26 | * - {$BRANCH_FILES|in-dir:foo/bar}
27 | * - {$BRANCH_FILES|of-type:php}
28 | *
29 | * @package CaptainHook
30 | * @author Sebastian Feldmann
31 | * @link https://github.com/captainhook-git/captainhook
32 | * @since Class available since Release 5.21.0
33 | */
34 | class BranchFiles extends Foundation
35 | {
36 | /**
37 | * @param array $options
38 | * @return string
39 | */
40 | public function replacement(array $options): string
41 | {
42 | $branch = $this->repository->getInfoOperator()->getCurrentBranch();
43 | $start = $options['compared-to'] ?? $this->repository->getLogOperator()->getBranchRevFromRefLog($branch);
44 |
45 | if (empty($start)) {
46 | $this->io->write('could not find branch start');
47 | return '';
48 | }
49 | $files = $this->repository->getLogOperator()->getChangedFilesSince($start, ['A', 'C', 'M', 'R']);
50 |
51 | return implode(($options['separated-by'] ?? ' '), FileList::filter($files, $options));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/ChangedFiles.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | use CaptainHook\App\Git;
15 | use CaptainHook\App\Hook\FileList;
16 |
17 | /**
18 | * Changed Files Placeholder
19 | *
20 | * This placeholder only works for pre-push, post-rewrite, post-checkout and post-merge actions.
21 | * If it is used in a pre-push hook and multiple refs are pushed the placeholder will contain
22 | * all changed files for all refs.
23 | *
24 | * Usage examples:
25 | * - {$CHANGED_FILES|separated-by:,}
26 | * - {$CHANGED_FILES|in-dir:foo/bar}
27 | * - {$CHANGED_FILES|of-type:php}
28 | *
29 | * @package CaptainHook
30 | * @author Sebastian Feldmann
31 | * @link https://github.com/captainhook-git/captainhook
32 | * @since Class available since Release 5.15.3
33 | */
34 | class ChangedFiles extends Foundation
35 | {
36 | /**
37 | * @param array $options
38 | * @return string
39 | */
40 | public function replacement(array $options): string
41 | {
42 | $factory = new Git\ChangedFiles\Detector\Factory();
43 | $detector = $factory->getDetector($this->io, $this->repository);
44 |
45 | $files = $detector->getChangedFiles(['A', 'C', 'M', 'R']);
46 |
47 | return implode(($options['separated-by'] ?? ' '), FileList::filter($files, $options));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/Config.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | /**
15 | * Class Config
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.6.0
21 | */
22 | class Config extends Foundation
23 | {
24 | /**
25 | * Maps the config value names to actual methods that have to be called to retrieve the value
26 | *
27 | * @var array
28 | */
29 | private $valueToMethod = [
30 | 'bootstrap' => 'getBootstrap',
31 | 'git-directory' => 'getGitDirectory',
32 | 'php-path' => 'getPhpPath',
33 | ];
34 |
35 | /**
36 | * @param array $options
37 | * @return string
38 | */
39 | public function replacement(array $options): string
40 | {
41 | if (!isset($options['value-of'])) {
42 | return '';
43 | }
44 |
45 | return $this->getConfigValueFor($options['value-of']);
46 | }
47 |
48 | /**
49 | * Returns the config value '' by default if value is unknown
50 | *
51 | * @param string $value
52 | * @return string
53 | */
54 | private function getConfigValueFor(string $value): string
55 | {
56 | if (strpos($value, 'custom>>') === 0) {
57 | $key = substr($value, 8);
58 | $custom = $this->config->getCustomSettings();
59 | return $custom[$key] ?? '';
60 | }
61 | if (!isset($this->valueToMethod[$value])) {
62 | return '';
63 | }
64 |
65 | $method = $this->valueToMethod[$value];
66 | return $this->config->$method();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/Env.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | /**
15 | * Class Env
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.8.0
21 | */
22 | class Env extends Foundation
23 | {
24 | /**
25 | * Return the requested ENVIRONMENT variable or a given default, returns empty string by default
26 | *
27 | * @param array $options
28 | * @return string
29 | */
30 | public function replacement(array $options): string
31 | {
32 | if (!isset($options['value-of'])) {
33 | return '';
34 | }
35 |
36 | $var = $options['value-of'];
37 | $default = $options['default'] ?? '';
38 |
39 | return (string) ($_ENV[$var] ?? $default);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/Foundation.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Runner\Action\Cli\Command\Placeholder as PlaceholderInterface;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Class Foundation
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 5.6.0
26 | */
27 | abstract class Foundation implements PlaceholderInterface
28 | {
29 | /**
30 | * Input Output handler
31 | *
32 | * @var \CaptainHook\App\Console\IO
33 | */
34 | protected IO $io;
35 |
36 | /**
37 | * CaptainHook configuration
38 | *
39 | * @var \CaptainHook\App\Config
40 | */
41 | protected Config $config;
42 |
43 | /**
44 | * Git repository
45 | *
46 | * @var \SebastianFeldmann\Git\Repository
47 | */
48 | protected Repository $repository;
49 |
50 | /**
51 | * StagedFile constructor
52 | *
53 | * @param \CaptainHook\App\Console\IO $io
54 | * @param \CaptainHook\App\Config $config
55 | * @param \SebastianFeldmann\Git\Repository $repository
56 | */
57 | public function __construct(IO $io, Config $config, Repository $repository)
58 | {
59 | $this->io = $io;
60 | $this->config = $config;
61 | $this->repository = $repository;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/StagedFiles.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | use CaptainHook\App\Hook\FileList;
15 |
16 | /**
17 | * Class UpdatedFiles
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 5.0.0
23 | */
24 | class StagedFiles extends Foundation
25 | {
26 | /**
27 | * @param array $options
28 | * @return string
29 | */
30 | public function replacement(array $options): string
31 | {
32 | $filter = isset($options['diff-filter']) ? str_split($options['diff-filter']) : ['A', 'C', 'M', 'R'];
33 | $files = isset($options['of-type'])
34 | ? $this->repository->getIndexOperator()->getStagedFilesOfType($options['of-type'], $filter)
35 | : $this->repository->getIndexOperator()->getStagedFiles($filter);
36 |
37 | $files = FileList::filterByDirectory($files, $options);
38 | $files = FileList::replaceInAll($files, $options);
39 |
40 | return implode(($options['separated-by'] ?? ' '), $files);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Runner/Action/Cli/Command/Placeholder/StdIn.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13 |
14 | /**
15 | * Class StdIn
16 | *
17 | * @package CaptainHook
18 | * @author Sebastian Feldmann
19 | * @link https://github.com/captainhook-git/captainhook
20 | * @since Class available since Release 5.23.5
21 | */
22 | class StdIn extends Foundation
23 | {
24 | /**
25 | * Return the original hook stdIn (shell escaped)
26 | *
27 | * Returns at least ''
28 | *
29 | * @param array $options
30 | * @return string
31 | */
32 | public function replacement(array $options): string
33 | {
34 | return escapeshellarg(implode(PHP_EOL, $this->io->getStandardInput()));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Runner/Bootstrap/Util.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Bootstrap;
13 |
14 | use CaptainHook\App\Config;
15 | use RuntimeException;
16 |
17 | /**
18 | * Bootstrap Util
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 5.23.3
24 | */
25 | class Util
26 | {
27 | /**
28 | * Return the bootstrap file to load (can be empty)
29 | *
30 | * @param bool $isPhar
31 | * @param \CaptainHook\App\Config $config
32 | * @return string
33 | */
34 | public static function validateBootstrapPath(bool $isPhar, Config $config): string
35 | {
36 | $bootstrapFile = dirname($config->getPath()) . '/' . $config->getBootstrap();
37 | if (!file_exists($bootstrapFile)) {
38 | // since the phar has its own autoloader we don't need to do anything
39 | // if the bootstrap file is not actively set
40 | if ($isPhar && empty($config->getBootstrap(''))) {
41 | return '';
42 | }
43 | throw new RuntimeException('bootstrap file not found');
44 | }
45 | return $bootstrapFile;
46 | }
47 |
48 | /**
49 | * Returns the bootstrap command option (can be empty)
50 | *
51 | * @param bool $isPhar
52 | * @param \CaptainHook\App\Config $config
53 | * @return string
54 | */
55 | public static function bootstrapCmdOption(bool $isPhar, Config $config): string
56 | {
57 | // nothing to load => no option
58 | if ($isPhar && empty($config->getBootstrap(''))) {
59 | return '';
60 | }
61 | return ' --bootstrap=' . $config->getBootstrap();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Runner/Config/Change.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Config\Change;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Runner\Config\Setup\Advanced;
16 |
17 | /**
18 | * Class AddAction
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 4.2.0
24 | */
25 | class AddAction extends Hook
26 | {
27 | /**
28 | * Apply changes to the given config
29 | *
30 | * @param \CaptainHook\App\Config $config
31 | * @return void
32 | * @throws \Exception
33 | */
34 | public function applyTo(Config $config): void
35 | {
36 | $hookConfig = $config->getHookConfig($this->hookToChange);
37 | $setup = new Advanced($this->io);
38 | $actionConfig = $setup->getActionConfig();
39 |
40 | $hookConfig->addAction($actionConfig);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Runner/Config/Change/DisableHook.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Config\Change;
13 |
14 | use CaptainHook\App\Config;
15 |
16 | /**
17 | * Class AddAction
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 4.2.0
23 | */
24 | class DisableHook extends Hook
25 | {
26 | /**
27 | * Apply changes to the given config
28 | *
29 | * @param \CaptainHook\App\Config $config
30 | * @return void
31 | * @throws \Exception
32 | */
33 | public function applyTo(Config $config): void
34 | {
35 | $config->getHookConfig($this->hookToChange)->setEnabled(false);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Runner/Config/Change/EnableHook.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Config\Change;
13 |
14 | use CaptainHook\App\Config;
15 |
16 | /**
17 | * Class AddAction
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 4.2.0
23 | */
24 | class EnableHook extends Hook
25 | {
26 | /**
27 | * Apply changes to the given config
28 | *
29 | * @param \CaptainHook\App\Config $config
30 | * @return void
31 | * @throws \Exception
32 | */
33 | public function applyTo(Config $config): void
34 | {
35 | $config->getHookConfig($this->hookToChange)->setEnabled(true);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Runner/Config/Change/Hook.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Config\Change;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Runner\Config\Change;
17 |
18 | /**
19 | * Class AddAction
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 4.2.0
25 | */
26 | abstract class Hook implements Change
27 | {
28 | /**
29 | * @var \CaptainHook\App\Console\IO
30 | */
31 | protected $io;
32 |
33 | /**
34 | * Name of the hook to add the action to
35 | *
36 | * @var string
37 | */
38 | protected $hookToChange;
39 |
40 | /**
41 | * AddAction constructor
42 | *
43 | * @param \CaptainHook\App\Console\IO $io
44 | * @param string $hookToChange
45 | */
46 | public function __construct(IO $io, string $hookToChange)
47 | {
48 | $this->io = $io;
49 | $this->hookToChange = $hookToChange;
50 | }
51 |
52 | /**
53 | * Apply changes to the given config
54 | *
55 | * @param \CaptainHook\App\Config $config
56 | * @return void
57 | * @throws \Exception
58 | */
59 | abstract public function applyTo(Config $config): void;
60 | }
61 |
--------------------------------------------------------------------------------
/src/Runner/Config/Setup.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Config;
13 |
14 | use CaptainHook\App\Config;
15 |
16 | /**
17 | * Interface Setup
18 | *
19 | * @package CaptainHook
20 | * @author Sebastian Feldmann
21 | * @link https://github.com/captainhook-git/captainhook
22 | * @since Class available since Release 2.1.3
23 | */
24 | interface Setup
25 | {
26 | /**
27 | * Setup hook configurations by asking some questions
28 | *
29 | * @param \CaptainHook\App\Config $config
30 | * @return void
31 | */
32 | public function configureHooks(Config $config): void;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Runner/Config/Setup/Guided.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Config\Setup;
13 |
14 | use CaptainHook\App\Console\IO;
15 | use Exception;
16 |
17 | /**
18 | * Class Guided
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 2.2.0
24 | */
25 | abstract class Guided
26 | {
27 | /**
28 | * @var \CaptainHook\App\Console\IO
29 | */
30 | protected $io;
31 |
32 | /**
33 | * Guided constructor
34 | *
35 | * @param \CaptainHook\App\Console\IO $io
36 | */
37 | public function __construct(IO $io)
38 | {
39 | $this->io = $io;
40 | }
41 |
42 | /**
43 | * PHP action option validation
44 | *
45 | * @param string $option
46 | * @return string
47 | * @throws \Exception
48 | */
49 | public static function isPHPActionOptionValid(string $option): string
50 | {
51 | if (count(explode(':', $option)) !== 2) {
52 | throw new Exception('Invalid option, use "key:value"');
53 | }
54 | return $option;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Runner/Hook/Arg.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Exception\InvalidHookName;
15 |
16 | /**
17 | * Hook argument for lots of commands
18 | *
19 | * - install pre-push,pre-commit
20 | * - info commit-message
21 | */
22 | class Arg
23 | {
24 | /**
25 | * List of hooks
26 | *
27 | * @var array
28 | */
29 | private array $hooks = [];
30 |
31 | /**
32 | * @param string $hook
33 | * @param callable $hookValidation
34 | * @throws \CaptainHook\App\Exception\InvalidHookName
35 | */
36 | public function __construct(string $hook, callable $hookValidation)
37 | {
38 | if (empty($hook)) {
39 | return;
40 | }
41 |
42 | /** @var array $hooks */
43 | $hooks = explode(',', $hook);
44 | $hooks = array_map('trim', $hooks);
45 |
46 | if (!empty(($invalidHooks = array_filter($hooks, $hookValidation)))) {
47 | throw new InvalidHookName(
48 | 'Invalid hook name \'' . implode('\', \'', $invalidHooks) . '\''
49 | );
50 | }
51 | $this->hooks = $hooks;
52 | }
53 |
54 | /**
55 | * Return the list of hooks provided as an argument
56 | *
57 | * @return array
58 | */
59 | public function hooks(): array
60 | {
61 | return $this->hooks;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Runner/Hook/CommitMsg.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Hooks;
15 | use CaptainHook\App\Runner\Hook;
16 | use SebastianFeldmann\Git;
17 |
18 | /**
19 | * CommitMsg
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 3.1.0
25 | */
26 | class CommitMsg extends Hook
27 | {
28 | /**
29 | * Hook to execute
30 | *
31 | * @var string
32 | */
33 | protected $hook = Hooks::COMMIT_MSG;
34 |
35 | /**
36 | * Read the commit message from file
37 | */
38 | public function beforeHook(): void
39 | {
40 | $commentChar = $this->repository->getConfigOperator()->getSettingSafely('core.commentchar', '#');
41 | $commitMsg = Git\CommitMessage::createFromFile(
42 | $this->io->getArgument(Hooks::ARG_MESSAGE_FILE, ''),
43 | $commentChar
44 | );
45 |
46 | $this->repository->setCommitMsg($commitMsg);
47 |
48 | parent::beforeHook();
49 | }
50 |
51 | /**
52 | * Makes sure we do not run commit message validation for fixup commits
53 | *
54 | * @return void
55 | * @throws \Exception
56 | */
57 | protected function runHook(): void
58 | {
59 | $msg = $this->repository->getCommitMsg();
60 | if ($msg->isFixup()) {
61 | $this->io->write(' - no commit message validation for fixup commits: skipping all actions');
62 | return;
63 | }
64 | parent::runHook();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Runner/Hook/Log.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Runner\Action\Log as ActionLog;
15 |
16 | class Log
17 | {
18 | /**
19 | * List if all Action Logs
20 | *
21 | * @var array<\CaptainHook\App\Runner\Action\Log>
22 | */
23 | private array $logs = [];
24 |
25 | /**
26 | * Adds an action log to the hook log
27 | *
28 | * @param \CaptainHook\App\Runner\Action\Log $actionLog
29 | * @return void
30 | */
31 | public function addActionLog(ActionLog $actionLog): void
32 | {
33 | $this->logs[] = $actionLog;
34 | }
35 |
36 | /**
37 | * Checks if any of the collected action logs has a message to display
38 | *
39 | * @param int $verbosity
40 | * @return bool
41 | */
42 | public function hasMessageForVerbosity(int $verbosity): bool
43 | {
44 | foreach ($this->logs as $actionLog) {
45 | if ($actionLog->hasMessageForVerbosity($verbosity)) {
46 | return true;
47 | }
48 | }
49 | return false;
50 | }
51 |
52 | /**
53 | * Returns all collected action logs
54 | *
55 | * @return array<\CaptainHook\App\Runner\Action\Log>
56 | */
57 | public function logs(): array
58 | {
59 | return $this->logs;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Runner/Hook/PostCheckout.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Hooks;
15 | use CaptainHook\App\Runner\Hook;
16 |
17 | /**
18 | * Hook
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 4.1.0
24 | */
25 | class PostCheckout extends Hook
26 | {
27 | /**
28 | * Hook to execute
29 | *
30 | * @var string
31 | */
32 | protected $hook = Hooks::POST_CHECKOUT;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Runner/Hook/PostCommit.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Hooks;
15 | use CaptainHook\App\Runner\Hook;
16 |
17 | /**
18 | * Hook
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 3.1.0
24 | */
25 | class PostCommit extends Hook
26 | {
27 | /**
28 | * Hook to execute
29 | *
30 | * @var string
31 | */
32 | protected $hook = Hooks::POST_COMMIT;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Runner/Hook/PostMerge.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Hooks;
15 | use CaptainHook\App\Runner\Hook;
16 |
17 | /**
18 | * Hook
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 3.1.0
24 | */
25 | class PostMerge extends Hook
26 | {
27 | /**
28 | * Hook to execute
29 | *
30 | * @var string
31 | */
32 | protected $hook = Hooks::POST_MERGE;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Runner/Hook/PostRewrite.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Hooks;
15 | use CaptainHook\App\Runner\Hook;
16 |
17 | /**
18 | * Hook
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 5.4.0
24 | */
25 | class PostRewrite extends Hook
26 | {
27 | /**
28 | * Hook to execute
29 | *
30 | * @var string
31 | */
32 | protected $hook = Hooks::POST_REWRITE;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Runner/Hook/PreCommit.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Hooks;
15 | use CaptainHook\App\Runner\Hook;
16 |
17 | /**
18 | * Hook
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 3.1.0
24 | */
25 | class PreCommit extends Hook
26 | {
27 | /**
28 | * Hook to execute
29 | *
30 | * @var string
31 | */
32 | protected $hook = Hooks::PRE_COMMIT;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Runner/Hook/PrePush.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner\Hook;
13 |
14 | use CaptainHook\App\Hooks;
15 | use CaptainHook\App\Runner\Hook;
16 |
17 | /**
18 | * Hook
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 3.1.0
24 | */
25 | class PrePush extends Hook
26 | {
27 | /**
28 | * Hook to execute
29 | *
30 | * @var string
31 | */
32 | protected $hook = Hooks::PRE_PUSH;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Runner/RepositoryAware.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner;
13 |
14 | use CaptainHook\App\Config;
15 | use CaptainHook\App\Console\IO;
16 | use CaptainHook\App\Runner;
17 | use SebastianFeldmann\Git\Repository;
18 |
19 | /**
20 | * Class HookHandler
21 | *
22 | * @package CaptainHook
23 | * @author Sebastian Feldmann
24 | * @link https://github.com/captainhook-git/captainhook
25 | * @since Class available since Release 0.9.0
26 | */
27 | abstract class RepositoryAware extends Runner
28 | {
29 | /**
30 | * Git repository.
31 | *
32 | * @var \SebastianFeldmann\Git\Repository
33 | */
34 | protected $repository;
35 |
36 | /**
37 | * HookHandler constructor.
38 | *
39 | * @param \CaptainHook\App\Console\IO $io
40 | * @param \CaptainHook\App\Config $config
41 | * @param \SebastianFeldmann\Git\Repository $repository
42 | */
43 | public function __construct(IO $io, Config $config, Repository $repository)
44 | {
45 | parent::__construct($io, $config);
46 | $this->repository = $repository;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Runner/Util.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Runner;
13 |
14 | /**
15 | * Class Util
16 | *
17 | * @package CaptainHook\App\Runner
18 | */
19 | final class Util
20 | {
21 | /**
22 | * List of valid action types
23 | *
24 | * @var array
25 | */
26 | private static $validTypes = ['php' => true, 'cli' => true];
27 |
28 |
29 | /**
30 | * Check the validity of a exec type
31 | *
32 | * @param string $type
33 | * @return bool
34 | */
35 | public static function isTypeValid(string $type): bool
36 | {
37 | return isset(self::$validTypes[$type]);
38 | }
39 |
40 | /**
41 | * Return action type
42 | *
43 | * @param string $action
44 | * @return string
45 | */
46 | public static function getExecType(string $action): string
47 | {
48 | return substr($action, 0, 1) === '\\' ? 'php' : 'cli';
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Storage/File/Json.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Storage\File;
13 |
14 | use CaptainHook\App\Storage\File;
15 | use RuntimeException;
16 | use stdClass;
17 |
18 | /**
19 | * Class Json
20 | *
21 | * @package CaptainHook
22 | * @author Sebastian Feldmann
23 | * @link https://github.com/captainhook-git/captainhook
24 | * @since Class available since Release 0.9.0
25 | */
26 | final class Json extends File
27 | {
28 | /**
29 | * Read and decode the json file
30 | *
31 | * @param bool $assoc
32 | * @return \stdClass|array|null
33 | */
34 | public function read(bool $assoc = false): array|stdClass|null
35 | {
36 | $json = json_decode(parent::read(), $assoc);
37 | if (json_last_error() !== JSON_ERROR_NONE) {
38 | throw new RuntimeException('Invalid json file');
39 | }
40 | return $json;
41 | }
42 |
43 | /**
44 | * Read the file and decode to assoc array
45 | *
46 | * @return array
47 | */
48 | public function readAssoc(): array
49 | {
50 | return (array) ($this->read(true) ?? []);
51 | }
52 |
53 | /**
54 | * Encode content to json and write to disk
55 | *
56 | * @param mixed $content
57 | * @param int $options
58 | * @return void
59 | */
60 | public function write($content, $options = 448): void
61 | {
62 | $json = json_encode($content, $options) . ($options & JSON_PRETTY_PRINT ? "\n" : '');
63 | parent::write($json);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Storage/File/Xml.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace CaptainHook\App\Storage\File;
13 |
14 | use CaptainHook\App\Storage\File;
15 | use RuntimeException;
16 |
17 | /**
18 | * Class Xml
19 | *
20 | * @package CaptainHook
21 | * @author Sebastian Feldmann
22 | * @link https://github.com/captainhook-git/captainhook
23 | * @since Class available since Release 1.2.0
24 | */
25 | final class Xml extends File
26 | {
27 | /**
28 | * Read the xml file and return a SimpleXML object.
29 | *
30 | * @return \SimpleXMLElement
31 | */
32 | public function read()
33 | {
34 | $old = libxml_use_internal_errors(true);
35 | $xml = simplexml_load_file($this->path);
36 | $errors = libxml_get_errors();
37 | libxml_use_internal_errors($old);
38 |
39 | if (count($errors) || $xml === false) {
40 | throw new RuntimeException('xml file \'' . $this->path . '\': ' . $errors[0]->message);
41 | }
42 | return $xml;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------