Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
ComposerDependencyAnalyserConfig
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
4 / 4
7
100.00% covered (success)
100.00%
1 / 1
 configure
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 applyIgnoresShadowDependencies
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 shouldShowShadowDependencies
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 applyPackagedRepositoryIgnores
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Fast Forward Development Tools for PHP projects.
7 *
8 * This file is part of fast-forward/dev-tools project.
9 *
10 * @author   Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
11 * @license  https://opensource.org/licenses/MIT MIT License
12 *
13 * @see      https://github.com/php-fast-forward/
14 * @see      https://github.com/php-fast-forward/dev-tools
15 * @see      https://github.com/php-fast-forward/dev-tools/issues
16 * @see      https://php-fast-forward.github.io/dev-tools/
17 * @see      https://datatracker.ietf.org/doc/html/rfc2119
18 */
19
20namespace FastForward\DevTools\Config;
21
22use FastForward\DevTools\Path\DevToolsPathResolver;
23use ShipMonk\ComposerDependencyAnalyser\Config\Configuration;
24use ShipMonk\ComposerDependencyAnalyser\Config\ErrorType;
25
26/**
27 * Provides the default Composer Dependency Analyser configuration.
28 *
29 * Consumers can use this as a starting point and extend it:
30 *
31 *     return \FastForward\DevTools\Config\ComposerDependencyAnalyserConfig::configure(
32 *         static function (\ShipMonk\ComposerDependencyAnalyser\Config\Configuration $configuration): void {
33 *             $configuration->ignoreErrorsOnPackage(
34 *                 'vendor/package',
35 *                 [\ShipMonk\ComposerDependencyAnalyser\Config\ErrorType::UNUSED_DEPENDENCY]
36 *             );
37 *         }
38 *     );
39 *
40 * @see https://github.com/shipmonk-rnd/composer-dependency-analyser
41 */
42 class ComposerDependencyAnalyserConfig
43{
44    public const string ENV_SHOW_SHADOW_DEPENDENCIES = 'FAST_FORWARD_DEV_TOOLS_SHOW_SHADOW_DEPENDENCIES';
45
46    /**
47     * Dependencies that are only required by the packaged DevTools distribution itself.
48     *
49     * These packages MUST only be ignored when the analyser runs against the
50     * DevTools repository, because consumer repositories do not inherit them as
51     * direct requirements automatically.
52     *
53     * @var array<int, string>
54     */
55    public const array DEFAULT_PACKAGED_UNUSED_DEPENDENCIES = [
56        'ergebnis/composer-normalize',
57        'fakerphp/faker',
58        'fast-forward/phpdoc-bootstrap-template',
59        'php-parallel-lint/php-parallel-lint',
60        'phpdocumentor/shim',
61        'phpmetrics/phpmetrics',
62        'phpro/grumphp-shim',
63        'pyrech/composer-changelogs',
64        'rector/jack',
65        'saggre/phpdocumentor-markdown',
66        'symfony/var-dumper',
67    ];
68
69    /**
70     * Production dependencies intentionally kept in require for the packaged toolchain.
71     *
72     * These dependencies are only exercised in test and development paths inside
73     * this repository, but they MUST remain available to the packaged DevTools
74     * runtime for consumer projects that choose to use those capabilities.
75     *
76     * @var array<int, string>
77     */
78    public const array DEFAULT_PACKAGED_PROD_ONLY_IN_DEV_DEPENDENCIES = [
79        'phpspec/prophecy',
80        'phpspec/prophecy-phpunit',
81        'symfony/var-exporter',
82    ];
83
84    /**
85     * Creates the default Composer Dependency Analyser configuration.
86     *
87     * @param callable|null $customize optional callback to customize the configuration
88     *
89     * @return Configuration the configured analyser configuration
90     */
91    public static function configure(?callable $customize = null): Configuration
92    {
93        $configuration = new Configuration();
94
95        if (! self::shouldShowShadowDependencies()) {
96            self::applyIgnoresShadowDependencies($configuration);
97        }
98
99        if (DevToolsPathResolver::isRepositoryCheckout()) {
100            self::applyPackagedRepositoryIgnores($configuration);
101        }
102
103        if (null !== $customize) {
104            $customize($configuration);
105        }
106
107        return $configuration;
108    }
109
110    /**
111     * The default configuration ignores shadow dependencies because Fast
112     * Forward packages MAY intentionally require dependency groups. For example,
113     * ecosystem or meta packages can require related PSR or framework packages
114     * so consumers do not need to install every package one by one.
115     *
116     * @param Configuration $configuration the analyser configuration to customize
117     *
118     * @return Configuration the modified configuration with shadow dependencies ignored
119     */
120    public static function applyIgnoresShadowDependencies(Configuration $configuration): Configuration
121    {
122        $configuration->ignoreErrors([ErrorType::SHADOW_DEPENDENCY]);
123
124        return $configuration;
125    }
126
127    /**
128     * Determines whether shadow dependency reports SHOULD remain visible.
129     *
130     * @return bool
131     */
132    public static function shouldShowShadowDependencies(): bool
133    {
134        return '1' === getenv(self::ENV_SHOW_SHADOW_DEPENDENCIES);
135    }
136
137    /**
138     * Applies the ignores required only by the packaged DevTools repository.
139     *
140     * @param Configuration $configuration the analyser configuration to customize
141     *
142     * @return Configuration the modified configuration with packaged repository ignores applied
143     */
144    public static function applyPackagedRepositoryIgnores(Configuration $configuration): Configuration
145    {
146        $configuration->ignoreErrorsOnExtension('ext-pcntl', [ErrorType::SHADOW_DEPENDENCY]);
147        $configuration->ignoreErrorsOnPackages(
148            self::DEFAULT_PACKAGED_UNUSED_DEPENDENCIES,
149            [ErrorType::UNUSED_DEPENDENCY]
150        );
151        $configuration->ignoreErrorsOnPackages(
152            self::DEFAULT_PACKAGED_PROD_ONLY_IN_DEV_DEPENDENCIES,
153            [ErrorType::PROD_DEPENDENCY_ONLY_IN_DEV],
154        );
155
156        return $configuration;
157    }
158}