Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
FileCopyScanner
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 2
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 scanFiles
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
272
1<?php
2/**
3 * Loop over the discovered files and mark the file to be copied or not.
4 *
5 * ```
6 * "exclude_from_copy": {
7 *   "packages": [
8 *   ],
9 *   "namespaces": [
10 *   ],
11 *   "file_patterns": [
12 *   ]
13 * },
14 * ```
15 */
16
17namespace BrianHenryIE\Strauss\Pipeline;
18
19use BrianHenryIE\Strauss\Config\FileCopyScannerConfigInterface;
20use BrianHenryIE\Strauss\Files\DiscoveredFiles;
21use BrianHenryIE\Strauss\Files\FileBase;
22use BrianHenryIE\Strauss\Files\FileWithDependency;
23use BrianHenryIE\Strauss\Helpers\FileSystem;
24use BrianHenryIE\Strauss\Types\DiscoveredSymbol;
25use BrianHenryIE\Strauss\Types\NamespaceSymbol;
26use League\Flysystem\FilesystemReader;
27use Psr\Log\LoggerAwareTrait;
28use Psr\Log\LoggerInterface;
29use Psr\Log\NullLogger;
30
31class FileCopyScanner
32{
33    use LoggerAwareTrait;
34
35    protected FileCopyScannerConfigInterface $config;
36
37    protected FileSystem $fileSystem;
38
39    public function __construct(
40        FileCopyScannerConfigInterface $config,
41        FileSystem $filesystem,
42        ?LoggerInterface $logger = null
43    ) {
44        $this->config = $config;
45        $this->fileSystem = $filesystem;
46
47        $this->setLogger($logger ?? new NullLogger());
48    }
49
50    public function scanFiles(DiscoveredFiles $files): void
51    {
52        /** @var FileBase $file */
53        foreach ($files->getFiles() as $file) {
54            $copy = true;
55
56            if ($file instanceof FileWithDependency) {
57                if (in_array($file->getDependency()->getPackageName(), $this->config->getExcludePackagesFromCopy(), true)) {
58                    $this->logger->debug("File {$file->getSourcePath()} will not be copied because {$file->getDependency()->getPackageName()} is excluded from copy.");
59                    $copy = false;
60                }
61            }
62
63            if ($this->config->getTargetDirectory() === $this->config->getVendorDirectory()) {
64                $this->logger->debug("The target directory is the same as the vendor directory."); // TODO: surely this should be outside the loop/class.
65                $copy = false;
66            }
67
68            /** @var DiscoveredSymbol $symbol */
69            foreach ($file->getDiscoveredSymbols() as $symbol) {
70                foreach ($this->config->getExcludeNamespacesFromCopy() as $namespace) {
71                    if (in_array($file->getSourcePath(), array_keys($symbol->getSourceFiles()), true)
72                        && $symbol instanceof NamespaceSymbol
73                        && str_starts_with($symbol->getOriginalSymbol(), $namespace)
74                    ) {
75                        $this->logger->debug("File {$file->getSourcePath()} will not be copied because namespace {$namespace} is excluded from copy.");
76                        $copy = false;
77                    }
78                }
79            }
80
81            $filePath = $file->getSourcePath();
82            foreach ($this->config->getExcludeFilePatternsFromCopy() as $pattern) {
83                if (1 == preg_match($pattern, $filePath)) {
84                    $this->logger->debug("File {$file->getSourcePath()} will not be copied because it matches pattern {$pattern}.");
85                    $copy = false;
86                }
87            }
88
89            if ($copy) {
90                $this->logger->debug("Marking file {$file->getSourcePath()} to be copied.");
91            }
92
93            $file->setDoCopy($copy);
94
95            $target = $copy && $file instanceof FileWithDependency
96                ? $this->config->getTargetDirectory() . $file->getVendorRelativePath()
97                : $file->getSourcePath();
98
99            $file->setAbsoluteTargetPath($target);
100
101            $shouldDelete = $this->config->isDeleteVendorFiles() && ! $this->fileSystem->isSymlinkedFile($file);
102            $file->setDoDelete($shouldDelete);
103        };
104    }
105}