1
|
|
|
<?php |
2
|
|
|
namespace Naneau\FileGen; |
3
|
|
|
|
4
|
|
|
use Naneau\FileGen\Parameterized; |
5
|
|
|
|
6
|
|
|
use Naneau\FileGen\Directory; |
7
|
|
|
use Naneau\FileGen\File; |
8
|
|
|
use Naneau\FileGen\SymLink; |
9
|
|
|
|
10
|
|
|
use Naneau\FileGen\Generator\Exception as GeneratorException; |
11
|
|
|
use Naneau\FileGen\Generator\Exception\NodeExists as NodeExistsException; |
12
|
|
|
|
13
|
|
|
use Symfony\Component\Filesystem\Filesystem; |
14
|
|
|
use Symfony\Component\Filesystem\Exception\IOException as FilesystemIOException; |
15
|
|
|
|
16
|
|
|
use \InvalidArgumentException; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* The generator takes directory structures and actually creates them on disk |
20
|
|
|
*/ |
21
|
|
|
class Generator implements Parameterized |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* Root of the generation |
25
|
|
|
* |
26
|
|
|
* @var string |
27
|
|
|
**/ |
28
|
|
|
private $root; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* The parameters |
32
|
|
|
* |
33
|
|
|
* @var array[string][string] |
34
|
|
|
**/ |
35
|
|
|
private $parameters; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* The symfony filesystem |
39
|
|
|
* |
40
|
|
|
* @var Filesystem |
41
|
|
|
**/ |
42
|
|
|
private $fileSystem; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Constructor |
46
|
|
|
* |
47
|
|
|
* @param string $root |
48
|
|
|
* @param array[string]string $parameters |
|
|
|
|
49
|
|
|
* @return void |
|
|
|
|
50
|
|
|
**/ |
51
|
|
|
public function __construct($root, array $parameters = array()) |
52
|
|
|
{ |
53
|
|
|
$this |
54
|
|
|
->setRoot($root) |
55
|
|
|
->setParameters($parameters) |
56
|
|
|
->setFilesystem(new Filesystem); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Generate a Structure on disk |
61
|
|
|
* |
62
|
|
|
* @param Structure $directory |
|
|
|
|
63
|
|
|
* @return bool |
64
|
|
|
**/ |
65
|
|
|
public function generate(Structure $structure) |
66
|
|
|
{ |
67
|
|
|
foreach ($structure as $node) { |
68
|
|
|
$this->createNode($node); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
return true; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Get the root directory |
76
|
|
|
* |
77
|
|
|
* @return string |
78
|
|
|
*/ |
79
|
|
|
public function getRoot() |
80
|
|
|
{ |
81
|
|
|
return $this->root; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Set the root directory |
86
|
|
|
* |
87
|
|
|
* @param string $root |
88
|
|
|
* @return Generator |
89
|
|
|
*/ |
90
|
|
|
public function setRoot($root) |
91
|
|
|
{ |
92
|
|
|
$this->root = $root; |
93
|
|
|
|
94
|
|
|
return $this; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Get the parameters |
99
|
|
|
* |
100
|
|
|
* @return array[string]string |
|
|
|
|
101
|
|
|
*/ |
102
|
|
|
public function getParameters() |
103
|
|
|
{ |
104
|
|
|
return $this->parameters; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Set the parameters |
109
|
|
|
* |
110
|
|
|
* @param array[string]string $parameters |
|
|
|
|
111
|
|
|
* @return Generator |
112
|
|
|
*/ |
113
|
|
|
public function setParameters(array $parameters) |
114
|
|
|
{ |
115
|
|
|
$this->parameters = $parameters; |
116
|
|
|
|
117
|
|
|
return $this; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Get the file system |
122
|
|
|
* |
123
|
|
|
* @return Filesystem |
124
|
|
|
*/ |
125
|
|
|
public function getFilesystem() |
126
|
|
|
{ |
127
|
|
|
return $this->fileSystem; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Set the file system |
132
|
|
|
* |
133
|
|
|
* @param Filesystem $fileSystem |
134
|
|
|
* @return Generator |
135
|
|
|
*/ |
136
|
|
|
public function setFilesystem(Filesystem $fileSystem) |
137
|
|
|
{ |
138
|
|
|
$this->fileSystem = $fileSystem; |
139
|
|
|
|
140
|
|
|
return $this; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Create a node |
145
|
|
|
* |
146
|
|
|
* @param Node $node |
147
|
|
|
* @return bool |
148
|
|
|
**/ |
149
|
|
|
private function createNode(Node $node) |
150
|
|
|
{ |
151
|
|
|
// See if it exists |
152
|
|
|
if (file_exists($this->getNodePath($node))) { |
153
|
|
|
throw new NodeExistsException(sprintf( |
154
|
|
|
'Node "%s" exists, can not create it', |
155
|
|
|
$this->getNodePath($node) |
156
|
|
|
)); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
if ($node instanceof File) { |
160
|
|
|
return $this->createFile($node); |
161
|
|
|
} elseif ($node instanceof SymLink) { |
162
|
|
|
return $this->createLink($node); |
163
|
|
|
} elseif ($node instanceof Directory) { |
164
|
|
|
return $this->createDirectory($node); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
throw new InvalidArgumentException('Invalid node type'); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Create a file |
172
|
|
|
* |
173
|
|
|
* @param File $file |
174
|
|
|
* @return bool |
175
|
|
|
**/ |
176
|
|
View Code Duplication |
private function createFile(File $file) |
|
|
|
|
177
|
|
|
{ |
178
|
|
|
// Full path to the file |
179
|
|
|
$fullPath = $this->getNodePath($file); |
180
|
|
|
|
181
|
|
|
// Generate contents |
182
|
|
|
$contents = $file->getContents($this->getParameters()); |
183
|
|
|
|
184
|
|
|
try { |
185
|
|
|
$this->getFilesystem()->dumpFile($fullPath, $contents); |
186
|
|
|
if ($file->hasMode()) { |
187
|
|
|
$this->getFilesystem()->chmod($fullPath, $file->getMode()); |
188
|
|
|
} |
189
|
|
|
} catch (FilesystemIOException $filesystemException) { |
190
|
|
|
throw new GeneratorException( |
191
|
|
|
sprintf( |
192
|
|
|
'Could not generate file "%s"', |
193
|
|
|
$fullPath |
194
|
|
|
), |
195
|
|
|
0, |
196
|
|
|
$filesystemException |
197
|
|
|
); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
return $this; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Create a directory |
205
|
|
|
* |
206
|
|
|
* @param Directory $directory |
207
|
|
|
* @return Generator |
208
|
|
|
**/ |
209
|
|
View Code Duplication |
private function createDirectory(Directory $directory) |
|
|
|
|
210
|
|
|
{ |
211
|
|
|
$fullPath = $this->getNodePath($directory); |
212
|
|
|
|
213
|
|
|
// Try to make it |
214
|
|
|
try { |
215
|
|
|
if ($directory->hasMode()) { |
216
|
|
|
$this->getFilesystem()->mkdir($fullPath, $directory->getMode()); |
217
|
|
|
} else { |
218
|
|
|
$this->getFilesystem()->mkdir($fullPath); |
219
|
|
|
} |
220
|
|
|
} catch (FilesystemIOException $filesystemException) { |
221
|
|
|
throw new GeneratorException( |
222
|
|
|
sprintf( |
223
|
|
|
'Could not generate directory "%s"', |
224
|
|
|
$this->getNodePath($directory) |
225
|
|
|
), |
226
|
|
|
0, |
227
|
|
|
$filesystemException |
228
|
|
|
); |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
// Recurse child nodes |
232
|
|
|
foreach ($directory as $node) { |
233
|
|
|
$this->createNode($node); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
return $this; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Create a symlink |
241
|
|
|
* |
242
|
|
|
* @param SymLink $link |
243
|
|
|
* @return Generator |
244
|
|
|
**/ |
245
|
|
|
private function createLink(SymLink $link) |
246
|
|
|
{ |
247
|
|
|
$fullToPath = $this->getNodePath($link); |
248
|
|
|
$fullFromPath = $link->getEndpoint(); |
249
|
|
|
|
250
|
|
|
// Endpoint needs to exist |
251
|
|
|
if (!file_exists($fullFromPath)) { |
252
|
|
|
throw new GeneratorException(sprintf( |
253
|
|
|
'Can not create symlink "%s", endpoint "%s" does not exist', |
254
|
|
|
$fullToPath, |
255
|
|
|
$fullFromPath |
256
|
|
|
)); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
// Try to link it |
260
|
|
|
try { |
261
|
|
|
$this->getFilesystem()->symlink($fullFromPath, $fullToPath); |
262
|
|
|
} catch (FilesystemIOException $filesystemException) { |
263
|
|
|
throw new GeneratorException( |
264
|
|
|
sprintf( |
265
|
|
|
'Can not create symlink "%s", with endpoint "%s"', |
266
|
|
|
$fullToPath, |
267
|
|
|
$fullFromPath |
268
|
|
|
), |
269
|
|
|
0, |
270
|
|
|
$filesystemException |
271
|
|
|
); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
return $this; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Get the full path to a node, including the root path |
279
|
|
|
* |
280
|
|
|
* @see getRoot() |
281
|
|
|
* |
282
|
|
|
* @param Node $node |
283
|
|
|
* @return string |
284
|
|
|
**/ |
285
|
|
|
private function getNodePath(Node $node) |
286
|
|
|
{ |
287
|
|
|
return $this->getRoot() |
288
|
|
|
. DIRECTORY_SEPARATOR |
289
|
|
|
. trim($node->getFullName(DIRECTORY_SEPARATOR), DIRECTORY_SEPARATOR); |
290
|
|
|
} |
291
|
|
|
} |
292
|
|
|
|
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.