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,46 +49,66 @@ 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), ['..', '.']);
$isStowed = is_link($targetFile) && readlink($targetFile) === $stowFile;
if ($action === 'stow') { foreach ($sourceFiles as $sourceFile) {
if (is_link($targetFile)) { $targetFile = path($targetPath, $sourceFile);
line("File $targetFile is already stowed from $stowFile"); $stowFile = path($sourcePath, $sourceFile);
continue; $isStowed = is_link($targetFile) && readlink($targetFile) === $stowFile;
}
if(is_dir($targetFile)) { if ($this->action === 'stow') {
line("File $targetFile is a folder, todo: recurse through existing folders"); if (is_link($targetFile)) {
continue; line("File $targetFile is already stowed from $stowFile");
}
if (is_file($targetFile)) {
if ($backup) {
$backFile = $targetFile . '.bak';
if (is_file($backFile)) {
line("Backup file $backFile already exists");
continue; continue;
} }
rename($targetFile, $backFile); if (is_dir($targetFile)) {
line("Backup file $targetFile to $backFile"); if (is_dir($stowFile)) {
} elseif ($force) { line("File $targetFile and $stowFile are folders, recurse into existing folders");
line("Todo: delete file $targetFile"); $this->run($stowFile, $targetFile);
continue; } else {
} else { line("File $targetFile is a folder, but stow file $stowFile is not a folder");
line("File $targetFile already exists"); }
continue; continue;
}
if (is_file($targetFile)) {
if ($this->backup) {
$backFile = $targetFile . '.bak';
if (is_file($backFile)) {
line("Backup file $backFile already exists");
continue;
}
rename($targetFile, $backFile);
line("Backup file $targetFile to $backFile");
} elseif ($this->force) {
line("Todo: delete file $targetFile");
continue;
} else {
line("File $targetFile already exists");
continue;
}
}
line("Stow $stowFile to $targetFile");
symlink($stowFile, $targetFile);
} elseif ($this->action === 'unstow') {
if (!$isStowed) {
line("File $targetFile is not stowed from $stowFile");
continue;
}
unlink($targetFile);
} }
} }
line("Stow $stowFile to $targetFile");
symlink($stowFile, $targetFile);
} elseif ($action === 'unstow') {
if (!$isStowed) {
line("File $targetFile is not stowed from $stowFile");
continue;
}
unlink($targetFile);
} }
} }
$stow = new stow($action, $backup, $force);
$stow->run($stowPath, $targetPath);