GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

BuildTestEnvironment_Command   C
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 234
Duplicated Lines 39.32 %

Coupling/Cohesion

Components 1
Dependencies 19
Metric Value
wmc 12
lcom 1
cbo 19
dl 92
loc 234
rs 6.875

6 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 28 28 1
B processCommand() 26 26 5
A initSignalHandling() 9 9 1
A initPlayerList() 0 5 1
B sigtermHandler() 29 29 2
B processInsideLegacyHandler() 0 79 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * Copyright (c) 2011-present Mediasift Ltd
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 *   * Redistributions of source code must retain the above copyright
12
 *     notice, this list of conditions and the following disclaimer.
13
 *
14
 *   * Redistributions in binary form must reproduce the above copyright
15
 *     notice, this list of conditions and the following disclaimer in
16
 *     the documentation and/or other materials provided with the
17
 *     distribution.
18
 *
19
 *   * Neither the names of the copyright holders nor the names of his
20
 *     contributors may be used to endorse or promote products derived
21
 *     from this software without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 *
36
 * @category  Libraries
37
 * @package   Storyplayer/Cli
38
 * @author    Stuart Herbert <[email protected]>
39
 * @copyright 2011-present Mediasift Ltd www.datasift.com
40
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
41
 * @link      http://datasift.github.io/storyplayer
42
 */
43
44
namespace DataSift\Storyplayer\Cli;
45
46
use Exception;
47
use RecursiveDirectoryIterator;
48
use RecursiveIteratorIterator;
49
use RecursiveRegexIterator;
50
use RegexIterator;
51
use stdClass;
52
use Phix_Project\CliEngine;
53
use Phix_Project\CliEngine\CliCommand;
54
use Phix_Project\ExceptionsLib1\Legacy_ErrorHandler;
55
use Phix_Project\ExceptionsLib1\Legacy_ErrorException;
56
use DataSift\Stone\ConfigLib\E5xx_ConfigFileNotFound;
57
use DataSift\Stone\ConfigLib\E5xx_InvalidConfigFile;
58
use DataSift\Storyplayer\PlayerLib\E4xx_NoSuchReport;
59
use DataSift\Storyplayer\PlayerLib\PhaseGroup_Player;
60
use DataSift\Storyplayer\PlayerLib\StoryTeller;
61
use DataSift\Storyplayer\PlayerLib\Story_Player;
62
use DataSift\Storyplayer\PlayerLib\TestEnvironment_Player;
63
use DataSift\Storyplayer\Console\DevModeConsole;
64
use DataSift\Storyplayer\Injectables;
65
66
use DataSift\Storyplayer\Cli\Feature\ActiveConfigSupport;
67
use DataSift\Storyplayer\Cli\Feature\ColorSupport;
68
use DataSift\Storyplayer\Cli\Feature\ConsoleSupport;
69
use DataSift\Storyplayer\Cli\Feature\DefinesSupport;
70
use DataSift\Storyplayer\Cli\Feature\DeviceSupport;
71
use DataSift\Storyplayer\Cli\Feature\LocalhostSupport;
72
use DataSift\Storyplayer\Cli\Feature\PersistDeviceSupport;
73
use DataSift\Storyplayer\Cli\Feature\PersistProcessesSupport;
74
use DataSift\Storyplayer\Cli\Feature\PersistReuseTargetSupport;
75
use DataSift\Storyplayer\Cli\Feature\PhaseLoaderSupport;
76
use DataSift\Storyplayer\Cli\Feature\ProseLoaderSupport;
77
use DataSift\Storyplayer\Cli\Feature\SystemUnderTestSupport;
78
use DataSift\Storyplayer\Cli\Feature\TestEnvironmentSupport;
79
use DataSift\Storyplayer\Cli\Feature\VerboseSupport;
80
81
/**
82
 * A command to build a test environment
83
 *
84
 * @category  Libraries
85
 * @package   Storyplayer/Cli
86
 * @author    Stuart Herbert <[email protected]>
87
 * @copyright 2011-present Mediasift Ltd www.datasift.com
88
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
89
 * @link      http://datasift.github.io/storyplayer
90
 */
