Stow: allow recursing into folder, tree folding

This commit is contained in:
Tim 2025-04-11 14:51:15 +02:00
parent ff767da809
commit 33ba450383

View File

@ -16,7 +16,7 @@ $action = 'stow';
$backup = $force = false; $backup = $force = false;
array_shift($argv); // we don't care about the script name array_shift($argv); // we don't care about the script name
if(count($argv) === 0) { if (count($argv) === 0) {
line("Usage: stow [-u] [-b] [-f] <stow-directory>"); line("Usage: stow [-u] [-b] [-f] <stow-directory>");
exit(1); exit(1);
} }
@ -49,24 +49,39 @@ if (!is_dir($stowPath)) {
exit(1); exit(1);
} }
$files = array_diff(scandir($stowPath), ['..', '.']); readonly class stow
{
public function __construct(
private string $action = 'stow',
private bool $backup = false,
private bool $force = false
) {}
foreach ($files as $file) { function run(string $sourcePath, string $targetPath): void
$targetFile = path($targetPath, $file); {
$stowFile = path($stowPath, $file); $sourceFiles = array_diff(scandir($sourcePath), ['..', '.']);
foreach ($sourceFiles as $sourceFile) {
$targetFile = path($targetPath, $sourceFile);
$stowFile = path($sourcePath, $sourceFile);
$isStowed = is_link($targetFile) && readlink($targetFile) === $stowFile; $isStowed = is_link($targetFile) && readlink($targetFile) === $stowFile;
if ($action === 'stow') { if ($this->action === 'stow') {
if (is_link($targetFile)) { if (is_link($targetFile)) {
line("File $targetFile is already stowed from $stowFile"); line("File $targetFile is already stowed from $stowFile");
continue; continue;
} }
if(is_dir($targetFile)) { if (is_dir($targetFile)) {
line("File $targetFile is a folder, todo: recurse through existing folders"); if (is_dir($stowFile)) {
line("File $targetFile and $stowFile are folders, recurse into existing folders");
$this->run($stowFile, $targetFile);
} else {
line("File $targetFile is a folder, but stow file $stowFile is not a folder");
}
continue; continue;
} }
if (is_file($targetFile)) { if (is_file($targetFile)) {
if ($backup) { if ($this->backup) {
$backFile = $targetFile . '.bak'; $backFile = $targetFile . '.bak';
if (is_file($backFile)) { if (is_file($backFile)) {
line("Backup file $backFile already exists"); line("Backup file $backFile already exists");
@ -74,7 +89,7 @@ foreach ($files as $file) {
} }
rename($targetFile, $backFile); rename($targetFile, $backFile);
line("Backup file $targetFile to $backFile"); line("Backup file $targetFile to $backFile");
} elseif ($force) { } elseif ($this->force) {
line("Todo: delete file $targetFile"); line("Todo: delete file $targetFile");
continue; continue;
} else { } else {
@ -84,11 +99,16 @@ foreach ($files as $file) {
} }
line("Stow $stowFile to $targetFile"); line("Stow $stowFile to $targetFile");
symlink($stowFile, $targetFile); symlink($stowFile, $targetFile);
} elseif ($action === 'unstow') { } elseif ($this->action === 'unstow') {
if (!$isStowed) { if (!$isStowed) {
line("File $targetFile is not stowed from $stowFile"); line("File $targetFile is not stowed from $stowFile");
continue; continue;
} }
unlink($targetFile); unlink($targetFile);
} }
}
}
} }
$stow = new stow($action, $backup, $force);
$stow->run($stowPath, $targetPath);