-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathDirectorySolution.php
More file actions
134 lines (117 loc) 路 4.14 KB
/
Copy pathDirectorySolution.php
File metadata and controls
134 lines (117 loc) 路 4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
declare(strict_types=1);
namespace PhpSchool\PhpWorkshop\Solution;
use InvalidArgumentException;
use RecursiveCallbackFilterIterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;
/**
* Solution which can contain multiple files, the file to execute is defined as the entry point.
*/
class DirectorySolution implements SolutionInterface
{
/**
* @var SolutionFile
*/
private $entryPoint;
/**
* @var array<SolutionFile>
*/
private $files;
/**
* @var string
*/
private $baseDirectory;
/**
* Build an instance from a given directory. Requires a file name to be used as the entry point,
* and optionally can take an array of files to exclude from the solution. For example you may want to
* ignore some dot files or `composer.lock`.
*
* @param string $directory The directory to search for files.
* @param string $entryPoint The relative path from the directory of the entry point file.
* @param array<string> $exclusions An array of file names to exclude from the folder.
* @throws InvalidArgumentException If the entry point does not exist in the folder.
*/
public function __construct(string $directory, string $entryPoint, array $exclusions = [])
{
$directory = (string) realpath(rtrim($directory, '/'));
$entryPoint = ltrim($entryPoint, '/');
$dir = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
$iter = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator($dir, function (SplFileInfo $current) use ($exclusions) {
return !in_array($current->getBasename(), $exclusions, true);
}),
RecursiveIteratorIterator::SELF_FIRST,
);
$files = [];
foreach ($iter as $file) {
/** @var \SplFileInfo $file */
if ($file->isFile()) {
$files[] = trim(substr($file->getPathname(), strlen($directory)), '/');
}
}
sort($files);
if (!in_array($entryPoint, $files, true)) {
throw new InvalidArgumentException(
sprintf('Entry point: "%s" does not exist in: "%s"', $entryPoint, $directory),
);
}
$this->files = array_map(function ($file) use ($directory) {
return new SolutionFile($file, $directory);
}, $files);
$this->entryPoint = array_values(array_filter($this->files, function (SolutionFile $file) use ($entryPoint) {
return $file->getRelativePath() === $entryPoint;
}))[0];
$this->baseDirectory = $directory;
}
/**
* Static constructor to build an instance from a directory.
*
* @param string $directory The directory to search for files.
* @param array<string> $exclusions An array of file names to exclude from the folder.
* @param string $entryPoint The relative path from the directory of the entry point file.
* @return self
*/
public static function fromDirectory(string $directory, array $exclusions = [], $entryPoint = 'solution.php'): self
{
return new self($directory, $entryPoint, array_merge($exclusions, ['composer.lock', 'vendor']));
}
/**
* Get the entry point. This is the PHP file that PHO would execute in order to run the
* program.
*
* @return SolutionFile
*/
public function getEntryPoint(): SolutionFile
{
return $this->entryPoint;
}
/**
* Get all the files which are contained with the solution.
*
* @return array<SolutionFile>
*/
public function getFiles(): array
{
return $this->files;
}
/**
* Get the absolute path to the directory containing the solution.
*
* @return string
*/
public function getBaseDirectory(): string
{
return $this->baseDirectory;
}
/**
* Check whether there is a `composer.json` file in the base directory.
*
* @return bool
*/
public function hasComposerFile(): bool
{
return file_exists(sprintf('%s/composer.json', $this->baseDirectory));
}
}