109 lines
3.9 KiB
PHP
Executable File
109 lines
3.9 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
require_once __DIR__ . '/../argvParser.php';
|
|
require_once __DIR__ . '/../functions.php';
|
|
|
|
readonly class stow
|
|
{
|
|
public function __construct(
|
|
private string $action = 'stow',
|
|
private bool $backup = false,
|
|
private bool $force = false
|
|
) {}
|
|
|
|
function run(string $sourcePath, string $targetPath): void
|
|
{
|
|
$sourceFiles = array_diff(scandir($sourcePath), ['..', '.']);
|
|
|
|
foreach ($sourceFiles as $sourceFile) {
|
|
$targetFile = path($targetPath, $sourceFile);
|
|
$stowFile = path($sourcePath, $sourceFile);
|
|
|
|
if ($this->action === 'stow') {
|
|
if (is_link($targetFile)) {
|
|
$targetLink = readlink($targetFile);
|
|
if ($targetLink === $stowFile) {
|
|
line("File $targetFile is already stowed from $stowFile");
|
|
} else {
|
|
line("File $targetFile is linked from $targetLink");
|
|
}
|
|
continue;
|
|
}
|
|
if (is_dir($targetFile)) {
|
|
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;
|
|
}
|
|
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 $targetFile from $stowFile");
|
|
symlink($stowFile, $targetFile);
|
|
} elseif ($this->action === 'unstow') {
|
|
if (is_link($targetFile) && readlink($targetFile) === $stowFile) {
|
|
line("Unstow $targetFile from $stowFile");
|
|
unlink($targetFile);
|
|
continue;
|
|
}
|
|
if (is_dir($targetFile)) {
|
|
if (is_dir($stowFile)) {
|
|
line("File $targetFile and $stowFile are folders, recurse into existing folders");
|
|
$this->run($stowFile, $targetFile);
|
|
continue;
|
|
} else {
|
|
line("File $targetFile is a folder, but stow file $stowFile is not a folder");
|
|
}
|
|
}
|
|
line("File $targetFile is not stowed from $stowFile");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$argvParser = new ArgvParser(
|
|
['u' => 'Unstow files', 'b' => 'Backup existing files', 'f' => 'Force overwrite'],
|
|
['stow-directory' => 'The directory to stow']
|
|
);
|
|
$parsed = $argvParser->parseArgv($argv);
|
|
if ($parsed === false) {
|
|
line('Usage: ' . __FILE__ . ' ' . $argvParser->getOptionsHelp());
|
|
exit(1);
|
|
}
|
|
|
|
$cwd = getcwd();
|
|
$action = $parsed->get('u') ? 'unstow' : 'stow';
|
|
$backup = $parsed->get('b');
|
|
$force = $parsed->get('f');
|
|
|
|
$stowName = $parsed->get('stow-directory');
|
|
$stowPath = path($cwd, $stowName);
|
|
$targetPath = dirname($stowPath, 2);
|
|
|
|
if (!is_dir($stowPath)) {
|
|
line("Directory '$stowName' does not exist");
|
|
exit(1);
|
|
}
|
|
|
|
$stow = new stow($action, $backup, $force);
|
|
$stow->run($stowPath, $targetPath);
|
|
|
|
exit(0); |