Passed
Pull Request — master (#282)
by Fabien
02:58
created

ProcessFactory   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 13
eloc 29
c 3
b 0
f 0
dl 0
loc 119
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A createCyclomaticComplexityProcess() 0 3 1
A getCyclomaticComplexityProcessBuilder() 0 10 1
A getAssessorArguments() 0 7 3
A getGitChangesCountProcessBuilder() 0 4 1
A getMercurialChangesCountProcessBuilder() 0 6 1
A createChangesCountProcess() 0 3 1
A getChangesCountProcessBuilder() 0 17 4
A __construct() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Churn\Process;
6
7
use Churn\File\File;
8
use Churn\Process\ChangesCount\GitChangesCountProcess;
9
use Churn\Process\ChangesCount\MercurialChangesCountProcess;
10
use Churn\Process\ChangesCount\NoVcsChangesCountProcess;
11
use Closure;
12
use InvalidArgumentException;
13
use Phar;
14
use Symfony\Component\Process\PhpExecutableFinder;
15
use Symfony\Component\Process\Process;
16
17
class ProcessFactory
18
{
19
20
    /**
21
     * Builder of objects implementing ChangesCountInterface.
22
     *
23
     * @var Closure
24
     */
25
    private $changesCountProcessBuilder;
26
27
    /**
28
     * Builder of objects implementing CyclomaticComplexityInterface.
29
     *
30
     * @var Closure
31
     */
32
    private $cyclomaticComplexityBuilder;
33
34
    /**
35
     * Class constructor.
36
     *
37
     * @param string $vcs Name of the version control system.
38
     * @param string $commitsSince String containing the date of when to look at commits since.
39
     */
40
    public function __construct(string $vcs, string $commitsSince)
41
    {
42
        $this->changesCountProcessBuilder = $this->getChangesCountProcessBuilder($vcs, $commitsSince);
43
        $this->cyclomaticComplexityBuilder = $this->getCyclomaticComplexityProcessBuilder();
44
    }
45
46
    /**
47
     * Creates a process that will count the number of changes for $file.
48
     *
49
     * @param File $file File that the process will execute on.
50
     */
51
    public function createChangesCountProcess(File $file): ChangesCountInterface
52
    {
53
        return ($this->changesCountProcessBuilder)($file);
54
    }
55
56
    /**
57
     * Creates a Cyclomatic Complexity Process that will run on $file.
58
     *
59
     * @param File $file File that the process will execute on.
60
     */
61
    public function createCyclomaticComplexityProcess(File $file): CyclomaticComplexityInterface
62
    {
63
        return ($this->cyclomaticComplexityBuilder)($file);
64
    }
65
66
    /**
67
     * @param string $vcs Name of the version control system.
68
     * @param string $commitsSince String containing the date of when to look at commits since.
69
     * @throws InvalidArgumentException If VCS is not supported.
70
     */
71
    private function getChangesCountProcessBuilder(string $vcs, string $commitsSince): Closure
72
    {
73
        if ('git' === $vcs) {
74
            return $this->getGitChangesCountProcessBuilder($commitsSince);
75
        }
76
77
        if ('mercurial' === $vcs) {
78
            return $this->getMercurialChangesCountProcessBuilder($commitsSince);
79
        }
80
81
        if ('none' === $vcs) {
82
            return static function (File $file): ChangesCountInterface {
83
                return new NoVcsChangesCountProcess($file);
84
            };
85
        }
86
87
        throw new InvalidArgumentException('Unsupported VCS: ' . $vcs);
88
    }
89
90
    /**
91
     * @param string $commitsSince String containing the date of when to look at commits since.
92
     */
93
    private function getGitChangesCountProcessBuilder(string $commitsSince): Closure
94
    {
95
        return static function (File $file) use ($commitsSince): ChangesCountInterface {
96
            return new GitChangesCountProcess($file, $commitsSince);
97
        };
98
    }
99
100
    /**
101
     * @param string $commitsSince String containing the date of when to look at commits since.
102
     */
103
    private function getMercurialChangesCountProcessBuilder(string $commitsSince): Closure
104
    {
105
        $date = \date('Y-m-d', \strtotime($commitsSince));
106
107
        return static function (File $file) use ($date): ChangesCountInterface {
108
            return new MercurialChangesCountProcess($file, $date);
109
        };
110
    }
111
112
    /**
113
     * Returns a cyclomatic complexity builder.
114
     */
115
    private function getCyclomaticComplexityProcessBuilder(): Closure
116
    {
117
        $phpExecutable = (string)(new PhpExecutableFinder())->find();
118
        $command = \array_merge([$phpExecutable], $this->getAssessorArguments());
119
120
        return static function (File $file) use ($command): CyclomaticComplexityInterface {
121
            $command[] = $file->getFullPath();
122
            $process = new Process($command);
123
124
            return new CyclomaticComplexityProcess($file, $process);
125
        };
126
    }
127
128
    /** @return array<string> */
129
    private function getAssessorArguments(): array
130
    {
131
        if (\is_callable([Phar::class, 'running']) && '' !== Phar::running(false)) {
132
            return [Phar::running(false), 'assess-complexity'];
133
        }
134
135
        return [__DIR__ . '/../../bin/CyclomaticComplexityAssessorRunner'];
136
    }
137
}
138