99use Toolkit \Stdlib \Str ;
1010use function array_merge ;
1111use function is_int ;
12- use function printf ;
1312use function println ;
13+ use function str_replace ;
1414use function trim ;
1515
1616/**
@@ -58,6 +58,13 @@ class FileTreeBuilder extends AbstractObj
5858 */
5959 public string $ tplDir = '' ;
6060
61+ /**
62+ * Callable on after file copied.
63+ *
64+ * @var callable(string $newFile): void
65+ */
66+ public $ afterCopy ;
67+
6168 /**
6269 * @param string $dir
6370 *
@@ -85,15 +92,41 @@ public function copy(string $srcFile, string $dstFile, ?callable $afterFn = null
8592 if ($ afterFn !== null ) {
8693 $ afterFn ($ dstFile );
8794 }
95+
96+ if ($ fn = $ this ->afterCopy ) {
97+ $ fn ($ dstFile );
98+ }
99+
88100 return $ this ;
89101 }
90102
91103 /**
104+ * Copy all files in dir to dst dir
105+ *
106+ * ### Exclude files:
107+ *
108+ * ```php
109+ * $ftb->copyDir('path/to/template dir', './', [
110+ * 'exclude' => ['*.tpl'],
111+ * ])
112+ * ```
113+ *
114+ * ### Adv Usage:
115+ *
116+ * ```php
117+ * $ftb->copyDir('path/to/template dir', './', [
118+ * 'afterFn' => function (string $newFile) use ($ftb) {
119+ * // render vars in the match file
120+ * $ftb->renderOnMatch($newFile, ['*.java']);
121+ * },
122+ * ])
123+ * ```
124+ *
92125 * @param string $srcDir source dir path.
93126 * @param string $dstDir dst dir path, default relative the workDir.
94127 * @param array $options = [
95- * 'include' => [], //
96- * 'exclude' => [], //
128+ * 'include' => [], // limit copy files
129+ * 'exclude' => [], // can exclude files on copy
97130 * 'afterFn' => function(string $newFile) {},
98131 * ]
99132 *
@@ -123,7 +156,15 @@ public function copyDir(string $srcDir, string $dstDir, array $options = []): se
123156
124157 return !File::isExclude ($ oldFile , $ options ['exclude ' ]);
125158 },
126- 'afterFn ' => $ options ['afterFn ' ],
159+ 'afterFn ' => function (string $ newFile ) use ($ options ) {
160+ if ($ fn = $ options ['afterFn ' ]) {
161+ $ fn ($ newFile );
162+ }
163+
164+ if ($ fn = $ this ->afterCopy ) {
165+ $ fn ($ newFile );
166+ }
167+ },
127168 ]);
128169
129170 return $ this ;
@@ -150,6 +191,8 @@ public function file(string $name, string $contents = ''): self
150191 }
151192
152193 /**
194+ * Create multi files at once.
195+ *
153196 * @param array $files file paths, default relative the workDir.
154197 * @param string $contents
155198 *
@@ -261,39 +304,84 @@ public function dirFiles(string $name, string ...$files): self
261304 *
262305 * @return $this
263306 */
264- public function globRender (string $ pattern , array $ tplVars = []): self
307+ public function renderByGlob (string $ pattern , array $ tplVars = []): self
265308 {
266309 foreach (glob ($ pattern ) as $ tplFile ) {
267310 $ this ->tplFile ($ tplFile , '' , $ tplVars );
268311 }
269312 return $ this ;
270313 }
271314
315+ /**
316+ * Render give file on match patterns.
317+ *
318+ * @param string $tplFile
319+ * @param array $patterns
320+ * @param array $tplVars
321+ *
322+ * @return $this
323+ */
324+ public function renderOnMatch (string $ tplFile , array $ patterns , array $ tplVars = []): self
325+ {
326+ if (File::isInclude ($ tplFile , $ patterns )) {
327+ $ this ->tplFile ($ tplFile , '' , $ tplVars );
328+ }
329+ return $ this ;
330+ }
331+
332+ /**
333+ * Render template vars in the give file, will update file contents to rendered.
334+ *
335+ * @param string $tplFile
336+ * @param array $tplVars
337+ *
338+ * @return $this
339+ */
340+ public function renderFile (string $ tplFile , array $ tplVars = []): self
341+ {
342+ return $ this ->tplFile ($ tplFile , '' , $ tplVars );
343+ }
344+
272345 /**
273346 * Create file from a template file
274347 *
275348 * @param string $tplFile tpl file path, relative the tplDir.
276- * @param string $dstFile Dst file path, relative the workdir. If empty, use $tplFile
349+ * @param string $dstFile Dst file path, relative the workdir. If empty, use $tplFile for update.
277350 * @param array $tplVars
278351 *
279352 * @return $this
280353 */
281354 public function tplFile (string $ tplFile , string $ dstFile = '' , array $ tplVars = []): self
282355 {
283356 Assert::notBlank ($ tplFile );
284-
285357 $ dstFile = $ this ->getRealpath ($ dstFile ?: $ tplFile );
358+
286359 if (!File::isAbsPath ($ tplFile )) {
287- $ tplFile = $ this ->tplDir . '/ ' . $ tplFile ;
360+ $ tplFile = $ this ->tplDir . '/ ' . $ tplFile ;
288361 }
289362
290363 $ this ->printMsgf ('render file: %s ' , $ tplFile );
291364 if ($ this ->tplVars ) {
292365 $ tplVars = array_merge ($ this ->tplVars , $ tplVars );
293366 }
294367
295- $ content = Str::renderTemplate (File::readAll ($ tplFile ), $ tplVars );
368+ return $ this ->doRender ($ tplFile , $ dstFile , $ tplVars );
369+ }
370+
371+ /**
372+ * Do render template file
373+ *
374+ * @param string $tplFile
375+ * @param string $dstFile
376+ * @param array $tplVars
377+ *
378+ * @return $this
379+ */
380+ protected function doRender (string $ tplFile , string $ dstFile , array $ tplVars = []): self
381+ {
296382 if (!$ this ->dryRun ) {
383+ $ content = Str::renderTemplate (File::readAll ($ tplFile ), $ tplVars );
384+
297385 File::putContents ($ dstFile , $ content );
298386 }
299387
@@ -434,7 +522,7 @@ protected function printMsg(string $msg): void
434522 $ msg = '[DRY-RUN] ' . $ msg ;
435523 }
436524
437- println ($ msg );
525+ println (str_replace ( $ this -> baseDir , ' {projectDir} ' , $ msg) );
438526 }
439527 }
440528
@@ -451,7 +539,7 @@ protected function printMsgf(string $tpl, ...$vars): void
451539 $ tpl = '[DRY-RUN] ' . $ tpl ;
452540 }
453541
454- printf ( $ tpl . "\n" , ...$ vars );
542+ println ( str_replace ( $ this -> baseDir , ' {projectDir} ' , sprintf ( $ tpl , ...$ vars)) );
455543 }
456544 }
457545
@@ -466,4 +554,15 @@ public function setTplVars(array $tplVars): self
466554 return $ this ;
467555 }
468556
557+ /**
558+ * @param callable(string $newFile): void $afterCopy
559+ *
560+ * @return FileTreeBuilder
561+ */
562+ public function setAfterCopy (callable $ afterCopy ): self
563+ {
564+ $ this ->afterCopy = $ afterCopy ;
565+ return $ this ;
566+ }
567+
469568}
0 commit comments