Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.76% covered (warning)
81.76%
121 / 148
60.00% covered (warning)
60.00%
24 / 40
CRAP
0.00% covered (danger)
0.00%
0 / 1
StraussConfig
81.76% covered (warning)
81.76%
121 / 148
60.00% covered (warning)
60.00%
24 / 40
116.89
0.00% covered (danger)
0.00%
0 / 1
 __construct
92.59% covered (success)
92.59%
75 / 81
0.00% covered (danger)
0.00%
0 / 1
26.27
 getTargetDirectory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTargetDirectory
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 getVendorDirectory
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setVendorDirectory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNamespacePrefix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setNamespacePrefix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getClassmapPrefix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setClassmapPrefix
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConstantsPrefix
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setConstantsPrefix
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUpdateCallSites
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setUpdateCallSites
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setExcludeFromCopy
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 getExcludePackagesFromCopy
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExcludeNamespacesFromCopy
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExcludeFilePatternsFromCopy
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setExcludeFromPrefix
66.67% covered (warning)
66.67%
4 / 6
0.00% covered (danger)
0.00%
0 / 1
4.59
 getExcludePackagesFromPrefixing
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setExcludePackagesFromPrefixing
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExcludeNamespacesFromPrefixing
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExcludeFilePatternsFromPrefixing
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getOverrideAutoload
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setOverrideAutoload
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isDeleteVendorFiles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isDeleteVendorPackages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDeleteVendorFiles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDeleteVendorPackages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPackages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPackages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isClassmapOutput
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setClassmapOutput
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setExcludePackages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNamespaceReplacementPatterns
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setNamespaceReplacementPatterns
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isIncludeModifiedDate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setIncludeModifiedDate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isIncludeAuthor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setIncludeAuthor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updateFromCli
71.43% covered (warning)
71.43%
10 / 14
0.00% covered (danger)
0.00%
0 / 1
12.33
1<?php
2/**
3 * The extra/strauss key in composer.json.
4 */
5
6namespace BrianHenryIE\Strauss\Composer\Extra;
7
8use Composer\Composer;
9use Exception;
10use JsonMapper\JsonMapperFactory;
11use JsonMapper\Middleware\Rename\Rename;
12use Symfony\Component\Console\Input\InputInterface;
13
14class StraussConfig
15{
16    /**
17     * The output directory.
18     *
19     * Probably `strauss/` or `src/strauss/`.
20     *
21     * @var string
22     */
23    protected $targetDirectory = 'vendor-prefixed';
24
25    /**
26     * The vendor directory.
27     *
28     * Probably 'vendor/'
29     *
30     * @var string
31     */
32    protected $vendorDirectory = 'vendor';
33
34    /**
35     * `namespacePrefix` is the prefix to be given to any namespaces.
36     * Presumably this will take the form `My_Project_Namespace\dep_directory`.
37     *
38     * @link https://www.php-fig.org/psr/psr-4/
39     *
40     * @var string
41     */
42    protected string $namespacePrefix;
43
44    /**
45     * @var string
46     */
47    protected string $classmapPrefix;
48
49
50    /**
51     * @var ?string
52     */
53    protected ?string $constantsPrefix = null;
54
55    /**
56     * Should replacements be performed in project files?
57     *
58     * When null, files in the project's `autoload` key are scanned and changes which have been performed on the
59     * vendor packages are reflected in the project files.
60     *
61     * When an array of relative file paths are provided, the files in those directories are updated.
62     *
63     * An empty array disables updating project files.
64     *
65     * @var ?string[]
66     */
67    protected ?array $updateCallSites = null;
68
69    /**
70     * Packages to copy and (maybe) prefix.
71     *
72     * If this is empty, the "requires" list in the project composer.json is used.
73     *
74     * @var string[]
75     */
76    protected array $packages = [];
77
78    /**
79     * Back-compatibility with Mozart.
80     *
81     * @var string[]
82     */
83    private array $excludePackages;
84
85    /**
86     * 'exclude_from_copy' in composer/extra config.
87     *
88     * @var array{packages: string[], namespaces: string[], file_patterns: string[]}
89     */
90    protected array $excludeFromCopy = array('file_patterns'=>array(),'namespaces'=>array(),'packages'=>array());
91
92    /**
93     * @var array{packages: string[], namespaces: string[], file_patterns: string[]}
94     */
95    protected array $excludeFromPrefix = array('file_patterns'=>array(),'namespaces'=>array(),'packages'=>array());
96
97    /**
98     * An array of autoload keys to replace packages' existing autoload key.
99     *
100     * e.g. when
101     * * A package has no autoloader
102     * * A package specified both a PSR-4 and a classmap but only needs one
103     * ...
104     *
105     * @var array<string, array{files?:array<string>,classmap?:array<string>,"psr-4":array<string|array<string>>}>|array{} $overrideAutoload
106     */
107    protected array $overrideAutoload = [];
108
109    /**
110     * After completing prefixing should the source files be deleted?
111     * This does not affect symlinked directories.
112     */
113    protected bool $deleteVendorFiles = false;
114
115    /**
116     * After completing prefixing should the source packages be deleted?
117     * This does not affect symlinked directories.
118     */
119    protected bool $deleteVendorPackages = false;
120
121    protected bool $classmapOutput;
122
123    /**
124     * A dictionary of regex captures => regex replacements.
125     *
126     * E.g. used to avoid repetition of the plugin vendor name in namespaces.
127     * `"~BrianHenryIE\\\\(.*)~" : "BrianHenryIE\\WC_Cash_App_Gateway\\\\$1"`.
128     *
129     * @var array<string, string> $namespaceReplacementPatterns
130     */
131    protected array $namespaceReplacementPatterns = array();
132
133    /**
134     * Should a modified date be included in the header for modified files?
135     *
136     * @var bool
137     */
138    protected $includeModifiedDate = true;
139
140    /**
141     * Should the author name be included in the header for modified files?
142     *
143     * @var bool
144     */
145    protected $includeAuthor = true;
146
147    /**
148     * Read any existing Mozart config.
149     * Overwrite it with any Strauss config.
150     * Provide sensible defaults.
151     *
152     * @param Composer $composer
153     *
154     * @throws Exception
155     */
156    public function __construct(Composer $composer)
157    {
158
159        $configExtraSettings = null;
160
161        // Backwards compatibility with Mozart.
162        if (isset($composer->getPackage()->getExtra()['mozart'])) {
163            $configExtraSettings = (object)$composer->getPackage()->getExtra()['mozart'];
164
165            // Default setting for Mozart.
166            $this->setDeleteVendorFiles(true);
167        }
168
169        if (isset($composer->getPackage()->getExtra()['strauss'])) {
170            $configExtraSettings = (object)$composer->getPackage()->getExtra()['strauss'];
171        }
172
173        if (!is_null($configExtraSettings)) {
174            $mapper = (new JsonMapperFactory())->bestFit();
175
176            $rename = new Rename();
177            $rename->addMapping(StraussConfig::class, 'dep_directory', 'targetDirectory');
178            $rename->addMapping(StraussConfig::class, 'dep_namespace', 'namespacePrefix');
179
180            $rename->addMapping(StraussConfig::class, 'exclude_packages', 'excludePackages');
181            $rename->addMapping(StraussConfig::class, 'delete_vendor_files', 'deleteVendorFiles');
182            $rename->addMapping(StraussConfig::class, 'delete_vendor_packages', 'deleteVendorPackages');
183
184            $rename->addMapping(StraussConfig::class, 'exclude_prefix_packages', 'excludePackagesFromPrefixing');
185
186            $mapper->unshift($rename);
187            $mapper->push(new \JsonMapper\Middleware\CaseConversion(
188                \JsonMapper\Enums\TextNotation::UNDERSCORE(),
189                \JsonMapper\Enums\TextNotation::CAMEL_CASE()
190            ));
191
192            $mapper->mapObject($configExtraSettings, $this);
193        }
194
195        // Defaults.
196        // * Use PSR-4 autoloader key
197        // * Use PSR-0 autoloader key
198        // * Use the package name
199        if (! isset($this->namespacePrefix)) {
200            if (isset($composer->getPackage()->getAutoload()['psr-4'])) {
201                $this->setNamespacePrefix(array_key_first($composer->getPackage()->getAutoload()['psr-4']));
202            } elseif (isset($composer->getPackage()->getAutoload()['psr-0'])) {
203                $this->setNamespacePrefix(array_key_first($composer->getPackage()->getAutoload()['psr-0']));
204            } elseif ('__root__' !== $composer->getPackage()->getName()) {
205                $packageName = $composer->getPackage()->getName();
206                $namespacePrefix = preg_replace('/[^\w\/]+/', '_', $packageName);
207                $namespacePrefix = str_replace('/', '\\', $namespacePrefix) . '\\';
208                $namespacePrefix = preg_replace_callback('/(?<=^|_|\\\\)[a-z]/', function ($match) {
209                    return strtoupper($match[0]);
210                }, $namespacePrefix);
211                $this->setNamespacePrefix($namespacePrefix);
212            } elseif (isset($this->classmapPrefix)) {
213                $namespacePrefix = rtrim($this->getClassmapPrefix(), '_');
214                $this->setNamespacePrefix($namespacePrefix);
215            }
216        }
217
218        if (! isset($this->classmapPrefix)) {
219            if (isset($composer->getPackage()->getAutoload()['psr-4'])) {
220                $autoloadKey = array_key_first($composer->getPackage()->getAutoload()['psr-4']);
221                $classmapPrefix = str_replace("\\", "_", $autoloadKey);
222                $this->setClassmapPrefix($classmapPrefix);
223            } elseif (isset($composer->getPackage()->getAutoload()['psr-0'])) {
224                $autoloadKey = array_key_first($composer->getPackage()->getAutoload()['psr-0']);
225                $classmapPrefix = str_replace("\\", "_", $autoloadKey);
226                $this->setClassmapPrefix($classmapPrefix);
227            } elseif ('__root__' !== $composer->getPackage()->getName()) {
228                $packageName = $composer->getPackage()->getName();
229                $classmapPrefix = preg_replace('/[^\w\/]+/', '_', $packageName);
230                $classmapPrefix = str_replace('/', '\\', $classmapPrefix);
231                // Uppercase the first letter of each word.
232                $classmapPrefix = preg_replace_callback('/(?<=^|_|\\\\)[a-z]/', function ($match) {
233                    return strtoupper($match[0]);
234                }, $classmapPrefix);
235                $classmapPrefix = str_replace("\\", "_", $classmapPrefix);
236                $this->setClassmapPrefix($classmapPrefix);
237            } elseif (isset($this->namespacePrefix)) {
238                $classmapPrefix = preg_replace('/[^\w\/]+/', '_', $this->getNamespacePrefix());
239                $classmapPrefix = rtrim($classmapPrefix, '_') . '_';
240                $this->setClassmapPrefix($classmapPrefix);
241            }
242        }
243
244        if (!isset($this->namespacePrefix) || !isset($this->classmapPrefix)) {
245            throw new Exception('Prefix not set. Please set `namespace_prefix`, `classmap_prefix` in composer.json/extra/strauss.');
246        }
247
248        if (empty($this->packages)) {
249            $this->packages = array_map(function (\Composer\Package\Link $element) {
250                return $element->getTarget();
251            }, $composer->getPackage()->getRequires());
252        }
253
254        // If the bool flag for classmapOutput wasn't set in the Json config.
255        if (!isset($this->classmapOutput)) {
256            $this->classmapOutput = true;
257            // Check each autoloader.
258            foreach ($composer->getPackage()->getAutoload() as $autoload) {
259                // To see if one of its paths.
260                foreach ($autoload as $entry) {
261                    $paths = (array) $entry;
262                    foreach ($paths as $path) {
263                        // Matches the target directory.
264                        if (trim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR === $this->getTargetDirectory()) {
265                            $this->classmapOutput = false;
266                            break 3;
267                        }
268                    }
269                }
270            }
271        }
272
273        // TODO: Throw an exception if any regex patterns in config are invalid.
274        // https://stackoverflow.com/questions/4440626/how-can-i-validate-regex
275        // preg_match('~Valid(Regular)Expression~', null) === false);
276
277        if (isset($configExtraSettings->updateCallSites)) {
278            if (true === $configExtraSettings->updateCallSites) {
279                $this->updateCallSites = null;
280            } elseif (false === $configExtraSettings->updateCallSites) {
281                $this->updateCallSites = array();
282            } elseif (is_array($configExtraSettings->updateCallSites)) {
283                $this->updateCallSites = $configExtraSettings->updateCallSites;
284            } else {
285                // uh oh.
286            }
287        }
288    }
289
290    /**
291     * `target_directory` will always be returned without a leading slash and with a trailing slash.
292     *
293     * @return string
294     */
295    public function getTargetDirectory(): string
296    {
297        return trim($this->targetDirectory, DIRECTORY_SEPARATOR . '\\/') . DIRECTORY_SEPARATOR;
298    }
299
300    /**
301     * @param string $targetDirectory
302     */
303    public function setTargetDirectory(string $targetDirectory): void
304    {
305        $this->targetDirectory = trim(
306            preg_replace(
307                '/[\/\\\\]+/',
308                DIRECTORY_SEPARATOR,
309                $targetDirectory
310            ),
311            DIRECTORY_SEPARATOR
312        )
313            . DIRECTORY_SEPARATOR ;
314    }
315
316    /**
317     * @return string
318     */
319    public function getVendorDirectory(): string
320    {
321        return trim($this->vendorDirectory, DIRECTORY_SEPARATOR . '\\/') . DIRECTORY_SEPARATOR;
322    }
323
324    /**
325     * @param string $vendorDirectory
326     */
327    public function setVendorDirectory(string $vendorDirectory): void
328    {
329        $this->vendorDirectory = $vendorDirectory;
330    }
331
332    /**
333     * @return string
334     */
335    public function getNamespacePrefix(): string
336    {
337        return trim($this->namespacePrefix, '\\');
338    }
339
340    /**
341     * @param string $namespacePrefix
342     */
343    public function setNamespacePrefix(string $namespacePrefix): void
344    {
345        $this->namespacePrefix = $namespacePrefix;
346    }
347
348    /**
349     * @return string
350     */
351    public function getClassmapPrefix(): string
352    {
353        return $this->classmapPrefix;
354    }
355
356    /**
357     * @param string $classmapPrefix
358     */
359    public function setClassmapPrefix(string $classmapPrefix): void
360    {
361        $this->classmapPrefix = $classmapPrefix;
362    }
363
364    /**
365     * @return string
366     */
367    public function getConstantsPrefix(): ?string
368    {
369        return $this->constantsPrefix;
370    }
371
372    /**
373     * @param string $constantsPrefix
374     */
375    public function setConstantsPrefix(string $constantsPrefix): void
376    {
377        $this->constantsPrefix = $constantsPrefix;
378    }
379
380    /**
381     * List of files and directories to update call sites in. Empty to disable. Null infers from the project's autoload key.
382     *
383     * @return string[]|null
384     */
385    public function getUpdateCallSites(): ?array
386    {
387        return $this->updateCallSites;
388    }
389
390    /**
391     * @param string[]|null $updateCallSites
392     */
393    public function setUpdateCallSites(?array $updateCallSites): void
394    {
395        $this->updateCallSites = $updateCallSites;
396    }
397
398    /**
399     * @param array{packages?:array<string>, namespaces?:array<string>, file_patterns?:array<string>} $excludeFromCopy
400     */
401    public function setExcludeFromCopy(array $excludeFromCopy): void
402    {
403        foreach (array( 'packages', 'namespaces', 'file_patterns' ) as $key) {
404            if (isset($excludeFromCopy[$key])) {
405                $this->excludeFromCopy[$key] = $excludeFromCopy[$key];
406            }
407        }
408    }
409
410    /**
411     * @return string[]
412     */
413    public function getExcludePackagesFromCopy(): array
414    {
415        return $this->excludeFromCopy['packages'] ?? array();
416    }
417
418    /**
419     * @return string[]
420     */
421    public function getExcludeNamespacesFromCopy(): array
422    {
423        return $this->excludeFromCopy['namespaces'] ?? array();
424    }
425
426    /**
427     * @return string[]
428     */
429    public function getExcludeFilePatternsFromCopy(): array
430    {
431        return $this->excludeFromCopy['file_patterns'] ?? array();
432    }
433
434    /**
435     * @param array{packages?:array<string>, namespaces?:array<string>, file_patterns?:array<string>} $excludeFromPrefix
436     */
437    public function setExcludeFromPrefix(array $excludeFromPrefix): void
438    {
439        if (isset($excludeFromPrefix['packages'])) {
440            $this->excludeFromPrefix['packages'] = $excludeFromPrefix['packages'];
441        }
442        if (isset($excludeFromPrefix['namespaces'])) {
443            $this->excludeFromPrefix['namespaces'] = $excludeFromPrefix['namespaces'];
444        }
445        if (isset($excludeFromPrefix['file_patterns'])) {
446            $this->excludeFromPrefix['file_patterns'] = $excludeFromPrefix['file_patterns'];
447        }
448    }
449
450    /**
451     * When prefixing, do not prefix these packages (which have been copied).
452     *
453     * @return string[]
454     */
455    public function getExcludePackagesFromPrefixing(): array
456    {
457        return $this->excludeFromPrefix['packages'] ?? array();
458    }
459
460    /**
461     * @param string[] $excludePackagesFromPrefixing
462     */
463    public function setExcludePackagesFromPrefixing(array $excludePackagesFromPrefixing): void
464    {
465        $this->excludeFromPrefix['packages'] = $excludePackagesFromPrefixing;
466    }
467
468    /**
469     * @return string[]
470     */
471    public function getExcludeNamespacesFromPrefixing(): array
472    {
473        return $this->excludeFromPrefix['namespaces'] ?? array();
474    }
475
476    /**
477     * @return string[]
478     */
479    public function getExcludeFilePatternsFromPrefixing(): array
480    {
481        return $this->excludeFromPrefix['file_patterns'] ?? array();
482    }
483
484
485    /**
486     * @return array{}|array<string, array{files?:array<string>,classmap?:array<string>,"psr-4":array<string|array<string>>}> $overrideAutoload Dictionary of package name: autoload rules.
487     */
488    public function getOverrideAutoload(): array
489    {
490        return $this->overrideAutoload;
491    }
492
493    /**
494     * @param array<string, array{files?:array<string>,classmap?:array<string>,"psr-4":array<string|array<string>>}> $overrideAutoload Dictionary of package name: autoload rules.
495     */
496    public function setOverrideAutoload(array $overrideAutoload): void
497    {
498        $this->overrideAutoload = $overrideAutoload;
499    }
500
501    /**
502     * @return bool
503     */
504    public function isDeleteVendorFiles(): bool
505    {
506        return $this->deleteVendorFiles;
507    }
508
509    /**
510     * @return bool
511     */
512    public function isDeleteVendorPackages(): bool
513    {
514        return $this->deleteVendorPackages;
515    }
516
517    /**
518     * @param bool $deleteVendorFiles
519     */
520    public function setDeleteVendorFiles(bool $deleteVendorFiles): void
521    {
522        $this->deleteVendorFiles = $deleteVendorFiles;
523    }
524
525    /**
526     * @param bool $deleteVendorPackages
527     */
528    public function setDeleteVendorPackages(bool $deleteVendorPackages): void
529    {
530        $this->deleteVendorPackages = $deleteVendorPackages;
531    }
532
533    /**
534     * @return string[]
535     */
536    public function getPackages(): array
537    {
538        return $this->packages;
539    }
540
541    /**
542     * @param string[] $packages
543     */
544    public function setPackages(array $packages): void
545    {
546        $this->packages = $packages;
547    }
548
549    /**
550     * @return bool
551     */
552    public function isClassmapOutput(): bool
553    {
554        return $this->classmapOutput;
555    }
556
557    /**
558     * @param bool $classmapOutput
559     */
560    public function setClassmapOutput(bool $classmapOutput): void
561    {
562        $this->classmapOutput = $classmapOutput;
563    }
564
565    /**
566     * Backwards compatibility with Mozart.
567     *
568     * @param string[] $excludePackages
569     */
570    public function setExcludePackages(array $excludePackages): void
571    {
572        $this->excludeFromPrefix['packages'] = $excludePackages;
573    }
574
575
576    /**
577     * @return array<string,string>
578     */
579    public function getNamespaceReplacementPatterns(): array
580    {
581        return $this->namespaceReplacementPatterns;
582    }
583
584    /**
585     * @param array<string,string> $namespaceReplacementPatterns
586     */
587    public function setNamespaceReplacementPatterns(array $namespaceReplacementPatterns): void
588    {
589        $this->namespaceReplacementPatterns = $namespaceReplacementPatterns;
590    }
591
592    /**
593     * @return bool
594     */
595    public function isIncludeModifiedDate(): bool
596    {
597        return $this->includeModifiedDate;
598    }
599
600    /**
601     * @param bool $includeModifiedDate
602     */
603    public function setIncludeModifiedDate(bool $includeModifiedDate): void
604    {
605        $this->includeModifiedDate = $includeModifiedDate;
606    }
607
608
609    /**
610     * @return bool
611     */
612    public function isIncludeAuthor(): bool
613    {
614        return $this->includeAuthor;
615    }
616
617    /**
618     * @param bool $includeAuthor
619     */
620    public function setIncludeAuthor(bool $includeAuthor): void
621    {
622        $this->includeAuthor = $includeAuthor;
623    }
624
625    /**
626     * @param InputInterface $input To access the command line options.
627     */
628    public function updateFromCli(InputInterface $input): void
629    {
630
631        // strauss --updateCallSites=false (default)
632        // strauss --updateCallSites=true
633        // strauss --updateCallSites=src,input,extra
634
635        if ($input->hasOption('updateCallSites') && $input->getOption('updateCallSites') !== null) {
636            $updateCallSitesInput = $input->getOption('updateCallSites');
637
638            if ('false' === $updateCallSitesInput) {
639                $this->updateCallSites = array();
640            } elseif ('true' === $updateCallSitesInput) {
641                $this->updateCallSites = null;
642            } elseif (! is_null($updateCallSitesInput)) {
643                $this->updateCallSites = explode(',', $updateCallSitesInput);
644            }
645        }
646
647        if ($input->hasOption('deleteVendorPackages') && $input->getOption('deleteVendorPackages') !== null) {
648            $isDeleteVendorPackagesCommandLine = $input->getOption('deleteVendorPackages') === 'true';
649            $this->setDeleteVendorPackages($isDeleteVendorPackagesCommandLine);
650        } elseif ($input->hasOption('delete_vendor_packages') && $input->getOption('delete_vendor_packages') !== null) {
651            $isDeleteVendorPackagesCommandLine = $input->getOption('delete_vendor_packages') === 'true';
652            $this->setDeleteVendorPackages($isDeleteVendorPackagesCommandLine);
653        }
654    }
655}