Completed
Push — master ( 696e0c...9b2b5f )
by Sebastian
02:46
created

Tar::archiveTo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
namespace phpbu\App\Cli\Executable;
3
4
use phpbu\App\Cli\Executable;
5
use phpbu\App\Exception;
6
use SebastianFeldmann\Cli\CommandLine;
7
use SebastianFeldmann\Cli\Command\Executable as Cmd;
8
9
/**
10
 * Tar Executable class.
11
 *
12
 * @package    phpbu
13
 * @subpackage Backup
14
 * @author     Sebastian Feldmann <[email protected]>
15
 * @copyright  Sebastian Feldmann <[email protected]>
16
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
17
 * @link       http://phpbu.de/
18
 * @since      Class available since Release 1.0.0
19
 */
20
class Tar extends Abstraction implements Executable
21
{
22
    /**
23
     * Path to compress
24
     *
25
     * @var string
26
     */
27
    private $path;
28
29
    /**
30
     * Compression to use
31
     *
32
     * @var string
33
     */
34
    private $compression;
35
36
    /**
37
     * Compress program to use.
38
     * --use-compress-program
39
     *
40
     * @var string
41
     */
42
    private $compressProgram;
43
44
    /**
45
     * Path to dump file
46
     *
47
     * @var string
48
     */
49
    private $tarPathname;
50
51
    /**
52
     * List of excluded path.
53
     * --exclude='foo'
54
     *
55
     * @var array
56
     */
57
    private $excludes = [];
58
59
    /**
60
     * Force local file resolution
61
     * --force-local
62
     *
63
     * @var bool
64
     */
65
    private $local = false;
66
67
    /**
68
     * Ignore failed reads
69
     * --ignore-failed-read
70
     *
71
     * @var bool
72
     */
73
    private $ignoreFailedRead;
74
75
    /**
76
     * Should the source directory be removed.
77
     *
78
     * @var boolean
79
     */
80
    private $removeSourceDir = false;
81
82
    /**
83
     * List of available compressors
84
     *
85
     * @var array
86
     */
87
    private static $availableCompressions = [
88
        'bzip2' => 'j',
89
        'gzip'  => 'z',
90
        'xz'    => 'J'
91
    ];
92
93
    /**
94
     * Constructor.
95
     *
96
     * @param string $path
97
     */
98 28
    public function __construct(string $path = '')
99
    {
100 28
        $this->setup('tar', $path);
101 28
    }
102
103
    /**
104
     * Return 'tar' compressor option e.g. 'j' for bzip2.
105
     *
106
     * @param  string $compressor
107
     * @return string
108
     */
109 8
    protected function getCompressionOption(string $compressor) : string
110
    {
111 8
        return $this->isCompressionValid($compressor) ? self::$availableCompressions[$compressor] : '';
112
    }
113
114
    /**
115
     * Compress tar.
116
     *
117
     * @param  string $compression
118
     * @return \phpbu\App\Cli\Executable\Tar
119
     */
120 18
    public function useCompression(string $compression) : Tar
121
    {
122 18
        if ($this->isCompressionValid($compression)) {
123 8
            $this->compression = $this->getCompressionOption($compression);
124
        }
125 18
        return $this;
126
    }
127
128
    /**
129
     * Set compress program.
130
     *
131
     * @param  string $program
132
     * @return \phpbu\App\Cli\Executable\Tar
133
     */
134 13
    public function useCompressProgram(string $program) : Tar
135
    {
136 13
        $this->compressProgram = $program;
137 13
        return $this;
138
    }
139
140
    /**
141
     * Add an path to exclude.
142
     *
143
     * @param  string $path
144
     * @return \phpbu\App\Cli\Executable\Tar
145
     */
146 2
    public function addExclude(string $path) : Tar
147
    {
148 2
        $this->excludes[] = $path;
149 2
        return $this;
150
    }
151
152
    /**
153
     * Force local file resolution.
154
     *
155
     * @param  bool $bool
156
     * @return \phpbu\App\Cli\Executable\Tar
157
     */
158 13
    public function forceLocal(bool $bool)
159
    {
160 13
        $this->local = $bool;
161 13
        return $this;
162
    }
163
164
    /**
165
     * Ignore failed reads setter.
166
     *
167
     * @param  bool $bool
168
     * @return \phpbu\App\Cli\Executable\Tar
169
     */
170 13
    public function ignoreFailedRead(bool $bool) : Tar
171
    {
172 13
        $this->ignoreFailedRead = $bool;
173 13
        return $this;
174
    }
175
176
    /**
177
     * Does the tar handle the compression.
178
     *
179
     * @return bool
180
     */
181 3
    public function handlesCompression() : bool
182
    {
183 3
        return !empty($this->compression);
184
    }
185
186
    /**
187
     * Set folder to compress.
188
     *
189
     * @param  string $path
190
     * @return \phpbu\App\Cli\Executable\Tar
191
     * @throws \phpbu\App\Exception
192
     */
193 26
    public function archiveDirectory(string $path) : Tar
194
    {
195 26
        $this->validateDirectory($path);
196 25
        $this->path = $path;
197 25
        return $this;
198
    }
199
200
    /**
201
     * Set target filename.
202
     *
203
     * @param  string $path
204
     * @return \phpbu\App\Cli\Executable\Tar
205
     */
206 24
    public function archiveTo(string $path) : Tar
207
    {
208 24
        $this->tarPathname = $path;
209 24
        return $this;
210
    }
211
212
    /**
213
     * Delete the source directory.
214
     *
215
     * @param  boolean $bool
216
     * @return \phpbu\App\Cli\Executable\Tar
217
     */
218 16
    public function removeSourceDirectory(bool $bool) : Tar
219
    {
220 16
        $this->removeSourceDir = $bool;
221 16
        return $this;
222
    }
223
224
    /**
225
     * Tar CommandLine generator.
226
     *
227
     * @return \SebastianFeldmann\Cli\CommandLine
228
     */
229 26
    protected function createCommandLine() : CommandLine
230
    {
231 26
        $this->validateSetup();
232
233 24
        $process = new CommandLine();
234 24
        $tar     = new Cmd($this->binary);
235
236 24
        $this->setExcludeOptions($tar);
237
238 24
        $tar->addOptionIfNotEmpty('--force-local', $this->local, false);
239 24
        $tar->addOptionIfNotEmpty('--ignore-failed-read', $this->ignoreFailedRead, false);
240 24
        $tar->addOptionIfNotEmpty('--use-compress-program', $this->compressProgram);
241 24
        $tar->addOption('-' . (empty($this->compressProgram) ? $this->compression : '') . 'cf');
242 24
        $tar->addArgument($this->tarPathname);
243 24
        $tar->addOption('-C', dirname($this->path), ' ');
244 24
        $tar->addArgument(basename($this->path));
245
246 24
        $process->addCommand($tar);
247
248
        // delete the source data if requested
249 24
        $this->addRemoveCommand($process);
250
251 24
        return $process;
252
    }
253
254
    /**
255
     * Adds necessary exclude options to tat command.
256
     *
257
     * @param \SebastianFeldmann\Cli\Command\Executable $tar
258
     */
259 24
    protected function setExcludeOptions(Cmd $tar)
260
    {
261 24
        foreach ($this->excludes as $path) {
262 2
            $tar->addOption('--exclude', $path);
263
        }
264 24
    }
265
266
    /**
267
     * Add a remove command if requested.
268
     *
269
     * @param \SebastianFeldmann\Cli\CommandLine $process
270
     */
271 24
    protected function addRemoveCommand(CommandLine $process)
272
    {
273 24
        if ($this->removeSourceDir) {
274 5
            $process->addCommand($this->getRmCommand());
275
        }
276 24
    }
277
278
    /**
279
     * Return 'rm' command.
280
     *
281
     * @return \SebastianFeldmann\Cli\Command\Executable
282
     */
283 5
    protected function getRmCommand() : Cmd
284
    {
285 5
        $rm = new Cmd('rm');
286 5
        $rm->addOption('-rf', $this->path, ' ');
287 5
        return $rm;
288
    }
289
290
    /**
291
     * Check directory to compress.
292
     *
293
     * @param  string $path
294
     * @throws \phpbu\App\Exception
295
     */
296 26
    private function validateDirectory(string $path)
297
    {
298 26
        if ($path === '.') {
299 1
            throw new Exception('unable to tar current working directory');
300
        }
301 25
    }
302
303
    /**
304
     * Check if source and target values are set.
305
     *
306
     * @throws \phpbu\App\Exception
307
     */
308 26
    private function validateSetup()
309
    {
310 26
        if (empty($this->path)) {
311 1
            throw new Exception('no directory to compress');
312
        }
313 25
        if (empty($this->tarPathname)) {
314 1
            throw new Exception('no target filename set');
315
        }
316 24
    }
317
318
    /**
319
     * Return true if a given compression is valid false otherwise.
320
     *
321
     * @param  string $compression
322
     * @return bool
323
     */
324 20
    public static function isCompressionValid(string  $compression) : bool
325
    {
326 20
        return isset(self::$availableCompressions[$compression]);
327
    }
328
}
329