extract and cleanup stow class
This commit is contained in:
parent
ae1c5cc147
commit
15bd1c4031
92
php/bin/stow
92
php/bin/stow
@ -3,95 +3,7 @@
|
|||||||
|
|
||||||
require_once __DIR__ . '/../argvParser.php';
|
require_once __DIR__ . '/../argvParser.php';
|
||||||
require_once __DIR__ . '/../functions.php';
|
require_once __DIR__ . '/../functions.php';
|
||||||
|
require_once __DIR__ . '/../stow.php';
|
||||||
readonly class stow
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private string $action = 'stow',
|
|
||||||
private bool $backup = false,
|
|
||||||
private bool $force = false,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
private function getNoStow(string $path): array
|
|
||||||
{
|
|
||||||
if (file_exists(path($path, '.nostow'))) {
|
|
||||||
$noStow = file_get_contents(path($path, '.nostow'));
|
|
||||||
if ($noStow === false) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return array_values(array_filter(array_map('trim', explode(PHP_EOL, $noStow))));
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function run(string $sourcePath, string $targetPath): void
|
|
||||||
{
|
|
||||||
$noStow = $this->getNoStow($sourcePath);
|
|
||||||
$sourceFiles = array_diff(scandir($sourcePath), ['..', '.', '.nostow', ...$noStow]);
|
|
||||||
|
|
||||||
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(
|
$argvParser = new ArgvParser(
|
||||||
['u' => 'Unstow files', 'b' => 'Backup existing files', 'f' => 'Force overwrite'],
|
['u' => 'Unstow files', 'b' => 'Backup existing files', 'f' => 'Force overwrite'],
|
||||||
@ -104,7 +16,7 @@ if ($parsed === false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$cwd = getcwd();
|
$cwd = getcwd();
|
||||||
$action = $parsed->get('u') ? 'unstow' : 'stow';
|
$action = $parsed->get('u') ? stow::ACTION_UNSTOW : stow::ACTION_STOW;
|
||||||
$backup = $parsed->get('b');
|
$backup = $parsed->get('b');
|
||||||
$force = $parsed->get('f');
|
$force = $parsed->get('f');
|
||||||
|
|
||||||
|
109
php/stow.php
Normal file
109
php/stow.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
readonly class stow
|
||||||
|
{
|
||||||
|
public const ACTION_STOW = 'stow';
|
||||||
|
public const ACTION_UNSTOW = 'unstow';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private string $action = self::ACTION_STOW,
|
||||||
|
private bool $backup = false,
|
||||||
|
private bool $force = false,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private function getNoStow(string $path): array
|
||||||
|
{
|
||||||
|
if (file_exists(path($path, '.nostow'))) {
|
||||||
|
$noStow = file_get_contents(path($path, '.nostow'));
|
||||||
|
if ($noStow === false) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return array_values(array_filter(array_map('trim', explode(PHP_EOL, $noStow))));
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run(string $sourcePath, string $targetPath): void
|
||||||
|
{
|
||||||
|
$noStow = $this->getNoStow($sourcePath);
|
||||||
|
$sourceFiles = array_diff(scandir($sourcePath), ['..', '.', '.nostow', ...$noStow]);
|
||||||
|
|
||||||
|
foreach ($sourceFiles as $sourceFile) {
|
||||||
|
$targetFile = path($targetPath, $sourceFile);
|
||||||
|
$stowFile = path($sourcePath, $sourceFile);
|
||||||
|
|
||||||
|
switch ($this->action) {
|
||||||
|
case self::ACTION_STOW:
|
||||||
|
$this->stow($targetFile, $stowFile);
|
||||||
|
break;
|
||||||
|
case self::ACTION_UNSTOW:
|
||||||
|
$this->unstow($targetFile, $stowFile);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
line("Unknown action: {$this->action}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function stow(string $targetFile, string $stowFile): void
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (is_file($targetFile)) {
|
||||||
|
if ($this->backup) {
|
||||||
|
$backFile = $targetFile . '.bak';
|
||||||
|
if (is_file($backFile)) {
|
||||||
|
line("Backup file $backFile already exists");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rename($targetFile, $backFile);
|
||||||
|
line("Backup file $targetFile to $backFile");
|
||||||
|
} elseif ($this->force) {
|
||||||
|
line("Todo: delete file $targetFile");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
line("File $targetFile already exists");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line("Stow $targetFile from $stowFile");
|
||||||
|
symlink($stowFile, $targetFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unstow(string $targetFile, string $stowFile): void
|
||||||
|
{
|
||||||
|
if (is_link($targetFile) && readlink($targetFile) === $stowFile) {
|
||||||
|
line("Unstow $targetFile from $stowFile");
|
||||||
|
unlink($targetFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (is_dir($targetFile)) {
|
||||||
|
if (is_dir($stowFile)) {
|
||||||
|
line("File $targetFile and $stowFile are folders, recurse into existing folders");
|
||||||
|
$this->run($stowFile, $targetFile);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
line("File $targetFile is a folder, but stow file $stowFile is not a folder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line("File $targetFile is not stowed from $stowFile");
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user