|
@@ -10,34 +10,58 @@
|
|
# Hopefully that is good enough.
|
|
# Hopefully that is good enough.
|
|
#
|
|
#
|
|
param(
|
|
param(
|
|
- [Parameter(Mandatory=$true)][string]$Source,
|
|
|
|
- [Parameter(Mandatory=$true)][string]$Target
|
|
|
|
|
|
+ [Parameter(Mandatory = $true)]
|
|
|
|
+ [string]$Source,
|
|
|
|
+
|
|
|
|
+ [Parameter(Mandatory = $true)]
|
|
|
|
+ [string]$Target,
|
|
|
|
+
|
|
|
|
+ [string]$Dir,
|
|
|
|
+ [string]$Ignore,
|
|
|
|
+ [string]$Defer,
|
|
|
|
+ [string]$Override,
|
|
|
|
+ [switch]$Restow,
|
|
|
|
+ [switch]$Delete,
|
|
|
|
+ [switch]$Verbose,
|
|
|
|
+ [switch]$Simulate,
|
|
|
|
+ [switch]$NoFolding,
|
|
|
|
+ [switch]$Adopt
|
|
)
|
|
)
|
|
|
|
|
|
-function New-Symlink($sourcePath, $targetPath) {
|
|
|
|
- $item = Get-Item $sourcePath
|
|
|
|
|
|
+$SourcePath = (Resolve-Path $Source).Path
|
|
|
|
+$SourceRoot = [System.IO.Path]::GetFullPath($SourcePath)
|
|
|
|
+$TargetRoot = [System.IO.Path]::GetFullPath($Target)
|
|
|
|
|
|
- if ($item.PSIsContainer) {
|
|
|
|
- # Directory symlink
|
|
|
|
- New-Item -ItemType SymbolicLink -Path $targetPath -Target $sourcePath | Out-Null
|
|
|
|
- Write-Host "Linked dir: $targetPath -> $sourcePath"
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- # File symlink
|
|
|
|
- New-Item -ItemType SymbolicLink -Path $targetPath -Target $sourcePath | Out-Null
|
|
|
|
- Write-Host "Linked file: $targetPath -> $sourcePath"
|
|
|
|
- }
|
|
|
|
|
|
+function Is-Under($child, $parent) {
|
|
|
|
+ $child = [System.IO.Path]::GetFullPath($child)
|
|
|
|
+ $parent = [System.IO.Path]::GetFullPath($parent)
|
|
|
|
+ return $child.StartsWith($parent, [System.StringComparison]::OrdinalIgnoreCase)
|
|
}
|
|
}
|
|
|
|
|
|
-# Ensure $Target exists
|
|
|
|
-if (-not (Test-Path $Target)) {
|
|
|
|
- New-Item -ItemType Directory -Path $Target | Out-Null
|
|
|
|
|
|
+if ($Delete) {
|
|
|
|
+ Get-ChildItem -Path $TargetRoot -Recurse -Force | ForEach-Object {
|
|
|
|
+ if ($_.LinkType -eq 'SymbolicLink') {
|
|
|
|
+ $linkTarget = (Get-Item $_.FullName -Force).Target
|
|
|
|
+ if ($linkTarget -and (Is-Under $linkTarget $SourceRoot)) {
|
|
|
|
+ Remove-Item $_.FullName
|
|
|
|
+ Write-Host "Unlinked: $($_.FullName)"
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return
|
|
}
|
|
}
|
|
|
|
|
|
-# Link each item from source into target
|
|
|
|
-Get-ChildItem -Path $Source -Force | ForEach-Object {
|
|
|
|
- $src = $_.FullName
|
|
|
|
- $dest = Join-Path $Target $_.Name
|
|
|
|
- New-Symlink -sourcePath $src -targetPath $dest
|
|
|
|
|
|
+# Stow (create symlinks)
|
|
|
|
+Get-ChildItem -Path $SourceRoot -Recurse -File -Force | ForEach-Object {
|
|
|
|
+ $relativePath = $_.FullName.Substring($SourceRoot.Length).TrimStart('\', '/')
|
|
|
|
+ $targetFile = Join-Path $TargetRoot $relativePath
|
|
|
|
+ $targetDir = Split-Path $targetFile
|
|
|
|
+
|
|
|
|
+ if (-not (Test-Path $targetDir)) {
|
|
|
|
+ New-Item -ItemType Directory -Path $targetDir -Force | Out-Null
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ New-Item -ItemType SymbolicLink -Path $targetFile -Target $_.FullName | Out-Null
|
|
|
|
+ Write-Host "Linked: $targetFile -> $($_.FullName)"
|
|
}
|
|
}
|
|
|
|
|