Completed
Push — master ( c612e7...f3e1c8 )
by Christian
06:23
created

AbstractComposerCommandTask   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
lcom 1
cbo 7
dl 0
loc 102
rs 10
c 1
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
prepareCommand() 0 1 ?
prepareInput() 0 1 ?
A fixCommandDefinition() 0 15 2
A attachComposerFactory() 0 15 2
A executeCommand() 0 10 3
A doPerform() 0 8 1
1
<?php
2
3
/**
4
 * This file is part of tenside/core.
5
 *
6
 * (c) Christian Schiffler <[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
 * This project is provided in good faith and hope to be usable by anyone.
12
 *
13
 * @package    tenside/core
14
 * @author     Christian Schiffler <[email protected]>
15
 * @copyright  2015 Christian Schiffler <[email protected]>
16
 * @license    https://github.com/tenside/core/blob/master/LICENSE MIT
17
 * @link       https://github.com/tenside/core
18
 * @filesource
19
 */
20
21
namespace Tenside\Core\Task\Composer;
22
23
use Composer\Command\Command;
24
use Composer\Factory;
25
use Symfony\Component\Console\Input\InputInterface;
26
use Symfony\Component\Console\Input\InputOption;
27
use Symfony\Component\Console\Output\OutputInterface;
28
use Tenside\Core\Task\Composer\WrappedCommand\WrappedCommandTrait;
29
use Tenside\Core\Task\Task;
30
use Tenside\Core\Task\TaskOutput;
31
32
/**
33
 * This task provides the basic framework for building tasks that perform composer commands.
34
 */
35
abstract class AbstractComposerCommandTask extends Task
36
{
37
    /**
38
     * Prepare the Command instance to execute.
39
     *
40
     * @return Command
41
     */
42
    abstract protected function prepareCommand();
43
44
    /**
45
     * Prepare the input interface for the command.
46
     *
47
     * @return InputInterface
48
     */
49
    abstract protected function prepareInput();
50
51
    /**
52
     * Add missing definition options to the command usually defined by the application.
53
     *
54
     * @param Command $command The command to fix.
55
     *
56
     * @return void
57
     */
58
    protected function fixCommandDefinition(Command $command)
59
    {
60
        $definition = $command->getDefinition();
61
62
        if (!$definition->hasOption('verbose')) {
63
            $definition->addOption(
64
                new InputOption(
65
                    'verbose',
66
                    'v|vv|vvv',
67
                    InputOption::VALUE_NONE,
68
                    'Shows more details including new commits pulled in when updating packages.'
69
                )
70
            );
71
        }
72
    }
73
74
    /**
75
     * Attach the composer factory to the command.
76
     *
77
     * @param Command $command The command to patch.
78
     *
79
     * @return Command
0 ignored issues
show
Documentation introduced by
Should the return type not be WrappedCommandTrait?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
80
     *
81
     * @throws \InvalidArgumentException When no setComposerFactory method is declared.
82
     */
83
    protected function attachComposerFactory(Command $command)
84
    {
85
        if (!method_exists($command, 'setComposerFactory')) {
86
            throw new \InvalidArgumentException('The passed command does not implement method setComposerFactory()');
87
        }
88
89
        /** @var WrappedCommandTrait $command */
90
        $command->setComposerFactory(
91
            function () {
92
                return Factory::create($this->getIO());
93
            }
94
        );
95
96
        return $command;
97
    }
98
99
    /**
100
     * Execute the command and throw exceptions on errors.
101
     *
102
     * @param Command         $command The command to execute.
103
     *
104
     * @param InputInterface  $input   The input to use.
105
     *
106
     * @param OutputInterface $output The output to use.
107
     *
108
     * @return void
109
     *
110
     * @throws \RuntimeException On exceptions or when the command has an non zero exit code.
111
     */
112
    protected function executeCommand(Command $command, InputInterface $input, OutputInterface $output)
113
    {
114
        try {
115
            if (0 !== ($statusCode = $command->run($input, $output))) {
116
                throw new \RuntimeException('Error: command exit code was ' . $statusCode);
117
            }
118
        } catch (\Exception $exception) {
119
            throw new \RuntimeException($exception->getMessage(), $exception->getCode(), $exception);
120
        }
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     *
126
     * @return void
127
     */
128
    public function doPerform()
129
    {
130
        $command = $this->prepareCommand();
131
        $command->setIO($this->getIO());
132
        $this->fixCommandDefinition($command);
133
134
        $this->executeCommand($command, $this->prepareInput(), new TaskOutput($this));
135
    }
136
}
137