91
class BuildTestEnvironment_Command extends BaseCommand implements CliSignalHandler
92
{
93
    // we need to track this for handling CTRL-C
94
    protected $st;
95
96
    // we track this for convenience
97
    protected $output;
98
99
    // our list of players to execute
100
    protected $playerList;
101
102
    // our injected data / services
103
    // needed for when user presses CTRL+C
104
    protected $injectables;
105
106 View Code Duplication
    public function __construct($injectables)
107
    {
108
        parent::__construct($injectables);
109
110
        // define the command
111
        $this->setName('build-test-environment');
112
        $this->setShortDescription('build a test environment');
113
        $this->setLongDescription(
114
            "Use this command to build a test environment. Handy for testing that your test environment "
115
            ."provisions correctly."
116
            .PHP_EOL
117
        );
118
119
        // add in the features that this command relies on
120
        $this->addFeature(new Feature_VerboseSupport);
121
        $this->addFeature(new Feature_ConsoleSupport);
122
        $this->addFeature(new Feature_ColorSupport);
123
        $this->addFeature(new Feature_TestEnvironmentConfigSupport);
124
        $this->addFeature(new Feature_LocalhostSupport);
125
        $this->addFeature(new Feature_ActiveConfigSupport);
126
        $this->addFeature(new Feature_DefinesSupport);
127
        $this->addFeature(new Feature_PhaseLoaderSupport);
128
        $this->addFeature(new Feature_ProseLoaderSupport);
129
        $this->addFeature(new Feature_PersistReuseTargetSupport);
130
131
        // now setup all of the switches that we support
132
        $this->addFeatureSwitches();
133
    }
134
135
    /**
136
     *
137
     * @param  CliEngine $engine
138
     * @param  array     $params
139
     * @param  Injectables|null $injectables
140
     * @return integer
141
     */
142 View Code Duplication
    public function processCommand(CliEngine $engine, $params = array(), $injectables = null)
143
    {
144
        // we need to wrap our code to catch old-style PHP errors
145
        $legacyHandler = new Legacy_ErrorHandler();
146
147
        // run our code
148
        try {
149
            $returnCode = $legacyHandler->run([$this, 'processInsideLegacyHandler'], [$engine, $params, $injectables]);
150
            return $returnCode;
151
        }
152
        catch (Exception $e) {
153
            $injectables->output->logCliError($e->getMessage());
154
            $engine->options->dev = true;
155
            if (isset($engine->options->dev) && $engine->options->dev) {
156
                $injectables->output->logCliError("Stack trace is:\n\n" . $e->getTraceAsString());
157
            }
158
159
            // stop the browser if available
160
            if (isset($this->st)) {
161
                $this->st->stopDevice();
162
            }
163
164
            // tell the calling process that things did not end well
165
            exit(1);
0 ignored issues
show
Coding Style Compatibility introduced by
The method processCommand() 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...
166
        }
167
    }
168
169
    public function processInsideLegacyHandler(CliEngine $engine, $params = array(), $injectables = null)
170
    {
171
        // process the common functionality
172
        $this->initFeaturesBeforeModulesAvailable($engine);
173
174
        // now it is safe to create our shorthand
175
        $runtimeConfig        = $injectables->getRuntimeConfig();
176
        $runtimeConfigManager = $injectables->getRuntimeConfigManager();
177
        $output               = $injectables->output;
178
179
        // save the output for use in other methods
180
        $this->output = $output;
181
182
        // at this point, all of the services / data held in $injectables
183
        // has been initialised and is ready for use
184
        //
185
        // what's left is the stuff that needs initialising in phases
186
        // or $st
187
188
        // create a new StoryTeller object
189
        $st = new StoryTeller($injectables);
190
191
        // remember our $st object, as we'll need it for our
192
        // shutdown function
193
        $this->st = $st;
194
195
        // now that we have $st, we can initialise any feature that
196
        // wants to use our modules
197
        $this->initFeaturesAfterModulesAvailable($st, $engine, $injectables);
198
199
        // install signal handling, now that $this->st is defined
200
        //
201
        // we wouldn't want signal handling called out of order :)
202
        $this->initSignalHandling($injectables);
203
204
        // build our list of players to run
205
        $this->initPlayerList($injectables);
206
207
        // let's keep score :)
208
        $startTime = microtime(true);
209
210
        // and we're ready to tell the world that we're here
211
        $output->startStoryplayer(
212
            $engine->getAppVersion(),
213
            $engine->getAppUrl(),
214
            $engine->getAppCopyright(),
215
            $engine->getAppLicense()
216
        );
217
218
        // $this->playerList contains one or more things to play
219
        //
220
        // let's play each of them in order
221
        foreach ($this->playerList as $player)
222
        {
223
            // execute each player in turn
224
            //
225
            // they may also have their own list of nested players
226
            $player->play($st, $injectables);
227
228
            // make sure the test device has been stopped
229
            // (it may have been persisted by the story)
230
            //
231
            // we do not allow the test device to persist between
232
            // top-level players
233
            $st->stopDevice();
234
        }
235
236
        // write out any changed runtime config to disk
237
        $runtimeConfigManager->saveRuntimeConfig($runtimeConfig, $output);
238
239
        // how long did that take?
240
        $duration = microtime(true) - $startTime;
241
242
        // tell the output plugins that we're all done
243
        $output->endStoryplayer($duration);
244
245
        // all done
246
        return 0;
247
    }
248
249
    // ==================================================================
250
    //
251
    // the individual initX() methods
252
    //
253
    // these are processed *after* the objects defined in the
254
    // CommonFunctionalitySupport trait have been initialised
255
    //
256
    // ------------------------------------------------------------------
257
258
    /**
259
     *
260
     * @param  Injectables $injectables
261
     * @return void
262
     */
263 View Code Duplication
    protected function initSignalHandling(Injectables $injectables)
264
    {
265
        // we need to remember the injectables, for when we handle CTRL+C
266
        $this->injectables = $injectables;
267
268
        // setup signal handling
269
        pcntl_signal(SIGTERM, array($this, 'sigtermHandler'));
270
        pcntl_signal(SIGINT , array($this, 'sigtermHandler'));
271
    }
272
273
    /**
274
     *
275
     * @param  Injectables $injectables
276
     * @return void
277
     */
278
    protected function initPlayerList(Injectables $injectables)
279
    {
280
        // we just want a TestEnvironment
281
        $this->playerList[] = new TestEnvironment_Player([], $injectables);
282
    }
283
284
    // ==================================================================
285
    //
286
    // SIGNAL handling
287
    //
288
    // ------------------------------------------------------------------
289
290
    /**
291
     *
292
     * @param  integer $signo
293
     * @return void
294
     */
295 View Code Duplication
    public function sigtermHandler($signo)
296
    {
297
        // tell the user what is happening
298
        echo PHP_EOL;
299
        echo "============================================================" . PHP_EOL;
300
        echo "USER ABORT!!" . PHP_EOL;
301
302
        // do we skip destroying the test environment?
303
        if ($this->st->getPersistTestEnvironment()) {
304
            echo PHP_EOL . "* Warning: NOT destroying test environment" . PHP_EOL
305
                 .         "           --reuse-target flag is set" . PHP_EOL;
306
        }
307
308
        // cleanup
309
        echo PHP_EOL . "Cleaning up: ";
310
        $phasesPlayer = new PhaseGroup_Player();
311
        $phasesPlayer->playPhases(
312
            "user abort",
313
            $this->st,
314
            $this->injectables,
315
            $this->injectables->activeConfig->getData('storyplayer.phases.userAbort'),
316
            null
317
        );
318
319
        echo " done" . PHP_EOL . "============================================================" . PHP_EOL . PHP_EOL;
320
321
        // force a clean shutdown
322
        exit(1);
0 ignored issues
show
Coding Style Compatibility introduced by
The method sigtermHandler() 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...
323
    }
324
}
325