getNoStow($sourcePath); $sourceFiles = array_diff(scandir($sourcePath), ['..', '.', 'config.php', '.nostow', ...$noStow]); foreach ($sourceFiles as $sourceFile) { $targetFile = path($targetPath, $sourceFile); $stowFile = path($sourcePath, $sourceFile); switch ($this->action) { case self::ACTION_STOW: $this->stow($stowFile, $targetFile); break; case self::ACTION_UNSTOW: $this->unstow($stowFile, $targetFile); break; default: line("Unknown action: {$this->action}"); return; } } } public function stow(string $stowFile, string $targetFile): void { if (is_link($targetFile)) { $targetLink = readlink($targetFile); if ($targetLink === $stowFile) { line("File $targetFile is already stowed from $stowFile"); } else { if ($this->unwrap) { line("Unwrapping $targetFile from $targetLink"); unlink($targetFile); mkdir($targetFile); $this->run($targetLink, $targetFile); $this->run($stowFile, $targetFile); } else { line("File $targetFile is linked from $targetLink, ignoring, add -w to unwrap"); } } 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 $stowFile, string $targetFile): 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"); } }