Skip to content

Commit f4b03ae

Browse files
committed
Introduce standalone DirDiff util class
1 parent f6b0914 commit f4b03ae

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

src/SPC/store/DirDiff.php

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SPC\store;
6+
7+
/**
8+
* A util class to diff directory file increments.
9+
*/
10+
class DirDiff
11+
{
12+
protected array $before = [];
13+
14+
protected array $before_file_hashes = [];
15+
16+
public function __construct(protected string $dir, protected bool $track_content_changes = false)
17+
{
18+
$this->reset();
19+
}
20+
21+
/**
22+
* Reset the baseline to current state.
23+
*/
24+
public function reset(): void
25+
{
26+
$this->before = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
27+
28+
if ($this->track_content_changes) {
29+
$this->before_file_hashes = [];
30+
foreach ($this->before as $file) {
31+
$this->before_file_hashes[$file] = md5_file($this->dir . DIRECTORY_SEPARATOR . $file);
32+
}
33+
}
34+
}
35+
36+
/**
37+
* Get the list of incremented files.
38+
*
39+
* @param bool $relative Return relative paths or absolute paths
40+
* @return array<string> List of incremented files
41+
*/
42+
public function getIncrementFiles(bool $relative = false): array
43+
{
44+
$after = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
45+
$diff = array_diff($after, $this->before);
46+
if ($relative) {
47+
return $diff;
48+
}
49+
return array_map(fn ($f) => $this->dir . DIRECTORY_SEPARATOR . $f, $diff);
50+
}
51+
52+
/**
53+
* Get the list of changed files (including new files).
54+
*
55+
* @param bool $relative Return relative paths or absolute paths
56+
* @param bool $include_new_files Include new files as changed files
57+
* @return array<string> List of changed files
58+
*/
59+
public function getChangedFiles(bool $relative = false, bool $include_new_files = true): array
60+
{
61+
$after = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
62+
$changed = [];
63+
foreach ($after as $file) {
64+
if (isset($this->before_file_hashes[$file])) {
65+
$after_hash = md5_file($this->dir . DIRECTORY_SEPARATOR . $file);
66+
if ($after_hash !== $this->before_file_hashes[$file]) {
67+
$changed[] = $file;
68+
}
69+
} elseif ($include_new_files) {
70+
// New file, consider as changed
71+
$changed[] = $file;
72+
}
73+
}
74+
if ($relative) {
75+
return $changed;
76+
}
77+
return array_map(fn ($f) => $this->dir . DIRECTORY_SEPARATOR . $f, $changed);
78+
}
79+
80+
/**
81+
* Get the list of removed files.
82+
*
83+
* @param bool $relative Return relative paths or absolute paths
84+
* @return array<string> List of removed files
85+
*/
86+
public function getRemovedFiles(bool $relative = false): array
87+
{
88+
$after = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
89+
$removed = array_diff($this->before, $after);
90+
if ($relative) {
91+
return $removed;
92+
}
93+
return array_map(fn ($f) => $this->dir . DIRECTORY_SEPARATOR . $f, $removed);
94+
}
95+
}

0 commit comments

Comments
 (0)