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.

Script_Command::addScriptsFromFolder()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 1
nc 1
nop 3
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 stdClass;
48
use Phix_Project\CliEngine;
49
use Phix_Project\CliEngine\CliCommand;
50
use Phix_Project\ExceptionsLib1\Legacy_ErrorHandler;
51
use Phix_Project\ExceptionsLib1\Legacy_ErrorException;
52
use DataSift\Stone\ConfigLib\E5xx_ConfigFileNotFound;
53
use DataSift\Stone\ConfigLib\E5xx_InvalidConfigFile;
54
use DataSift\Storyplayer\PlayerLib\E4xx_NoSuchReport;
55
use DataSift\Storyplayer\PlayerLib\PhaseGroup_Player;
56
use DataSift\Storyplayer\PlayerLib\StoryTeller;
57
use DataSift\Storyplayer\PlayerLib\Script_Player;
58
use DataSift\Storyplayer\Console\ScriptConsole;
59
use DataSift\Storyplayer\Injectables;
60
61
/**
62
 * A command to play a script
63
 *
64
 * @category  Libraries
65
 * @package   Storyplayer/Cli
66
 * @author    Stuart Herbert <[email protected]>
67
 * @copyright 2011-present Mediasift Ltd www.datasift.com
68
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
69
 * @link      http://datasift.github.io/storyplayer
70
 */
