Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
6.67% covered (danger)
6.67%
4 / 60
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
FileEnumerator
6.67% covered (danger)
6.67%
4 / 60
0.00% covered (danger)
0.00%
0 / 4
129.08
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
8.89% covered (danger)
8.89%
4 / 45
0.00% covered (danger)
0.00%
0 / 1
44.06
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        if ($dependency) {
105//        $isOutsideProjectDir = $this->filesystem->normalize($dependency->getRealPath())
106//                               !== $this->filesystem->normalize($dependency->getPackageAbsolutePath());
107
108            $isOutsideProjectDir = str_starts_with($dependency->getPackageAbsolutePath(), $this->config->getAbsoluteVendorDirectory());
109
110            $vendorRelativePath = $this->filesystem->getRelativePath(
111                $this->config->getAbsoluteVendorDirectory(),
112                $sourceAbsoluteFilepath
113            );
114
115            /** @var string $dependencyPackageAbsolutePath */
116            $dependencyPackageAbsolutePath = $dependency->getPackageAbsolutePath();
117            if ($vendorRelativePath === $sourceAbsoluteFilepath) {
118                $vendorRelativePath = $dependency->getRelativePath() . str_replace(
119                    FileSystem::normalizeDirSeparator($dependencyPackageAbsolutePath),
120                    '',
121                    FileSystem::normalizeDirSeparator($sourceAbsoluteFilepath)
122                );
123            }
124
125            /** @var FileWithDependency $f */
126            $f = $this->discoveredFiles->getFile($sourceAbsoluteFilepath)
127                ?? new FileWithDependency(
128                    $dependency,
129                    $this->filesystem->normalizePath($vendorRelativePath),
130                    $this->filesystem->normalizePath($sourceAbsoluteFilepath),
131                    $this->config->getAbsoluteTargetDirectory(). '/' . $vendorRelativePath
132                );
133
134//            $f->setTargetAbsolutePath($this->config->getAbsoluteTargetDirectory() . '/' . $vendorRelativePath);
135
136            $autoloaderType && $f->addAutoloader($autoloaderType);
137            //         $f->setDoDelete(!$isOutsideProjectDir);
138//            $f->setDoDelete($isOutsideProjectDir);
139        } else {
140            $vendorRelativePath = $this->filesystem->getRelativePath(
141                str_starts_with($sourceAbsoluteFilepath, $this->config->getAbsoluteVendorDirectory()) ? $this->config->getAbsoluteVendorDirectory() : $this->config->getAbsoluteTargetDirectory(),
142                $sourceAbsoluteFilepath,
143            );
144
145            $targetAbsolutePath = $this->config->getAbsoluteTargetDirectory() . '/' . $vendorRelativePath;
146
147            $f = $this->discoveredFiles->getFile($sourceAbsoluteFilepath)
148                 ?? new File(
149                     FileSystem::normalizeDirSeparator($sourceAbsoluteFilepath),
150                     $vendorRelativePath,
151                     $targetAbsolutePath
152                 );
153        }
154
155        $this->discoveredFiles->add($f);
156
157        $vendorRelativeFilePath =
158            $this->filesystem->getRelativePath(
159                $this->config->getProjectAbsolutePath(),
160                $f->getSourcePath()
161            );
162        $this->logger->info("Found file " . $vendorRelativeFilePath);
163    }
164}