Test Failed
Push — test ( 0c4d14...2be48d )
by Tom
02:17
created

Directories::getProjectDirectory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Runner;
6
7
use InvalidArgumentException;
8
use Ktomk\Pipelines\LibFs;
9
10
/**
11
 * Pipelines directories.
12
 *
13
 * Provides common directories (as path-names) for the pipelines project,
14
 * making use of environment parameters like HOME and some from the
15
 * XDG Base Directory Specification (XDGBDS).
16
 *
17
 * @link https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
18
 * @link https://wiki.debian.org/XDGBaseDirectorySpecification
19
 * @link https://wiki.archlinux.org/index.php/XDG_Base_Directory
20
 *
21
 * @package Ktomk\Pipelines\Runner
22
 */
23
class Directories
24
{
25
    /**
26
     * @var array environment parameters
27
     */
28
    private $env;
29
30
    /**
31
     * @var string
32
     */
33
    private $projectDirectory;
34
35
    /**
36
     * @var string name of the utility to have directories for
37 11
     */
38
    private $utility;
39 11
40 1
    /**
41
     * @var array|string[]
42
     */
43 10
    private static $baseDirectory = array(
44
        'XDG_DATA_HOME' => '$HOME/.local/share',
45 10
        'XDG_CACHE_HOME' => '$HOME/.cache',
46
        'XDG_CONFIG_HOME' => '$HOME/.config',
47
    );
48
49 1
    /**
50
     * Directories ctor
51
     *
52 9
     * @param array|string[] $env
53 9
     * @param string $projectDirectory project directory
54
     * @param string $utility [optional] name, defaults to "pipelines"
55
     * @see Directories::getBaseDirectory
56
     * @throws \InvalidArgumentException
57
     */
58
    public function __construct(array $env, $projectDirectory, $utility = null)
59
    {
60 2
        if (!isset($env['HOME']) || '' === $env['HOME']) {
61
            throw new InvalidArgumentException('$HOME unset or empty');
62 2
        }
63
64
        if (!basename($projectDirectory)) {
65
            throw new InvalidArgumentException(sprintf('Invalid project directory: "%s"', $projectDirectory));
66
        }
67
68 1
        null === $utility && $utility = 'pipelines';
69
        if (!LibFs::isPortableFilename($utility)) {
70 1
            throw new InvalidArgumentException(sprintf('Not a portable utility name: "%s"', $utility));
71
        }
72
73
        $this->env = $env;
74
        $this->projectDirectory = $projectDirectory;
75
        $this->utility = $utility;
76
    }
77
78 1
    /**
79
     * basename of the project directory
80 1
     *
81
     * @return string
82
     */
83
    public function getName()
84
    {
85
        return basename($this->projectDirectory);
86
    }
87
88
    /**
89
     * Get project directory.
90
     *
91
     * project is the base-folder (root-folder) of the project which
92
     * is run by pipelines.
93
     *
94
     * @return string
95
     */
96
    public function getProjectDirectory()
97 5
    {
98
        return $this->projectDirectory;
99 5
    }
100
101
    /**
102
     * FIXME(tk) unused (only in tests!) - reason: yet undecided what / when
103
     * to put the local deploy stuff in there. needs XDGBDS reading and
104 5
     * some more considerations as more likely more data is needed to store
105 1
     * in the file-system. But better use XDGDBS here.
106 1
     *
107 1
     * @return string
108 1
     */
109
    public function getPipelineLocalDeploy()
110
    {
111
        return sprintf('%s/.%s/%s', $this->env['HOME'], $this->utility, $this->getName());
112 4
    }
113 4
114 1
    /**
115
     * Pipelines base directories
116 3
     *
117 3
     * In the style of the (here weakly referenced) XDG Base Directory specs.
118
     *
119
     * Examples:
120 4
     *
121
     *      XDG_DATA_HOME is $HOME/.local/share if unset or empty
122 4
     *      XDG_CACHE_HOME is $HOME/.cache if unset or empty
123
     *      XDG_CONFIG_HOME is $HOME/.config if unset or empty
124
     *
125
     * @link https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
126
     * @link https://wiki.debian.org/XDGBaseDirectorySpecification
127
     * @link https://wiki.archlinux.org/index.php/XDG_Base_Directory
128
     *
129
     * @param string $type name XDG_DATA_HOME / XDG_CACHE_HOME / XDG_CONFIG_HOME
130
     * @param null|string $suffix
131
     * @return string
132
     */
133
    public function getBaseDirectory($type, $suffix = null)
134
    {
135
        $paths = self::$baseDirectory;
136
137
        $this->validateBaseDirectory($type);
138
139
        $buffer = null;
140
        if (isset($this->env[$type])) {
141
            $buffer = $this->env[$type];
142
        } else {
143
            $home = $this->env['HOME'];
144
            $buffer = substr_replace($paths[$type], $home, 0, strlen('$HOME'));
145
        }
146
147
        $buffer .= '/' . $this->utility;
148
149
        null === $suffix || $buffer .= '/' . $suffix;
150
151
        return $buffer;
152
    }
153
154
    /**
155
     * @param string $xdgName
156
     */
157
    private function validateBaseDirectory($xdgName)
158
    {
159
        $paths = self::$baseDirectory;
160
161
        if (!isset($paths[$xdgName])) {
162
            throw new \InvalidArgumentException(sprintf(
163
                'Not a base directory: %s. Known base directories are: "%s"',
164
                var_export($xdgName, true),
165
                implode('", "', array_keys($paths))
166
            ));
167
        }
168
    }
169
}
170