44
55namespace Efabrica \PHPStanLatte \Temp ;
66
7+ use FilesystemIterator ;
8+ use Nette \Utils \FileSystem ;
9+ use RecursiveDirectoryIterator ;
10+ use RecursiveIteratorIterator ;
711use RuntimeException ;
12+ use SplFileInfo ;
813
914final class TempDirResolver
1015{
16+ private const MAX_AGE = 7 * 24 * 60 * 60 ; // one week
17+ private const MAX_SIZE = 100 * 1024 * 1024 ; // 100 MB
18+
1119 private string $ tmpDir ;
1220
1321 public function __construct (?string $ tmpDir )
1422 {
1523 $ tmpDir = $ tmpDir ? rtrim ($ tmpDir , DIRECTORY_SEPARATOR ) : sys_get_temp_dir () . '/phpstan-latte ' ;
24+
25+ if (is_dir ($ tmpDir ) &&
26+ (time () - (int )filemtime ($ tmpDir ) > self ::MAX_AGE ||
27+ $ this ->getDirTotalSize ($ tmpDir ) > self ::MAX_SIZE )
28+ ) {
29+ $ this ->pruneDir ($ tmpDir );
30+ }
31+
1632 if (!is_dir ($ tmpDir )) {
17- if (!@mkdir ($ tmpDir ) && !is_dir ($ tmpDir )) {
18- throw new RuntimeException (sprintf ('Cannot create temp dir "%s" ' , $ tmpDir ));
19- }
33+ Filesystem::createDir ($ tmpDir );
2034 }
2135 $ tmpDir = realpath ($ tmpDir ) ?: $ tmpDir ;
2236 if (!is_writable ($ tmpDir )) {
@@ -39,4 +53,26 @@ public function resolveCollectorDir(): string
3953 {
4054 return $ this ->tmpDir . DIRECTORY_SEPARATOR . 'collector-cache ' . DIRECTORY_SEPARATOR ;
4155 }
56+
57+ private function pruneDir (string $ tmpDir ): void
58+ {
59+ $ ri = new RecursiveIteratorIterator (
60+ new RecursiveDirectoryIterator ($ tmpDir , FilesystemIterator::SKIP_DOTS ),
61+ RecursiveIteratorIterator::CHILD_FIRST
62+ );
63+ /** @var SplFileInfo $file */
64+ foreach ($ ri as $ file ) {
65+ Filesystem::delete ($ file ->getPathname ());
66+ }
67+ }
68+
69+ private function getDirTotalSize (string $ tmpDir ): int
70+ {
71+ $ size = 0 ;
72+ /** @var SplFileInfo $file */
73+ foreach (new RecursiveIteratorIterator (new RecursiveDirectoryIterator ($ tmpDir , FilesystemIterator::SKIP_DOTS )) as $ file ) {
74+ $ size += $ file ->getSize ();
75+ }
76+ return $ size ;
77+ }
4278}
0 commit comments