Passed
Pull Request — master (#99)
by Sebastian
01:56
created

Hook::handleError()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 11
ccs 0
cts 0
cp 0
rs 10
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * This file is part of CaptainHook
5
 *
6
 * (c) Sebastian Feldmann <[email protected]>
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\Config;
15
use CaptainHook\App\Console\IOUtil;
16
use CaptainHook\App\Hook\Util;
17
use Exception;
18
use RuntimeException;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Input\InputOption;
21
use Symfony\Component\Console\Output\OutputInterface;
22
23
/**
24
 * Class Hook
25
 *
26
 * @package CaptainHook
27
 * @author  Sebastian Feldmann <[email protected]>
28
 * @link    https://github.com/captainhookphp/captainhook
29
 * @since   Class available since Release 0.9.0
30
 */
31
abstract class Hook extends RepositoryAware
32
{
33
    /**
34
     * Name of the hook to execute
35
     *
36
     * @var string
37
     */
38
    protected $hookName;
39
40
    /**
41
     * Configure the command
42
     *
43
     * @return void
44
     */
45
    protected function configure(): void
46
    {
47
        parent::configure();
48
        $this->setName('hook:' . $this->hookName)
49
             ->setDescription('Run git ' . $this->hookName . ' hook.')
50
             ->setHelp('This command executes the ' . $this->hookName . ' hook.');
51
52
        $this->addOption(
53
            'bootstrap',
54
            'b',
55
            InputOption::VALUE_OPTIONAL,
56 8
            'Relative path from your config file to your bootstrap file'
57
        );
58 8
    }
59 8
60 8
    /**
61 8
     * Execute the command
62
     *
63
     * @param  \Symfony\Component\Console\Input\InputInterface   $input
64
     * @param  \Symfony\Component\Console\Output\OutputInterface $output
65
     * @return int
66
     * @throws \Exception
67
     */
68 8
    protected function execute(InputInterface $input, OutputInterface $output): int
69
    {
70 8
        $io         = $this->getIO($input, $output);
71 8
        $config     = $this->createConfig($input, true, ['git-directory', 'bootstrap']);
72 8
        $repository = $this->createRepository(dirname($config->getGitDirectory()));
73 8
74
        // if CaptainHook is executed via PHAR we have to make sure to load
75
        $this->handleBootstrap($config);
76
77
        // use ansi coloring only if not disabled in captainhook.json
78
        $output->setDecorated($config->useAnsiColors());
79
        // use the configured verbosity to manage general output verbosity
80
        $output->setVerbosity(IOUtil::mapConfigVerbosity($config->getVerbosity()));
81
82
        $class = '\\CaptainHook\\App\\Runner\\Hook\\' . Util::getHookCommand($this->hookName);
83 8
        /** @var \CaptainHook\App\Runner\Hook $hook */
84
        $hook  = new $class($io, $config, $repository);
85 8
86 8
        try {
87 8
            $hook->run();
88
            return 0;
89
        } catch (Exception $e) {
90 7
            if ($output->isDebug()) {
91
                throw $e;
92 7
            }
93
            return $this->handleError($output, $e);
94
        }
95 7
    }
96 7
97
    /**
98 7
     * Handles the bootstrap file inclusion
99 7
     *
100
     * @param \CaptainHook\App\Config $config
101
     */
102
    private function handleBootstrap(Config $config): void
103
    {
104
        if ($this->resolver->isPharRelease()) {
105
            $bootstrapFile = dirname($config->getPath()) . '/' . $config->getBootstrap();
106
            if (!file_exists($bootstrapFile)) {
107
                throw new RuntimeException('bootstrap file not found');
108
            }
109
            require $bootstrapFile;
110
        }
111
    }
112
113
    /**
114
     * Handle all hook errors
115
     *
116
     * @param  \Symfony\Component\Console\Output\OutputInterface $output
117
     * @param  \Exception                                        $e
118
     * @return int
119
     */
120
    private function handleError(OutputInterface $output, Exception $e): int
121
    {
122
        $error = IOUtil::$tplError
123
               . PHP_EOL . IOUtil::getLineSeparator() . PHP_EOL
124
               . IOUtil::formatHeadline(get_class($e), 80, '>', '<') . PHP_EOL
125
               . IOUtil::getLineSeparator() . PHP_EOL
126
               . $e->getMessage()  . PHP_EOL;
127
128
        $output->writeLn($error);
129
130
        return 1;
131
    }
132
}
133