Completed
Push — master ( 447b50...b231ae )
by Frank
02:30
created

LockedCommandDecorator::setProcessTitle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace FrankDeJonge\LockedConsoleCommand;
4
5
use Symfony\Component\Console\Application;
6
use Symfony\Component\Console\Command\Command;
7
use Symfony\Component\Console\Helper\HelperSet;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Output\OutputInterface;
10
use Symfony\Component\Filesystem\LockHandler;
11
12
class LockedCommandDecorator extends Command
13
{
14
    /**
15
     * @var Command
16
     */
17
    private $decoratedCommand;
18
19
    /**
20
     * @var string|LockHandler
21
     */
22
    private $lockName;
23
24
    /**
25
     * @var string
26
     */
27
    private $lockPath;
28
29
    /**
30
     * Constructor.
31
     *
32
     * @param Command            $command
33
     * @param string|LockHandler $lockName
34
     * @param string             $lockPath
35
     */
36 30
    public function __construct(Command $command, $lockName = null, $lockPath = null)
37
    {
38 30
        $this->decoratedCommand = $command;
39 30
        $this->setLockName($lockName);
40 30
        $this->lockPath = $lockPath;
41 30
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 3
    public function ignoreValidationErrors()
47
    {
48 3
        $this->decoratedCommand->ignoreValidationErrors();
49 3
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54 3
    public function setApplication(Application $application = null)
55
    {
56 3
        $this->decoratedCommand->setApplication($application);
57 3
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62 3
    public function setHelperSet(HelperSet $helperSet)
63
    {
64 3
        $this->decoratedCommand->setHelperSet($helperSet);
65 3
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70 3
    public function getHelperSet()
71
    {
72 3
        return $this->decoratedCommand->getHelperSet();
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 3
    public function getApplication()
79
    {
80 3
        return $this->decoratedCommand->getApplication();
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86 3
    public function isEnabled()
87
    {
88 3
        return $this->decoratedCommand->isEnabled();
89
    }
90
91
    /**
92
     * @param string|LockHandler|null $lockName
93
     */
94 30
    public function setLockName($lockName)
95
    {
96 30
        $this->lockName = $lockName;
97 30
    }
98
99
    /**
100
     * Runs the command.
101
     *
102
     * Before the decorated command is run, a lock is requested.
103
     * When failed to acquire the lock, the command exits.
104
     *
105
     * @param InputInterface  $input  An InputInterface instance
106
     * @param OutputInterface $output An OutputInterface instance
107
     *
108
     * @return int The command exit code
109
     */
110 12
    public function run(InputInterface $input, OutputInterface $output)
111
    {
112 12
        $this->mergeApplicationDefinition();
113 12
        $input->bind($this->getDefinition());
114 12
        $lock = $this->getLockHandler($input);
115
116 12
        if ( ! $lock->lock()) {
117 6
            $this->writeLockedMessage($input, $output);
118
119 3
            return 1;
120
        }
121
122
        try {
123 6
            return $this->decoratedCommand->run($input, $output);
124
        } finally {
125 6
            $lock->release();
126
        }
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132 3
    public function setCode(callable $code)
133
    {
134 3
        $this->decoratedCommand->setCode($code);
135
136 3
        return $this;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142 15
    public function mergeApplicationDefinition($mergeArgs = true)
143
    {
144 15
        $this->decoratedCommand->mergeApplicationDefinition($mergeArgs);
145 15
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150 3
    public function setDefinition($definition)
151
    {
152 3
        $this->decoratedCommand->setDefinition($definition);
153
154 3
        return $this;
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 15
    public function getDefinition()
161
    {
162 15
        return $this->decoratedCommand->getDefinition();
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168 3
    public function getNativeDefinition()
169
    {
170 3
        return $this->decoratedCommand->getNativeDefinition();
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176 3
    public function addArgument($name, $mode = null, $description = '', $default = null)
177
    {
178 3
        $this->decoratedCommand->addArgument($name, $mode, $description, $default);
179
180 3
        return $this;
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186 3
    public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
187
    {
188 3
        $this->decoratedCommand->addOption($name, $shortcut, $mode, $description, $default);
189
190 3
        return $this;
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196 3
    public function setName($name)
197
    {
198 3
        $this->decoratedCommand->setName($name);
199
200 3
        return $this;
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206 3
    public function setProcessTitle($title)
207
    {
208 3
        $this->decoratedCommand->setProcessTitle($title);
209
210 3
        return $this;
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     */
216 3
    public function getName()
217
    {
218 3
        return $this->decoratedCommand->getName();
219
    }
220
221
    /**
222
     * {@inheritdoc}
223
     */
224 3
    public function setDescription($description)
225
    {
226 3
        $this->decoratedCommand->setDescription($description);
227
228 3
        return $this;
229
    }
230
231
    /**
232
     * {@inheritdoc}
233
     */
234 3
    public function getDescription()
235
    {
236 3
        return $this->decoratedCommand->getDescription();
237
    }
238
239
    /**
240
     * {@inheritdoc}
241
     */
242 3
    public function setHelp($help)
243
    {
244 3
        $this->decoratedCommand->setHelp($help);
245
246 3
        return $this;
247
    }
248
249
    /**
250
     * {@inheritdoc}
251
     */
252 3
    public function getHelp()
253
    {
254 3
        return $this->decoratedCommand->getHelp();
255
    }
256
257
    /**
258
     * {@inheritdoc}
259
     */
260 3
    public function getProcessedHelp()
261
    {
262 3
        return $this->decoratedCommand->getProcessedHelp();
263
    }
264
265
    /**
266
     * {@inheritdoc}
267
     */
268 3
    public function setAliases($aliases)
269
    {
270 3
        $this->decoratedCommand->setAliases($aliases);
271
272 3
        return $this;
273
    }
274
275
    /**
276
     * {@inheritdoc}
277
     */
278 3
    public function getAliases()
279
    {
280 3
        return $this->decoratedCommand->getAliases();
281
    }
282
283
    /**
284
     * {@inheritdoc}
285
     */
286 3
    public function getSynopsis($short = false)
287
    {
288 3
        return $this->decoratedCommand->getSynopsis($short);
289
    }
290
291
    /**
292
     * {@inheritdoc}
293
     */
294 3
    public function getHelper($name)
295
    {
296 3
        return $this->decoratedCommand->getHelper($name);
297
    }
298
299
    /**
300
     * Get the locking helper.
301
     *
302
     * @param  InputInterface $input
303
     *
304
     * @return LockHandler
305
     */
306 12
    private function getLockHandler(InputInterface $input)
307
    {
308 12
        if ($this->lockName instanceof LockHandler) {
309 9
            return $this->lockName;
310
        }
311
312 3
        $lockName = $this->getLockName($input);
313 3
        $lockPath = $this->getLockPath($input);
314
315 3
        return new LockHandler($lockName, $lockPath);
316
    }
317
318
    /**
319
     * Get the name for the lock.
320
     *
321
     * @param  InputInterface $input
322
     *
323
     * @return string
324
     */
325 15
    public function getLockName(InputInterface $input)
326
    {
327 15
        if (is_string($this->lockName)) {
328 6
            return $this->lockName;
329
        }
330
331 9
        if ($this->lockName instanceof LockHandler) {
332 3
            return 'UNKNOWN';
333
        }
334
335 6
        if ($this->decoratedCommand instanceof SpecifiesLockName) {
336 3
            return $this->decoratedCommand->getLockName($input);
337
        }
338
339 3
        return $this->decoratedCommand->getName();
340
    }
341
342
    /**
343
     * Get the lock path.
344
     *
345
     * @param  InputInterface $input
346
     *
347
     * @return null|string
348
     */
349 12
    public function getLockPath(InputInterface $input)
350
    {
351 12
        if ($this->lockName instanceof LockHandler) {
352 3
            return 'UNKNOWN';
353
        }
354
355 9
        if ($this->lockPath !== null) {
356 3
            return $this->lockPath;
357
        }
358
359 6
        if ($this->decoratedCommand instanceof SpecifiesLockPath) {
360 3
            return $this->decoratedCommand->getLockPath($input);
361
        }
362
363 3
        return sys_get_temp_dir();
364
    }
365
366
    /**
367
     * Write the "is locked" message.
368
     *
369
     * @param InputInterface  $input
370
     * @param OutputInterface $output
371
     */
372 6
    private function writeLockedMessage(InputInterface $input, OutputInterface $output)
373
    {
374 6
        $commandName = $this->decoratedCommand->getName();
375 6
        $lockName = $this->getLockName($input);
376 6
        $lockPath = $this->getLockPath($input);
377 6
        $message = sprintf(
378 6
            '<info>Command "%s" is already running, locked with "%s" at path "%s"</info>',
379 4
            $commandName,
380 4
            $lockName,
381
            $lockPath
382 4
        );
383
384 6
        if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
385 3
            $output->writeln($message);
386 2
        }
387 3
    }
388
}
389