Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
8.70% covered (danger)
8.70%
4 / 46
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
FileEnumerator
8.70% covered (danger)
8.70%
4 / 46
0.00% covered (danger)
0.00%
0 / 4
121.61
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 compileFileListForDependencies
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 compileFileListForPaths
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 addFile
12.90% covered (danger)
12.90%
4 / 31
0.00% covered (danger)
0.00%
0 / 1
39.37
1<?php
2/**
3 * Build a list of files for the Composer packages.
4 */
5
6namespace BrianHenryIE\Strauss\Pipeline;
7
8use BrianHenryIE\Strauss\Composer\ComposerPackage;
9use BrianHenryIE\Strauss\Config\FileEnumeratorConfig;
10use BrianHenryIE\Strauss\Files\DiscoveredFiles;
11use BrianHenryIE\Strauss\Files\File;
12use BrianHenryIE\Strauss\Files\FileWithDependency;
13use BrianHenryIE\Strauss\Helpers\FileSystem;
14use League\Flysystem\FilesystemException;
15use Psr\Log\LoggerAwareTrait;
16use Psr\Log\LoggerInterface;
17
18class FileEnumerator
19{
20    use LoggerAwareTrait;
21
22    protected FileEnumeratorConfig $config;
23
24    protected Filesystem $filesystem;
25
26    protected DiscoveredFiles $discoveredFiles;
27
28    /**
29     * Copier constructor.
30     */
31    public function __construct(
32        FileEnumeratorConfig $config,
33        FileSystem $filesystem,
34        LoggerInterface $logger
35    ) {
36        $this->discoveredFiles = new DiscoveredFiles();
37
38        $this->config = $config;
39
40        $this->filesystem = $filesystem;
41
42        $this->logger = $logger;
43    }
44
45    /**
46     * @param ComposerPackage[] $dependencies
47     * @throws FilesystemException
48     */
49    public function compileFileListForDependencies(array $dependencies): DiscoveredFiles
50    {
51        foreach ($dependencies as $dependency) {
52            $this->logger->info("Scanning for files for package {packageName}", ['packageName' => $dependency->getPackageName()]);
53            /** @var string $dependencyPackageAbsolutePath */
54            $dependencyPackageAbsolutePath = $dependency->getPackageAbsolutePath();
55            $this->compileFileListForPaths([$dependencyPackageAbsolutePath], $dependency);
56        }
57
58        $this->discoveredFiles->sort();
59        return $this->discoveredFiles;
60    }
61
62    /**
63     * @param string[] $paths
64     * @throws FilesystemException
65     */
66    public function compileFileListForPaths(array $paths, ?ComposerPackage $dependency = null): DiscoveredFiles
67    {
68        $absoluteFilePaths = $this->filesystem->findAllFilesAbsolutePaths($paths);
69
70        foreach ($absoluteFilePaths as $sourceAbsolutePath) {
71            $this->addFile($sourceAbsolutePath, $dependency);
72        }
73
74        $this->discoveredFiles->sort();
75        return $this->discoveredFiles;
76    }
77
78    /**
79     * @param string $sourceAbsoluteFilepath
80     * @param ?ComposerPackage $dependency
81     * @param ?string $autoloaderType
82     *
83     * @throws FilesystemException
84     * @uses DiscoveredFiles::add
85     *
86     */
87    protected function addFile(
88        string $sourceAbsoluteFilepath,
89        ?ComposerPackage $dependency = null,
90        ?string $autoloaderType = null
91    ): void {
92
93        if ($this->filesystem->directoryExists($sourceAbsoluteFilepath)) {
94            $this->logger->debug("Skipping directory at {sourcePath}", ['sourcePath' => $sourceAbsoluteFilepath]);
95            return;
96        }
97
98        // Do not add a file if its source does not exist!
99        if (!$this->filesystem->fileExists($sourceAbsoluteFilepath)) {
100            $this->logger->warning("File does not exist: {sourcePath}", ['sourcePath' => $sourceAbsoluteFilepath]);
101            return;
102        }
103
104        $isOutsideProjectDir = 0 !== strpos($sourceAbsoluteFilepath, $this->config->getVendorDirectory());
105
106        if ($dependency) {
107            $vendorRelativePath = substr(
108                $sourceAbsoluteFilepath,
109                strpos($sourceAbsoluteFilepath, $dependency->getRelativePath()) ?: 0
110            );
111
112            /** @var string $dependencyPackageAbsolutePath */
113            $dependencyPackageAbsolutePath = $dependency->getPackageAbsolutePath();
114            if ($vendorRelativePath === $sourceAbsoluteFilepath) {
115                $vendorRelativePath = $dependency->getRelativePath() . str_replace($dependencyPackageAbsolutePath, '', $sourceAbsoluteFilepath);
116            }
117
118            /** @var FileWithDependency $f */
119            $f = $this->discoveredFiles->getFile($sourceAbsoluteFilepath)
120                ?? new FileWithDependency($dependency, $vendorRelativePath, $sourceAbsoluteFilepath);
121
122            $f->setAbsoluteTargetPath($this->config->getVendorDirectory() . $vendorRelativePath);
123
124            $autoloaderType && $f->addAutoloader($autoloaderType);
125            $f->setDoDelete($isOutsideProjectDir);
126        } else {
127            $vendorRelativePath = str_replace($this->config->getVendorDirectory(), '', $sourceAbsoluteFilepath);
128            $vendorRelativePath = str_replace($this->config->getTargetDirectory(), '', $vendorRelativePath);
129
130            $f = $this->discoveredFiles->getFile($sourceAbsoluteFilepath)
131                 ?? new File($sourceAbsoluteFilepath, $vendorRelativePath);
132        }
133
134        $this->discoveredFiles->add($f);
135
136        $relativeFilePath =
137            $this->filesystem->getRelativePath(
138                dirname($this->config->getVendorDirectory()),
139                $f->getAbsoluteTargetPath()
140            );
141        $this->logger->info("Found file " . $relativeFilePath);
142    }
143}