StepScriptRunner::runStepScript()   B
last analyzed

Complexity

Conditions 6
Paths 18

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 6

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 6
eloc 23
c 3
b 1
f 0
nc 18
nop 1
dl 0
loc 38
ccs 24
cts 24
cp 1
crap 6
rs 8.9297
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Runner;
6
7
use Ktomk\Pipelines\Cli\Exec;
8
use Ktomk\Pipelines\File\Pipeline\Step;
9
use Ktomk\Pipelines\Lib;
10
11
/**
12
 * Class StepScriptRunner
13
 *
14
 * Running step and after-step scripts or exec scripts in a running docker container
15
 *
16
 * @package Ktomk\Pipelines\Runner
17
 *
18
 * @see StepRunner::runStepScript
19
 */
20
class StepScriptRunner
21
{
22
    /**
23
     * @var Runner
24
     */
25
    private $runner;
26
27
    /**
28
     * @var string
29
     */
30
    private $name;
31
32
    /**
33
     * Static factory method to create a run step script
34
     *
35
     * @param Runner $runner
36
     * @param string $name container name
37
     * @param Step $step
38
     *
39
     * @return int status of step script, non-zero if a script command failed
40
     */
41 1
    public static function createRunStepScript(Runner $runner, $name, Step $step)
42
    {
43 1
        $self = new self($runner, $name);
44
45 1
        return $self->runStepScript($step);
46
    }
47
48
    /**
49
     * StepScriptRunner constructor.
50
     *
51
     * @param Runner $runner
52
     * @param string $name of container to run script in
53
     */
54 6
    public function __construct(Runner $runner, $name)
55
    {
56 6
        $this->runner = $runner;
57 6
        $this->name = $name;
58
    }
59
60
    /**
61
     * @param Step $step
62
     *
63
     * @return int status of step script, non-zero if a script command failed
64
     */
65 6
    public function runStepScript(Step $step)
66
    {
67 6
        $streams = $this->runner->getStreams();
68 6
        $exec = $this->runner->getExec();
69 6
        $name = $this->name;
70
71 6
        $buffer = StepScriptWriter::writeStepScript(
72 6
            $step->getScript(),
73 6
            $this->runner->getRunOpts()->getBoolOption('script.exit-early')
74
        );
75
76 6
        $scriptRunner = $this->runner->getRunOpts()->getOption('script.runner');
77 6
        if ($this->runner->getRunOpts()->getBoolOption('script.bash-runner')) {
78 6
            $bashRunner = '/bin/bash';
79 6
            0 === $exec->capture('docker', array(
80 6
                'exec', $name, '/bin/sh', '-c', "test -f {$bashRunner} && test -x {$bashRunner}",
81 1
            )) && $scriptRunner = $bashRunner;
82
        }
83
84 6
        $status = $this->execScript($buffer, $exec, $name, $scriptRunner);
85 6
        if (0 !== $status) {
86 2
            $streams->err(sprintf("script non-zero exit status: %d\n", $status));
87
        }
88
89 6
        if (!($script = $step->getAfterScript())) {
90 4
            return $status;
91
        }
92
93 2
        $streams->out("After script:\n");
94
95 2
        $buffer = StepScriptWriter::writeAfterScript($script, $status);
96
97 2
        $afterStatus = $this->execScript($buffer, $exec, $name, $scriptRunner);
98 2
        if (0 !== $afterStatus) {
99 1
            $streams->err(sprintf("after-script non-zero exit status: %d\n", $afterStatus));
100
        }
101
102 2
        return $status;
103
    }
104
105
    /**
106
     *
107
     * @param string $script "\n" terminated script lines
108
     * @param Exec $exec
109
     * @param string $name
110
     * @param string $runner executable (absolute path), defaults to "/bin/sh"
111
     *
112
     * @return int
113
     */
114 6
    private function execScript($script, Exec $exec, $name, $runner = '/bin/sh')
115
    {
116 6
        $buffer = Lib::cmd("<<'SCRIPT' docker", array(
117
                'exec', '-i', $name, $runner,
118
            )) . "\n";
119 6
        $buffer .= $script;
120 6
        $buffer .= "SCRIPT\n";
121
122 6
        return $exec->pass($buffer, array());
123
    }
124
}
125