Skip to content

Instantly share code, notes, and snippets.

@Anachron
Created December 27, 2013 21:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Anachron/8152658 to your computer and use it in GitHub Desktop.
Save Anachron/8152658 to your computer and use it in GitHub Desktop.
Quick way how to install applications to a path of your choice in scoop.
$scoopdir = "$env:APPS\scoop"
$globaldir = "$env:APPS\scoop"
$cachedir = "$scoopdir\cache" # always local
# helper functions
function coalesce($a, $b) { if($a) { return $a } $b }
function format($str, $hash) {
$hash.keys | % { set-variable $_ $hash[$_] }
$executionContext.invokeCommand.expandString($str)
}
function is_admin {
$admin = [security.principal.windowsbuiltinrole]::administrator
$id = [security.principal.windowsidentity]::getcurrent()
([security.principal.windowsprincipal]($id)).isinrole($admin)
}
# messages
function abort($msg) { write-host $msg -f darkred; exit 1 }
function warn($msg) { write-host $msg -f darkyellow; }
function success($msg) { write-host $msg -f darkgreen }
# dirs
function basedir($global) { if($global) { return $globaldir } $scoopdir }
function appsdir($global) { "$scoopdir\apps" }
function shimdir($global) { "$scoopdir\shims" }
function appdir($app, $global) { "$(appsdir $global)\$app" }
function versiondir($app, $version, $global) { "$(appdir $app $global)\$version" }
# apps
function installed($app, $global) { return test-path (appdir $app $global) }
function installed_apps($global) {
$dir = appsdir $global
if(test-path $dir) {
gci $dir | where { $_.psiscontainer -and $_.name -ne 'scoop' } | % { $_.name }
}
}
# paths
function fname($path) { split-path $path -leaf }
function strip_ext($fname) { $fname -replace '\.[^\.]*$', '' }
function ensure($dir) { if(!(test-path $dir)) { mkdir $dir > $null }; resolve-path $dir }
function fullpath($path) { # should be ~ rooted
$executionContext.sessionState.path.getUnresolvedProviderPathFromPSPath($path)
}
function relpath($path) { "$($myinvocation.psscriptroot)\$path" } # relative to calling script
function friendly_path($path) {
$h = $home; if(!$h.endswith('\')) { $h += '\' }
return "$path" -replace ([regex]::escape($h)), "~\"
}
function is_local($path) {
($path -notmatch '^https?://') -and (test-path $path)
}
# operations
function dl($url,$to) { (new-object system.net.webClient).downloadFile($url,$to) }
function env($name,$global,$val='__get') {
$target = 'User'; if($global) {$target = 'Machine'}
if($val -eq '__get') { [environment]::getEnvironmentVariable($name,$target) }
else { [environment]::setEnvironmentVariable($name,$val,$target) }
}
function unzip($path,$to) {
if(!(test-path $path)) { abort "can't find $path to unzip"}
add-type -assembly "System.IO.Compression.FileSystem"
[io.compression.zipfile]::extracttodirectory($path,$to)
}
function shim($path, $global) {
if(!(test-path $path)) { abort "can't shim $(fname $path): couldn't find $path" }
$abs_shimdir = ensure (shimdir $global)
$shim = "$abs_shimdir\$(strip_ext(fname $path).tolower()).ps1"
# note: use > for first line to replace file, then >> to append following lines
echo '# ensure $HOME is set for MSYS programs' > $shim
echo "if(!`$env:home) { `$env:home = `"`$env:APPS`" }" >> $shim
echo 'if($env:home -eq "\") { $env:home = $env:APPS }' >> $shim
echo "`$path = '$path'" >> $shim
echo 'if($myinvocation.expectingInput) { $input | & $path @args } else { & $path @args }' >> $shim
if($path -match '\.((exe)|(bat)|(cmd))$') {
# shim .exe, .bat, .cmd so they can be used by programs with no awareness of PSH
$shim_cmd = "$(strip_ext($shim)).cmd"
':: ensure $HOME is set for MSYS programs' | out-file $shim_cmd -encoding oem
'@if "%home%"=="" set home=$env:APPS' | out-file $shim_cmd -encoding oem -append
'@if "%home%"=="\" set home=$env:APPS' | out-file $shim_cmd -encoding oem -append
"@`"$path`" %*" | out-file $shim_cmd -encoding oem -append
} elseif($path -match '\.ps1$') {
# make ps1 accessible from cmd.exe
$shim_cmd = "$(strip_ext($shim)).cmd"
"@powershell -noprofile -ex unrestricted `"& '$path' %*;exit `$lastexitcode`"" | out-file $shim_cmd -encoding oem
}
}
function ensure_in_path($dir, $global) {
$path = env 'path' $global
$dir = fullpath $dir
if($path -notmatch [regex]::escape($dir)) {
echo "adding $(friendly_path $dir) to $(if($global){'global'}else{'your'}) path"
env 'path' $global "$dir;$path" # for future sessions...
$env:path = "$dir;$env:path" # for this session
}
}
function strip_path($orig_path, $dir) {
$stripped = [string]::join(';', @( $orig_path.split(';') | ? { $_ -and $_ -ne $dir } ))
return ($stripped -ne $orig_path), $stripped
}
function remove_from_path($dir,$global) {
$dir = fullpath $dir
# future sessions
$was_in_path, $newpath = strip_path (env 'path' $global) $dir
if($was_in_path) {
echo "removing $(friendly_path $dir) from your path"
env 'path' $global $newpath
}
# current session
$was_in_path, $newpath = strip_path $env:path $dir
if($was_in_path) { $env:path = $newpath }
}
function ensure_scoop_in_path($global) {
$abs_shimdir = ensure (shimdir $global)
# be aggressive (b-e-aggressive) and install scoop first in the path
ensure_in_path $abs_shimdir $global
}
function wraptext($text, $width) {
if(!$width) { $width = $host.ui.rawui.windowsize.width };
$width -= 1 # be conservative: doesn't seem to print the last char
$text -split '\r?\n' | % {
$line = ''
$_ -split ' ' | % {
if($line.length -eq 0) { $line = $_ }
elseif($line.length + $_.length + 1 -le $width) { $line += " $_" }
else { $lines += ,$line; $line = $_ }
}
$lines += ,$line
}
$lines -join "`n"
}
Howto:
Add a new environment variable called "APPS" and set the location to the parent directory where you want SCOOP to be installed to.
Download core.ps1 and install.ps1 and run install.ps1 from the Windows Powershell.
Replace core.ps1 in "scoop\apps\scoop\current\lib" with the one you just downloaded.
That's it! You will now have everything installed in the folder of your choice.
#requires -v 3
# remote install:
# iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
$erroractionpreference='stop' # quit if anything goes wrong
# get core functions
$core_url = 'D:\apps\scoop\core\core.ps1'
echo 'initializing...'
iex (new-object net.webclient).downloadstring($core_url)
# prep
if(installed 'scoop') {
write-host "scoop is already installed. run 'scoop update' to get the latest version." -f red
# don't abort if invoked with iex——that would close the PS session
if($myinvocation.commandorigin -eq 'Internal') { return } else { exit 1 }
}
$dir = ensure (versiondir 'scoop' 'current')
# download scoop zip
$zipurl = 'https://github.com/lukesampson/scoop/archive/master.zip'
$zipfile = "$dir\scoop.zip"
echo 'downloading...'
dl $zipurl $zipfile
'extracting...'
unzip $zipfile "$dir\_scoop_extract"
cp "$dir\_scoop_extract\scoop-master\*" $dir -r -force
rm "$dir\_scoop_extract" -r -force
rm $zipfile
$null > "$dir\last_updated" # save install timestamp
echo 'creating shim...'
shim "$dir\bin\scoop.ps1" $false
ensure_scoop_in_path
success 'scoop was installed successfully!'
echo "type 'scoop help' for instructions"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment