Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite data persisting #2897

Merged
merged 4 commits into from
Jan 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 42 additions & 20 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ function persist_def($persist) {
}

if (!$target) {
$target = fname($source)
$target = $source
}

return $source, $target
Expand All @@ -1222,39 +1222,61 @@ function persist_data($manifest, $original_dir, $persist_dir) {

write-host "Persisting $source"

# add base paths
if (!(Test-Path(fullpath "$dir\$source")) -or (is_directory(fullpath "$dir\$source"))) {
$source = New-Object System.IO.DirectoryInfo(fullpath "$dir\$source")
$target = New-Object System.IO.DirectoryInfo(fullpath "$persist_dir\$target")
} else {
$source = New-Object System.IO.FileInfo(fullpath "$dir\$source")
$target = New-Object System.IO.FileInfo(fullpath "$persist_dir\$target")
}
$source = fullpath "$dir\$source"
$target = fullpath "$persist_dir\$target"

if (!$target.Exists) {
# If we do not have data in the store we move the original
if ($source.Exists) {
Move-Item $source $target
} elseif($target.GetType() -eq [System.IO.DirectoryInfo]) {
# if there is no source and it's a directory we create an empty directory
ensure $target.FullName | out-null
# if we have had persist data in the store, just create link and go
if (Test-Path $target) {
# if there is also a source data, rename it (to keep a original backup)
if (Test-Path $source) {
Move-Item -Force $source "$source.original"
}
} elseif ($source.Exists) {
# (re)move original (keep a copy)
Move-Item $source "$source.original"
# we don't have persist data in the store, move the source to target, then create link
} elseif (Test-Path $source) {
# ensure target parent folder exist
$null = ensure (Split-Path -Path $target)
Move-Item $source $target
# we don't have neither source nor target data! we need to crate an empty target,
# but we can't make a judgement that the data should be a file or directory...
# so we create a directory by default. to avoid this, use pre_install
# to create the source file before persisting (DON'T use post_install)
} else {
$target = New-Object System.IO.DirectoryInfo($target)
}

# create link
if (is_directory $target) {
# target is a directory, create junction
& "$env:COMSPEC" /c "mklink /j `"$source`" `"$target`"" | out-null
attrib $source.FullName +R /L
attrib $source +R /L
} else {
# target is a file, create hard link
& "$env:COMSPEC" /c "mklink /h `"$source`" `"$target`"" | out-null
}
}
}
}

function unlink_persist_data($dir) {
# unlink all junction / hard link in the directory
Get-ChildItem -Recurse $dir | ForEach-Object {
$file = $_
if ($null -ne $file.LinkType) {
$filepath = $file.FullName
# directory (junction)
if ($file -is [System.IO.DirectoryInfo]) {
# remove read-only attribute on the link
attrib -R /L $filepath
# remove the junction
& "$env:COMSPEC" /c "rmdir /s /q $filepath"
} else {
# remove the hard link
& "$env:COMSPEC" /c "del $filepath"
}
}
}
}

# check whether write permission for Users usergroup is set to global persist dir, if not then set
function persist_permission($manifest, $global) {
if($global -and $manifest.persist -and (is_admin)) {
Expand Down
14 changes: 3 additions & 11 deletions libexec/scoop-cleanup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
. "$psscriptroot\..\lib\versions.ps1"
. "$psscriptroot\..\lib\getopt.ps1"
. "$psscriptroot\..\lib\help.ps1"
. "$psscriptroot\..\lib\install.ps1"

reset_aliases

Expand All @@ -39,17 +40,8 @@ function cleanup($app, $global, $verbose) {
$version = $_
write-host " $version" -nonewline
$dir = versiondir $app $version $global
Get-ChildItem $dir | ForEach-Object {
$file = $_
# the file is a junction
if ($null -ne $file.LinkType -and $file -is [System.IO.DirectoryInfo]) {
# remove read-only attribute on the link
attrib -R /L $file
# remove the junction
$filepath = Resolve-Path $file
& "$env:COMSPEC" /c "rmdir /s /q $filepath"
}
}
# unlink all potential old link before doing recursive Remove-Item
unlink_persist_data $dir
Remove-Item $dir -ErrorAction Stop -Recurse -Force
}
write-host ''
Expand Down
2 changes: 2 additions & 0 deletions libexec/scoop-reset.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ $apps | ForEach-Object {
create_startmenu_shortcuts $manifest $dir $global $architecture
env_add_path $manifest $dir
env_set $manifest $dir $global
# unlink all potential old link before re-persisting
unlink_persist_data $original_dir
persist_data $manifest $original_dir $persist_dir
persist_permission $manifest $global
}
Expand Down
4 changes: 4 additions & 0 deletions libexec/scoop-uninstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ if(!$apps) { exit 0 }
env_rm $manifest $global

try {
# unlink all potential old link before doing recursive Remove-Item
unlink_persist_data $dir
Remove-Item -r $dir -ea stop -force
} catch {
if(test-path $dir) {
Expand All @@ -85,6 +87,8 @@ if(!$apps) { exit 0 }
write-host "Removing older version ($oldver)."
$dir = versiondir $app $oldver $global
try {
# unlink all potential old link before doing recursive Remove-Item
unlink_persist_data $dir
Remove-Item -r -force -ea stop $dir
} catch {
error "Couldn't remove '$(friendly_path $dir)'; it may be in use."
Expand Down
4 changes: 2 additions & 2 deletions test/Scoop-Install.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ describe 'persist_def' -Tag 'Scoop' {
$target | should -be "test"
}

it 'should strip directories of source for target' {
it 'should handle sub-folder' {
$source, $target = persist_def "foo/bar"
$source | should -be "foo/bar"
$target | should -be "bar"
$target | should -be "foo/bar"
}

it 'should handle arrays' {
Expand Down