Passed
Pull Request — master (#34)
by
unknown
03:39
created

DependencyFilter::getDependents()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 2
nop 2
dl 0
loc 21
ccs 12
cts 12
cp 1
crap 3
rs 9.9
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright MediaCT. All rights reserved.
4
 * https://www.mediact.nl
5
 */
6
7
namespace Mediact\DependencyGuard\Violation\Filter;
8
9
use Composer\Composer;
10
use Composer\Package\PackageInterface;
11
use Composer\Repository\CompositeRepository;
12
use Composer\Repository\RepositoryInterface;
13
use Mediact\DependencyGuard\Candidate\Candidate;
14
use Mediact\DependencyGuard\Violation\Violation;
15
use Mediact\DependencyGuard\Violation\ViolationInterface;
16
17
class DependencyFilter implements ViolationFilterInterface
18
{
19
    /** @var ViolationFilterInterface */
20
    private $filter;
21
22
    /** @var CompositeRepository */
23
    private $repository;
24
25
    /**
26
     * Constructor.
27
     *
28
     * @param RepositoryInterface      $repository
29
     * @param ViolationFilterInterface $filter
30
     */
31 1
    public function __construct(
32
        RepositoryInterface $repository,
33
        ViolationFilterInterface $filter
34
    ) {
35 1
        $this->filter     = $filter;
36 1
        $this->repository = new CompositeRepository([$repository]);
37 1
    }
38
39
    /**
40
     * Filter violations.
41
     *
42
     * @param ViolationInterface $violation
43
     *
44
     * @return bool
45
     */
46 5
    public function __invoke(ViolationInterface $violation): bool
47
    {
48 5
        return array_reduce(
49 5
            array_map(
50
                function (
51
                    array $dependent
52
                ) use ($violation): ViolationInterface {
53
                    /** @var PackageInterface $package */
54 2
                    [$package] = $dependent;
55 2
                    return new Violation(
56 2
                        sprintf(
57 2
                            'Package "%s" provides violating package "%s".',
58 2
                            $package->getName(),
59 2
                            $violation->getPackage()->getName()
60
                        ),
61 2
                        new Candidate(
62 2
                            $package,
63 2
                            $violation->getSymbols()
64
                        )
65
                    );
66 5
                },
67 5
                $this->getDependents($violation->getPackage()->getName())
68
            ),
69
            function (bool $carry, ViolationInterface $violation): bool {
70 2
                return $carry || $this->filter->__invoke($violation);
71 5
            },
72 5
            false
73
        );
74
    }
75
76
    /**
77
     * Retrieves the dependents of a package in a recursive way.
78
     *
79
     * @param string $packageName
80
     * @param array  $context
81
     *
82
     * @return array
83
     */
84 5
    private function getDependents(
85
        string $packageName,
86
        array $context = []
87
    ): array {
88 5
        if (!isset($context[$packageName])) {
89 5
            $context[$packageName] = $this->repository->getDependents(
90 5
                $packageName,
91 5
                null,
92 5
                false,
93 5
                false
94
            );
95
96 5
            foreach ($context[$packageName] as $key => $dependent) {
97 2
                $context[$packageName] = array_merge(
98 2
                    $context[$packageName],
99 2
                    $this->getDependents($key)
100
                );
101
            }
102
        }
103
104 5
        return $context[$packageName];
105
    }
106
}
107