Passed
Pull Request — master (#9)
by John
02:59
created

AbstractOperation::executeForAllRepositories()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 16
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Dandelion\Operation;
6
7
use Closure;
8
use Dandelion\Configuration\ConfigurationLoaderInterface;
9
use Dandelion\Operation\Result\MessageFactoryInterface;
10
use Dandelion\Operation\Result\MessageInterface;
11
use Dandelion\Process\ProcessPoolFactoryInterface;
12
use Symfony\Component\Process\Process;
13
use Phar;
14
15
abstract class AbstractOperation
16
{
17
    /**
18
     * @var \Dandelion\Configuration\ConfigurationLoaderInterface
19
     */
20
    protected $configurationLoader;
21
22
    /**
23
     * @var \Dandelion\Process\ProcessPoolFactoryInterface
24
     */
25
    protected $processPoolFactory;
26
27
    /**
28
     * @var \Dandelion\Operation\ResultFactoryInterface
29
     */
30
    protected $resultFactory;
31
32
    /**
33
     * @var \Dandelion\Operation\Result\MessageFactoryInterface
34
     */
35
    protected $messageFactory;
36
37
    /**
38
     * @var string
39
     */
40
    protected $binDir;
41
42
    /**
43
     * @param \Dandelion\Configuration\ConfigurationLoaderInterface $configurationLoader
44
     * @param \Dandelion\Process\ProcessPoolFactoryInterface $processPoolFactory
45
     * @param \Dandelion\Operation\ResultFactoryInterface $resultFactory
46
     * @param \Dandelion\Operation\Result\MessageFactoryInterface $messageFactory
47
     * @param string $binDir
48
     */
49
    public function __construct(
50
        ConfigurationLoaderInterface $configurationLoader,
51
        ProcessPoolFactoryInterface $processPoolFactory,
52
        ResultFactoryInterface $resultFactory,
53
        MessageFactoryInterface $messageFactory,
54
        string $binDir
55
    ) {
56
        $this->configurationLoader = $configurationLoader;
57
        $this->processPoolFactory = $processPoolFactory;
58
        $this->resultFactory = $resultFactory;
59
        $this->messageFactory = $messageFactory;
60
        $this->binDir = $binDir;
61
    }
62
63
    /**
64
     * @param string $repositoryName
65
     * @param string $branch
66
     *
67
     * @return \Dandelion\Operation\AbstractOperation
68
     */
69
    abstract public function executeForSingleRepository(string $repositoryName, string $branch): AbstractOperation;
70
71
    /**
72
     * @param string $branch
73
     *
74
     * @return \Dandelion\Operation\ResultInterface
75
     */
76
    public function executeForAllRepositories(string $branch = 'master'): ResultInterface
77
    {
78
        $configuration = $this->configurationLoader->load();
79
        $processPool = $this->processPoolFactory->create();
80
        $result = $this->resultFactory->create();
81
82
        foreach ($configuration->getRepositories() as $repositoryName => $repository) {
83
            $processPool->addProcess(
84
                $this->getCommand($repositoryName, $branch),
85
                $this->getCallback($result, $repositoryName)
86
            );
87
        }
88
89
        $processPool->start();
90
91
        return $result;
92
    }
93
94
    /**
95
     * @param \Dandelion\Operation\ResultInterface $result
96
     * @param string $repositoryName
97
     *
98
     * @return \Closure
99
     */
100
    protected function getCallback(ResultInterface $result, string $repositoryName): Closure
101
    {
102
        $messageFactory = $this->messageFactory;
103
104
        return static function (Process $process) use ($result, $messageFactory, $repositoryName) {
105
            // @codeCoverageIgnoreStart
106
            $type = $process->isSuccessful() ? MessageInterface::TYPE_INFO : MessageInterface::TYPE_ERROR;
107
108
            $message = $messageFactory->create()
109
                ->setType($type)
110
                ->setText($repositoryName);
111
112
            $result->addMessage($message);
113
            // @codeCoverageIgnoreEnd
114
        };
115
    }
116
117
    /**
118
     * @param string $repositoryName
119
     * @param string $branch
120
     *
121
     * @return string[]
122
     */
123
    abstract protected function getCommand(string $repositoryName, string $branch): array;
124
125
    /**
126
     * @return string
127
     */
128
    protected function getDandelionPath(): string
129
    {
130
        $path = sprintf('%sdandelion', $this->binDir);
131
        if (Phar::running()) {
132
            $path = Phar::running(false);
133
        }
134
135
        return $path;
136
    }
137
}
138