Completed
Push — master ( 1c75f1...7c4959 )
by Greg
110:52 queued 82:25
created

ArgumentProcessor::selectArgs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 9.424
c 0
b 0
f 0
cc 2
nc 2
nop 4
1
<?php
2
namespace Consolidation\SiteProcess\Util;
3
4
use Consolidation\SiteAlias\AliasRecord;
5
use Symfony\Component\Process\Process;
6
7
class ArgumentProcessor
8
{
9
    public function selectArgs(AliasRecord $siteAlias, $args, $options = [], $optionsPassedAsArgs = [])
10
    {
11
        // Split args into three arrays separated by the `--`
12
        list($leadingArgs, $dashDash, $remaingingArgs) = $this->findArgSeparator($args);
13
        $convertedOptions = $this->convertOptions($options);
14
        $convertedOptionsPassedAsArgs = $this->convertOptions($optionsPassedAsArgs);
15
16
        // If the caller provided options that should be passed as args, then we
17
        // always need a `--`, whether or not one existed to begin with in $args
18
        if (!empty($convertedOptionsPassedAsArgs)) {
19
            $dashDash = ['--'];
20
        }
21
22
        // Combine our separated args in the correct order. $dashDash will
23
        // always be `['--']` if $optionsPassedAsArgs or $remaingingArgs are
24
        // not empty, and otherwise will usually be empty.
25
        $selectedArgs = array_merge(
26
            $leadingArgs,
27
            $convertedOptions,
28
            $dashDash,
29
            $optionsPassedAsArgs,
30
            $remaingingArgs
31
        );
32
33
        // Do any necessary interpolation on the selected arguments.
34
        $processedArgs = $this->interpolate($siteAlias, $selectedArgs);
35
36
        // Wrap the command with 'ssh' or some other transport if this is
37
        // a remote command; otherwise, leave it as-is.
38
        return $this->wrapWithTransport($siteAlias, $processedArgs);
39
    }
40
41
    protected function findArgSeparator($args)
42
    {
43
        $pos = array_search('--', $args);
44
        if ($pos === false) {
45
            return [$args, [], []];
46
        }
47
48
        return [
49
            array_slice($args, 0, $pos),
50
            ['--'],
51
            array_slice($args, $pos + 1),
52
        ];
53
    }
54
55
    protected function convertOptions($options)
56
    {
57
        $result = [];
58
        foreach ($options as $option => $value) {
59
            if ($value === true || $value == null) {
60
                $result[] = "--$option";
61
            } elseif ($value === false) {
62
                // Ignore this option.
63
            } else {
64
                $result[] = "--{$option}={$value}";
65
            }
66
        }
67
68
        return $result;
69
    }
70
71
    protected function wrapWithTransport(AliasRecord $siteAlias, $args)
72
    {
73
        if (!$siteAlias->isRemote()) {
74
            return $args;
75
        }
76
77
        // @TODO: Methinks this needs to be escaped for the target system.
78
        $commandToExecute = implode(' ', $args);
79
80
        // Question: How could we support variable transport mechanisms?
81
        return [
82
            'ssh',
83
            $siteAlias->get('ssh.options', '-o PasswordAuthentication=no'),
84
            $siteAlias->remoteHostWithUser(),
85
            $commandToExecute,
86
        ];
87
    }
88
89
    protected function interpolate(AliasRecord $siteAlias, $args)
90
    {
91
        return array_map(
92
            function ($arg) use ($siteAlias, $interpolator) {
0 ignored issues
show
Bug introduced by
The variable $interpolator does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
93
                return $interpolator->interpolate($siteAlias, $arg, false);
94
            },
95
            $args
96
        );
97
    }
98
}
99