71
class Script_Command extends BaseCommand implements CliSignalHandler
72
{
73
    /**
74
     * should we let background processes survive when we shutdown?
75
     * @var boolean
76
     */
77
    protected $persistProcesses = false;
78
79
    // we need to track this for handling CTRL-C
80
    protected $st;
81
82
    // we track this for convenience
83
    protected $output;
84
85
    // our list of scripts to execute
86
    protected $scriptList;
87
88
    // our injected data / services
89
    // needed for when user presses CTRL+C
90
    protected $injectables;
91
92 View Code Duplication
    public function __construct($injectables)
93
    {
94
        parent::__construct($injectables);
95
96
        // define the command
97
        $this->setName('script');
98
        $this->setShortDescription('run an automation script');
99
        $this->setLongDescription(
100
            "Use this command to play an automation script."
101
            .PHP_EOL
102
        );
103
        $this->setArgsList(array(
104
            "[<script.php>]" => "run a script"
105
        ));
106
107
        // the switches that this command supports
108
        $this->addFeature(new Feature_ConsoleSupport);
109
        $this->addFeature(new Feature_DeviceSupport);
110
        $this->addFeature(new Feature_TestEnvironmentConfigSupport);
111
        $this->addFeature(new Feature_SystemUnderTestConfigSupport);
112
        $this->addFeature(new Feature_LocalhostSupport);
113
        $this->addFeature(new Feature_ActiveConfigSupport);
114
        $this->addFeature(new Feature_DefinesSupport);
115
        $this->addFeature(new Feature_PhaseLoaderSupport);
116
        $this->addFeature(new Feature_ProseLoaderSupport);
117
        $this->addFeature(new Feature_TestUsersSupport);
118
119
        // now setup all of the switches that we support
120
        $this->addFeatureSwitches();
121
    }
122
123
    /**
124
     *
125
     * @param  CliEngine $engine
126
     * @param  array     $params
127
     * @param  Injectables|null $injectables
128
     * @return integer
129
     */
130
    public function processCommand(CliEngine $engine, $params = array(), $injectables = null)
131
    {
132
        // we need to wrap our code to catch old-style PHP errors
133
        $legacyHandler = new Legacy_ErrorHandler();
134
        try {
135
            $returnCode = $legacyHandler->run([$this, 'processInsideLegacyHandler'], [$engine, $params, $injectables]);
136
            return $returnCode;
137
        }
138
        catch (Exception $e) {
139
            $injectables->output->logCliError($e->getMessage());
140
            $engine->options->dev = true;
141
            if (isset($engine->options->dev) && $engine->options->dev) {
142
                $injectables->output->logCliError("Stack trace is:\n\n" . $e->getTraceAsString());
143
            }
144
            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...
145
        }
146
    }
147
148
    public function processInsideLegacyHandler(CliEngine $engine, $params = array(), $injectables = null)
149
    {
150
        // make sure we're using the ScriptConsole by default
151
        $injectables->output->usePluginInSlot(new ScriptConsole, 'console');
152
153
        // process the common functionality
154
        $this->initFeaturesBeforeModulesAvailable($engine);
155
156
        // now it is safe to create our shorthand
157
        $runtimeConfig        = $injectables->getRuntimeConfig();
158
        $runtimeConfigManager = $injectables->getRuntimeConfigManager();
159
        $output               = $injectables->output;
160
161
        // save the output for use in other methods
162
        $this->output = $output;
163
164
        // at this point, all of the services / data held in $injectables
165
        // has been initialised and is ready for use
166
167
        // create a new StoryTeller object
168
        $st = new StoryTeller($injectables);
169
170
        // remember our $st object, as we'll need it for our
171
        // shutdown function
172
        $this->st = $st;
173
174
        // now that we have $st, we can initialise any feature that
175
        // wants to use our modules
176
        $this->initFeaturesAfterModulesAvailable($st, $engine, $injectables);
177
178
        // install signal handling, now that $this->st is defined
179
        //
180
        // we wouldn't want signal handling called out of order :)
181
        $this->initSignalHandling($injectables);
182
183
        // build our list of stories to run
184
        $this->initScriptList($engine, $injectables, $params);
185
186
        // and we're ready to tell the world that we're here
187
        $output->startStoryplayer(
188
            $engine->getAppVersion(),
189
            $engine->getAppUrl(),
190
            $engine->getAppCopyright(),
191
            $engine->getAppLicense()
192
        );
193
194
        // $this->scriptList contains one or more things to run
195
        //
196
        // let's play each of them in order
197
        foreach ($this->scriptList as $player)
198
        {
199
            // play the story(ies)
200
            $player->play($st, $injectables);
201
        }
202
203
        // write out any changed runtime config to disk
204
        $runtimeConfigManager->saveRuntimeConfig($runtimeConfig, $output);
205
206
        // tell the output plugins that we're all done
207
        $output->endStoryplayer(0);
208
209
        // all done
210
        return 0;
211
    }
212
213
    // ==================================================================
214
    //
215
    // the individual initX() methods
216
    //
217
    // these are processed *after* the objects defined in the
218
    // CommonFunctionalitySupport trait have been initialised
219
    //
220
    // ------------------------------------------------------------------
221
222
    /**
223
     *
224
     * @param  Injectables $injectables
225
     * @return void
226
     */
227 View Code Duplication
    protected function initSignalHandling(Injectables $injectables)
228
    {
229
        // we need to remember the injectables, for when we handle CTRL+C
230
        $this->injectables = $injectables;
231
232
        // setup signal handling
233
        pcntl_signal(SIGTERM, array($this, 'sigtermHandler'));
234
        pcntl_signal(SIGINT , array($this, 'sigtermHandler'));
235
    }
236
237
    /**
238
     *
239
     * @param  CliEngine   $cliEngine
240
     * @param  Injectables $injectables
241
     * @param  array       $cliParams
242
     * @return void
243
     */
244
    protected function initScriptList(CliEngine $cliEngine, Injectables $injectables, $cliParams)
245
    {
246
        // our list of stories to play
247
        $this->scriptList = [];
248
249
        foreach ($cliParams as $cliParam) {
250
            // figure out what to do?
251
            if (is_dir($cliParam)) {
252
                $this->scriptList = $this->scriptList + $this->addScriptsFromFolder($cliEngine, $injectables, $cliParam);
253
            }
254
            else if (is_file($cliParam)) {
255
                // are we loading a story, or a list of stories?
256
                $paramParts  = explode('.', $cliParams[0]);
257
                $paramSuffix = end($paramParts);
258
259
                switch ($paramSuffix) {
260
                    case 'php':
261
                        $this->scriptList = $this->scriptList + $this->addScriptFromFile($cliEngine, $injectables, $cliParam);
262
                        break;
263
264
                    case 'json':
265
                        $this->scriptList = $this->scriptList + $this->addScriptsFromFile($cliEngine, $injectables, $cliParam);
266
                        break;
267
268
                    default:
269
                        $this->output->logCliError("unsupported script file '{$cliParam}'");
270
                        exit(1);
0 ignored issues
show
Coding Style Compatibility introduced by
The method initScriptList() 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...
271
                }
272
            }
273
            else {
274
                // if we get here, we've no idea what to do
275
                $this->output->logCliError("no such file: '{$cliParam}'");
276
                exit(1);
0 ignored issues
show
Coding Style Compatibility introduced by
The method initScriptList() 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...
277
            }
278
        }
279
    }
280
281
    // ==================================================================
282
    //
283
    // Story loading
284
    //
285
    // ------------------------------------------------------------------
286
287
    protected function addScriptFromFile(CliEngine $engine, Injectables $injectables, $storyFile)
0 ignored issues
show
Unused Code introduced by
The parameter $engine is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
288
    {
289
        // these are the players we want to execute for the story
290
        $return = [
291
            new Script_Player($storyFile, $injectables),
292
        ];
293
294
        // all done
295
        return $return;
296
    }
297
298
    protected function addScriptsFromFolder(CliEngine $engine, Injectables $injectables, $folder)
0 ignored issues
show
Unused Code introduced by
The parameter $engine is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $injectables is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $folder is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
299
    {
300
        // tbd
301
    }
302
303
    protected function addScriptsFromFile(CliEngine $engine, Injectables $injectables, $file)
0 ignored issues
show
Unused Code introduced by
The parameter $engine is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $injectables is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $file is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
304
    {
305
        // tbd
306
    }
307
308
    // ==================================================================
309
    //
310
    // SIGNAL handling
311
    //
312
    // ------------------------------------------------------------------
313
314
    /**
315
     *
316
     * @param  integer $signo
317
     * @return void
318
     */
319
    public function sigtermHandler($signo)
320
    {
321
        // tell the user what is happening
322
        echo "\n";
323
        echo "============================================================\n";
324
        echo "USER ABORT!!\n";
325
        echo "============================================================\n";
326
        echo "\n";
327
328
        // cleanup
329
        $phasesPlayer = new PhaseGroup_Player();
330
        $phasesPlayer->playPhases(
331
            "user abort",
332
            $this->st,
333
            $this->injectables,
334
            $this->injectables->activeConfig->getData('storyplayer.phases.userAbort'),
335
            null
336
        );
337
338
        // force a clean shutdown
339
        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...
340
    }
341
}