Skip to content

Commit 14e1d53

Browse files
authored
Fix: Changes in subdirectories are not detected (#13)
1 parent 83eaa34 commit 14e1d53

File tree

5 files changed

+56
-11
lines changed

5 files changed

+56
-11
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ test-cleanup:
3333
@rm -rf tests/sandbox/*
3434

3535
.PHONY: test-container
36-
test-container: test-container82
36+
test-container: test-container80
3737

3838
.PHONY: test-container80
3939
test-container80:

src/MemoizeClassMapGenerator.php

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Composer\ClassMapGenerator\ClassMapGenerator;
66
use Composer\IO\IOInterface;
7+
use DirectoryIterator;
78
use RuntimeException;
89

910
use function array_filter;
@@ -89,13 +90,9 @@ public function scanPaths(
8990
?string $namespace = null
9091
): void {
9192
$this->paths[$path] = true;
92-
[ $timestamp ] = $this->state[$path] ?? [ 0, [ ] ];
93+
[ $timestamp ] = $this->state[$path] ?? [ 0 ];
9394

94-
$mtime = filemtime($path);
95-
assert(is_int($mtime));
96-
97-
if ($timestamp < $mtime) {
98-
$this->io->debug("Refresh class map for path '$path' ($timestamp < $mtime)");
95+
if ($this->should_update($timestamp, $path)) {
9996
$inner = new ClassMapGenerator();
10097
$inner->avoidDuplicateScans();
10198
$inner->scanPaths($path, $excluded, $autoloadType, $namespace);
@@ -104,4 +101,32 @@ public function scanPaths(
104101
$this->state[$path] = [ time(), $map ];
105102
}
106103
}
104+
105+
private function should_update(int $timestamp, string $path): bool
106+
{
107+
if (!$timestamp) {
108+
return true;
109+
}
110+
111+
$mtime = filemtime($path);
112+
113+
assert(is_int($mtime));
114+
115+
if ($timestamp < $mtime) {
116+
$diff = $mtime - $timestamp;
117+
$this->io->debug("Refresh class map for path '$path' ($diff sec ago)");
118+
119+
return true;
120+
}
121+
122+
foreach (new DirectoryIterator($path) as $di) {
123+
if ($di->isDir() && !$di->isDot()) {
124+
if ($this->should_update($timestamp, $di->getPathname())) {
125+
return true;
126+
}
127+
}
128+
}
129+
130+
return false;
131+
}
107132
}

tests/MemoizeClassMapGeneratorTest.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
use olvlvl\ComposerAttributeCollector\MemoizeClassMapGenerator;
88
use PHPUnit\Framework\TestCase;
99

10+
use function file_exists;
1011
use function file_put_contents;
1112
use function time;
1213
use function touch;
14+
use function unlink;
1315

1416
final class MemoizeClassMapGeneratorTest extends TestCase
1517
{
@@ -19,14 +21,24 @@ protected function setUp(): void
1921
{
2022
parent::setUp();
2123

22-
clear_directory(self::DIR);
24+
$remove = [
25+
self::DIR . 'a.php',
26+
self::DIR . 'a/b/c/b.php',
27+
];
28+
29+
foreach ($remove as $filename) {
30+
if (file_exists($filename)) {
31+
unlink($filename);
32+
}
33+
}
2334
}
2435

2536
public function testMemoize(): void
2637
{
2738
$map = $this->map();
2839
$this->assertEmpty($map);
2940

41+
// check changes in the directory are detected
3042
self::write(
3143
"a.php",
3244
<<<PHP
@@ -45,8 +57,9 @@ class A {
4557
'App\A' => self::DIR . 'a.php',
4658
], $map);
4759

60+
// check changes in subdirectories are detected
4861
self::write(
49-
"b.php",
62+
"a/b/c/b.php",
5063
<<<PHP
5164
<?php
5265
@@ -61,7 +74,7 @@ class B {
6174
$map = $this->map();
6275
$this->assertEquals([
6376
'App\A' => self::DIR . 'a.php',
64-
'App\B' => self::DIR . 'b.php',
77+
'App\B' => self::DIR . 'a/b/c/b.php',
6578
], $map);
6679
}
6780

tests/bootstrap.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
require_once __DIR__ . '/../vendor/autoload.php';
1515

16+
/**
17+
* @return non-empty-string
18+
*/
1619
function get_cache_dir(): string
1720
{
1821
$dir = dirname(__DIR__) . '/.composer-attribute-collector';
@@ -24,8 +27,10 @@ function get_cache_dir(): string
2427
return $dir;
2528
}
2629

27-
/*
30+
/**
2831
* Clean up cache
32+
*
33+
* @param non-empty-string $dir
2934
*/
3035
function clear_directory(string $dir): void
3136
{
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

0 commit comments

Comments
 (0)