Completed
Pull Request — master (#200)
by Erin
01:51
created

Application::createCommand()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 2
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Peridot\Console;
3
4
use Peridot\Configuration;
5
use Peridot\Reporter\ReporterFactory;
6
use Peridot\Runner\Context;
7
use Peridot\Runner\Runner;
8
use Peridot\Runner\RunnerInterface;
9
use Symfony\Component\Console\Application as ConsoleApplication;
10
use Symfony\Component\Console\Input\ArgvInput;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\ConsoleOutput;
13
use Symfony\Component\Console\Output\OutputInterface;
14
15
/**
16
 * The main Peridot application class.
17
 *
18
 * @package Peridot\Console
19
 */
20
class Application extends ConsoleApplication
21
{
22
    /**
23
     * @var Environment
24
     */
25
    protected $environment;
26
27
    /**
28
     * @var RunnerInterface
29
     */
30
    protected $runner;
31
32
    /**
33
     * @var Configuration
34
     */
35
    protected $configuration;
36
37
    /**
38
     * @param Environment $environment
39
     */
40
    public function __construct(Environment $environment)
41
    {
42
        $this->environment = $environment;
43
        $this->validateConfiguration();
44
        $this->environment->getEventEmitter()->emit('peridot.start', [$this->environment, $this]);
45
        parent::__construct(Version::NAME, Version::NUMBER);
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     *
51
     * @param  InputInterface  $input
52
     * @param  OutputInterface $output
53
     * @return int
54
     */
55
    public function run(InputInterface $input = null, OutputInterface $output = null)
56
    {
57
        if ($input !== null) {
58
            $in = $input;
59
        } else {
60
            $in = $this->getInput();
61
        }
62
63
        return parent::run($in, $output);
64
    }
65
66
    /**
67
     * Run the Peridot application
68
     *
69
     * @param InputInterface $input
70
     * @param OutputInterface $output
71
     * @return int
72
     */
73
    public function doRun(InputInterface $input, OutputInterface $output)
74
    {
75
        $this->configuration = ConfigurationReader::readInput($input);
76
        $this->environment->getEventEmitter()->emit('peridot.configure', [$this->configuration, $this]);
77
78
        $this->loadDsl($this->configuration->getDsl());
79
        $this->add($this->createCommand($this->configuration, $output));
80
81
        $exitCode = parent::doRun($input, $output);
82
83
        $this->environment->getEventEmitter()->emit('peridot.end', [$exitCode, $input, $output]);
84
85
        return $exitCode;
86
    }
87
88
    /**
89
     * Fetch the ArgvInput used by Peridot. If any exceptions are thrown due to
90
     * a mismatch between the option or argument requested and the input definition, the
91
     * exception will be rendered and Peridot will exit with an error code.
92
     *
93
     * @param array $argv An array of parameters from the CLI in the argv format.
94
     * @return ArgvInput
95
     */
96
    public function getInput(array $argv = null)
97
    {
98
        try {
99
            return new ArgvInput($argv, $this->environment->getDefinition());
100
        } catch (\Exception $e) {
101
            $this->renderException($e, new ConsoleOutput());
102
            exit(1);
0 ignored issues
show
Coding Style Compatibility introduced by
The method getInput() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
103
        }
104
    }
105
106
    /**
107
     * Return's peridot as the sole command used by Peridot
108
     *
109
     * @param  InputInterface $input
110
     * @return string
111
     */
112
    public function getCommandName(InputInterface $input)
113
    {
114
        return 'peridot';
115
    }
116
117
    /**
118
     * Load the configured DSL.
119
     *
120
     * @param $dsl
121
     */
122
    public function loadDsl($dslPath)
123
    {
124
        if (file_exists($dslPath)) {
125
            include_once $dslPath;
126
        }
127
    }
128
129
    /**
130
     * Set the runner used by the Peridot application.
131
     *
132
     * @param RunnerInterface $runner
133
     * @return $this
134
     */
135
    public function setRunner(RunnerInterface $runner)
136
    {
137
        $this->runner = $runner;
138
        return $this;
139
    }
140
141
    /**
142
     * Get the RunnerInterface being used by the Peridot application.
143
     * If one is not set, a default Runner will be used.
144
     *
145
     * @return RunnerInterface
146
     */
147
    public function getRunner()
148
    {
149
        if ($this->runner === null) {
150
            $this->runner = new Runner(
151
                Context::getInstance()->getCurrentSuite(),
152
                $this->getConfiguration(),
153
                $this->environment->getEventEmitter()
154
            );
155
        }
156
        return $this->runner;
157
    }
158
159
    /**
160
     * Return the Environment used by the Peridot application.
161
     *
162
     * @return Environment
163
     */
164
    public function getEnvironment()
165
    {
166
        return $this->environment;
167
    }
168
169
    /**
170
     * Return the configuration used by the Peridot application.
171
     *
172
     * @return Configuration
173
     */
174
    public function getConfiguration()
175
    {
176
        return $this->configuration;
177
    }
178
179
    /**
180
     * Set the configuration object used by the Peridot application.
181
     *
182
     * @param Configuration $configuration
183
     * @return $this
184
     */
185
    public function setConfiguration(Configuration $configuration)
186
    {
187
        $this->configuration = $configuration;
188
        return $this;
189
    }
190
191
    /**
192
     * Return an empty application input definition.
193
     *
194
     * @return InputDefinition
195
     */
196
    public function getDefinition()
197
    {
198
        $inputDefinition = parent::getDefinition();
199
        $inputDefinition->setArguments();
200
201
        return $inputDefinition;
202
    }
203
204
    /**
205
     * Validate that a supplied configuration exists.
206
     *
207
     * @return void
208
     */
209
    protected function validateConfiguration()
210
    {
211
        if (!$this->environment->load(getcwd() . DIRECTORY_SEPARATOR . 'peridot.php')) {
212
            fwrite(STDERR, "Configuration file specified but does not exist" . PHP_EOL);
213
            exit(1);
0 ignored issues
show
Coding Style Compatibility introduced by
The method validateConfiguration() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
214
        }
215
    }
216
217
    private function createCommand(Configuration $configuration, OutputInterface $output)
218
    {
219
        $runner = $this->getRunner();
220
        $factory = new ReporterFactory($configuration, $output, $this->environment->getEventEmitter());
221
222
        return new Command(
223
            $runner,
224
            $configuration,
225
            $factory,
226
            $this->environment->getEventEmitter(),
227
            $this->environment->getDefinition()
228
        );
229
    }
230
}
231