Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 67 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
FileEnumerator | |
0.00% |
0 / 67 |
|
0.00% |
0 / 4 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
compileFileListForDependencies | |
0.00% |
0 / 33 |
|
0.00% |
0 / 1 |
182 | |||
addFileWithDependency | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
12 | |||
compileFileListForPaths | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * Build a list of files from the composer autoloaders. |
4 | * |
5 | * Also record the `files` autoloaders. |
6 | */ |
7 | |
8 | namespace BrianHenryIE\Strauss\Pipeline; |
9 | |
10 | use BrianHenryIE\Strauss\Composer\ComposerPackage; |
11 | use BrianHenryIE\Strauss\Config\FileEnumeratorConfig; |
12 | use BrianHenryIE\Strauss\Files\DiscoveredFiles; |
13 | use BrianHenryIE\Strauss\Files\File; |
14 | use BrianHenryIE\Strauss\Files\FileWithDependency; |
15 | use BrianHenryIE\Strauss\Helpers\FileSystem; |
16 | use League\Flysystem\FilesystemException; |
17 | use Psr\Log\LoggerAwareTrait; |
18 | use Psr\Log\LoggerInterface; |
19 | use Psr\Log\NullLogger; |
20 | |
21 | class FileEnumerator |
22 | { |
23 | use LoggerAwareTrait; |
24 | |
25 | protected string $vendorDir; |
26 | |
27 | /** @var string[] */ |
28 | protected array $excludePackageNames = array(); |
29 | |
30 | /** @var string[] */ |
31 | protected array $excludeNamespaces = array(); |
32 | |
33 | /** @var string[] */ |
34 | protected array $excludeFilePatterns = array(); |
35 | |
36 | protected Filesystem $filesystem; |
37 | |
38 | protected DiscoveredFiles $discoveredFiles; |
39 | |
40 | /** |
41 | * Record the files autoloaders for later use in building our own autoloader. |
42 | * |
43 | * Package-name: [ dir1, file1, file2, ... ]. |
44 | * |
45 | * @var array<string, string[]> |
46 | */ |
47 | protected array $filesAutoloaders = []; |
48 | |
49 | protected FileEnumeratorConfig $config; |
50 | |
51 | /** |
52 | * Copier constructor. |
53 | */ |
54 | public function __construct( |
55 | FileEnumeratorConfig $config, |
56 | FileSystem $filesystem, |
57 | ?LoggerInterface $logger = null |
58 | ) { |
59 | $this->discoveredFiles = new DiscoveredFiles(); |
60 | |
61 | $this->vendorDir = $config->getVendorDirectory(); |
62 | |
63 | $this->config = $config; |
64 | |
65 | $this->excludeNamespaces = $config->getExcludeNamespacesFromCopy(); |
66 | $this->excludePackageNames = $config->getExcludePackagesFromCopy(); |
67 | $this->excludeFilePatterns = $config->getExcludeFilePatternsFromCopy(); |
68 | |
69 | $this->filesystem = $filesystem; |
70 | |
71 | $this->logger = $logger ?? new NullLogger(); |
72 | } |
73 | |
74 | /** |
75 | * Read the autoload keys of the dependencies and generate a list of the files referenced. |
76 | * |
77 | * Includes all files in the directories and subdirectories mentioned in the autoloaders. |
78 | * |
79 | * @param ComposerPackage[] $dependencies |
80 | */ |
81 | public function compileFileListForDependencies(array $dependencies): DiscoveredFiles |
82 | { |
83 | foreach ($dependencies as $dependency) { |
84 | $this->logger->info("Scanning for files for package " . $dependency->getPackageName()); |
85 | |
86 | /** |
87 | * Where $dependency->autoload is ~ |
88 | * |
89 | * [ "psr-4" => [ "BrianHenryIE\Strauss" => "src" ] ] |
90 | * Exclude "exclude-from-classmap" |
91 | * @see https://getcomposer.org/doc/04-schema.md#exclude-files-from-classmaps |
92 | */ |
93 | $autoloaders = array_filter($dependency->getAutoload(), function ($type) { |
94 | return 'exclude-from-classmap' !== $type; |
95 | }, ARRAY_FILTER_USE_KEY); |
96 | |
97 | foreach ($autoloaders as $type => $value) { |
98 | // Might have to switch/case here. |
99 | |
100 | if ('files' === $type) { |
101 | // TODO: This is not in use. |
102 | $this->filesAutoloaders[$dependency->getRelativePath()] = $value; |
103 | } |
104 | |
105 | foreach ($value as $namespace => $namespace_relative_paths) { |
106 | if (!empty($namespace) && in_array($namespace, $this->excludeNamespaces)) { |
107 | $this->logger->info("Excluding namespace " . $namespace); |
108 | continue; |
109 | } |
110 | |
111 | $namespace_relative_paths = (array) $namespace_relative_paths; |
112 | // if (! is_array($namespace_relative_paths)) { |
113 | // $namespace_relative_paths = array( $namespace_relative_paths ); |
114 | // } |
115 | |
116 | foreach ($namespace_relative_paths as $namespaceRelativePath) { |
117 | $sourceAbsoluteDirPath = in_array($namespaceRelativePath, ['.','./']) |
118 | ? $dependency->getPackageAbsolutePath() |
119 | : $dependency->getPackageAbsolutePath() . $namespaceRelativePath; |
120 | |
121 | if ($this->filesystem->directoryExists($sourceAbsoluteDirPath)) { |
122 | $fileList = $this->filesystem->listContents($sourceAbsoluteDirPath, true); |
123 | $actualFileList = $fileList->toArray(); |
124 | |
125 | foreach ($actualFileList as $foundFile) { |
126 | $sourceAbsoluteFilepath = '/'. $foundFile->path(); |
127 | // No need to record the directory itself. |
128 | if (!$this->filesystem->fileExists($sourceAbsoluteFilepath) |
129 | || |
130 | $this->filesystem->directoryExists($sourceAbsoluteFilepath) |
131 | ) { |
132 | continue; |
133 | } |
134 | |
135 | $this->addFileWithDependency( |
136 | $dependency, |
137 | $sourceAbsoluteFilepath, |
138 | $type |
139 | ); |
140 | } |
141 | } else { |
142 | $this->addFileWithDependency($dependency, $sourceAbsoluteDirPath, $type); |
143 | } |
144 | } |
145 | } |
146 | } |
147 | } |
148 | |
149 | $this->discoveredFiles->sort(); |
150 | return $this->discoveredFiles; |
151 | } |
152 | |
153 | /** |
154 | * @param ComposerPackage $dependency |
155 | * @param string $sourceAbsoluteFilepath |
156 | * @param string $autoloaderType |
157 | * |
158 | * @throws FilesystemException |
159 | * @uses \BrianHenryIE\Strauss\Files\DiscoveredFiles::add() |
160 | * |
161 | */ |
162 | protected function addFileWithDependency( |
163 | ComposerPackage $dependency, |
164 | string $sourceAbsoluteFilepath, |
165 | string $autoloaderType |
166 | ): void { |
167 | $vendorRelativePath = substr( |
168 | $sourceAbsoluteFilepath, |
169 | strpos($sourceAbsoluteFilepath, $dependency->getRelativePath() ?: 0) |
170 | ); |
171 | |
172 | if ($vendorRelativePath === $sourceAbsoluteFilepath) { |
173 | $vendorRelativePath = $dependency->getRelativePath() . str_replace($dependency->getPackageAbsolutePath(), '', $sourceAbsoluteFilepath); |
174 | } |
175 | |
176 | $isOutsideProjectDir = 0 !== strpos($sourceAbsoluteFilepath, $this->config->getVendorDirectory()); |
177 | |
178 | /** @var FileWithDependency $f */ |
179 | $f = $this->discoveredFiles->getFile($sourceAbsoluteFilepath) |
180 | ?? new FileWithDependency($dependency, $vendorRelativePath, $sourceAbsoluteFilepath); |
181 | |
182 | $f->setAbsoluteTargetPath($this->config->getVendorDirectory() . $vendorRelativePath); |
183 | |
184 | $f->addAutoloader($autoloaderType); |
185 | $f->setDoDelete($isOutsideProjectDir); |
186 | |
187 | $this->discoveredFiles->add($f); |
188 | |
189 | $relativeFilePath = |
190 | $this->filesystem->getRelativePath( |
191 | dirname($this->config->getVendorDirectory()), |
192 | $f->getAbsoluteTargetPath() |
193 | ); |
194 | $this->logger->info("Found file " . $relativeFilePath); |
195 | } |
196 | |
197 | /** |
198 | * @param string[] $paths |
199 | */ |
200 | public function compileFileListForPaths(array $paths): DiscoveredFiles |
201 | { |
202 | $absoluteFilePaths = $this->filesystem->findAllFilesAbsolutePaths($paths); |
203 | |
204 | foreach ($absoluteFilePaths as $sourceAbsolutePath) { |
205 | $f = $this->discoveredFiles->getFile($sourceAbsolutePath) |
206 | ?? new File($sourceAbsolutePath); |
207 | |
208 | $this->discoveredFiles->add($f); |
209 | } |
210 | |
211 | $this->discoveredFiles->sort(); |
212 | return $this->discoveredFiles; |
213 | } |
214 | } |