mirror of
https://github.com/ScoopInstaller/Scoop.git
synced 2025-11-27 20:03:33 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d63b7d6f01 | ||
|
|
ecb8f02d4e | ||
|
|
7e6be8f3f5 | ||
|
|
574bea4975 | ||
|
|
9e70dcad79 | ||
|
|
64364b40b4 | ||
|
|
387835753d | ||
|
|
bfb5c8d04a | ||
|
|
3a1186ea1b | ||
|
|
ccd067b2b1 | ||
|
|
78c1bc45b4 | ||
|
|
dd0f51426b | ||
|
|
d6c6ddcbb3 | ||
|
|
2e52888b63 | ||
|
|
0f6d012d26 | ||
|
|
896ea6cdbd | ||
|
|
d056d542db | ||
|
|
ad04dc9e6f | ||
|
|
8140a2052c | ||
|
|
ac2fb38722 | ||
|
|
47d7f76f7c | ||
|
|
bb5392b486 | ||
|
|
f49f976618 | ||
|
|
5d58703484 | ||
|
|
b130e606cf | ||
|
|
c6fc2de306 | ||
|
|
a2600b1203 |
33
CHANGELOG.md
33
CHANGELOG.md
@@ -1,3 +1,36 @@
|
||||
## [v0.2.1](https://github.com/ScoopInstaller/Scoop/compare/v0.2.0...v0.2.1) - 2022-06-10
|
||||
|
||||
### Features
|
||||
|
||||
- **core:** Add pre_uninstall and post_uninstall hooks ([#4957](https://github.com/ScoopInstaller/Scoop/issues/4957), [#4962](https://github.com/ScoopInstaller/Scoop/issues/4962))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **bucket:** Make sure `list_buckets` return array ([#4979](https://github.com/ScoopInstaller/Scoop/issues/4979))
|
||||
- **chore:** Deprecate tls1 and tls1.1 ([#4950](https://github.com/ScoopInstaller/Scoop/issues/4950))
|
||||
- **chore:** Update Nonportable bucket URL ([#4955](https://github.com/ScoopInstaller/Scoop/issues/4955))
|
||||
- **core:** Using `Invoke-Command` instead of `Invoke-Expression` ([#4941](https://github.com/ScoopInstaller/Scoop/issues/4941))
|
||||
- **core:** Load config file before initialization ([#4932](https://github.com/ScoopInstaller/Scoop/issues/4932))
|
||||
- **core:** Allow to use '_' and '.' in bucket name ([#4952](https://github.com/ScoopInstaller/Scoop/issues/4952))
|
||||
- **depends:** Avoid digits in archive file extension (except for .7z and .001) ([#4915](https://github.com/ScoopInstaller/Scoop/issues/4915))
|
||||
- **bucket:** Don't check remote URL of non-git buckets ([#4923](https://github.com/ScoopInstaller/Scoop/issues/4923))
|
||||
- **bucket:** Don't write message OK before bucket is cloned ([#4925](https://github.com/ScoopInstaller/Scoop/issues/4925))
|
||||
- **shim:** Add 'Get-CommandPath()' to find git ([#4913](https://github.com/ScoopInstaller/Scoop/issues/4913))
|
||||
- **shim:** Remove character replacement in .cmd -> .ps1 shims ([#4914](https://github.com/ScoopInstaller/Scoop/issues/4914))
|
||||
- **scoop:** Pass CLI arguments as string objects ([#4931](https://github.com/ScoopInstaller/Scoop/issues/4931))
|
||||
- **scoop-info:** Fix error message when manifest is not found ([#4935](https://github.com/ScoopInstaller/Scoop/issues/4935))
|
||||
- **scoop-search:** Require files in 'bucket' dir for remote known buckets ([#4944](https://github.com/ScoopInstaller/Scoop/issues/4944))
|
||||
- **update:** Prevent uninstall when update ([#4949](https://github.com/ScoopInstaller/Scoop/issues/4949))
|
||||
- **scoop-download:** Use correct Args when calling `Get-Manifest` ([#4970](https://github.com/ScoopInstaller/Scoop/issues/4970))
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
- **manifest:** Rename 'Find-Manifest()' to 'Get-Manifest() ([#4966](https://github.com/ScoopInstaller/Scoop/issues/4966), [#4981](https://github.com/ScoopInstaller/Scoop/issues/4981))
|
||||
|
||||
### Documentation
|
||||
|
||||
- **readme:** Update license badge ([#4929](https://github.com/ScoopInstaller/Scoop/issues/4929))
|
||||
|
||||
## [v0.2.0](https://github.com/ScoopInstaller/Scoop/compare/v0.1.0...v0.2.0) - 2022-05-10
|
||||
|
||||
### Features
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
<a href="https://gitter.im/lukesampson/scoop">
|
||||
<img src="https://badges.gitter.im/lukesampson/scoop.png" alt="Gitter Chat" />
|
||||
</a>
|
||||
<a href="https://github.com/ScoopInstaller/Scoop/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/ScoopInstaller/Scoop.svg" alt="License" />
|
||||
<a href="./LICENSE">
|
||||
<img src="https://img.shields.io/badge/license-UNLICENSE%20or%20MIT-blue" alt="License" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -121,7 +121,7 @@ The following buckets are known to scoop:
|
||||
- [nerd-fonts](https://github.com/matthewjberger/scoop-nerd-fonts) - Nerd Fonts
|
||||
- [nirsoft](https://github.com/kodybrown/scoop-nirsoft) - Almost all of the [250+](https://rasa.github.io/scoop-directory/by-apps#kodybrown_scoop-nirsoft) apps from [Nirsoft](https://nirsoft.net)
|
||||
- [java](https://github.com/ScoopInstaller/Java) - A collection of Java development kits (JDKs), Java runtime engines (JREs), Java's virtual machine debugging tools and Java based runtime engines.
|
||||
- [nonportable](https://github.com/TheRandomLabs/scoop-nonportable) - Non-portable apps (may require UAC)
|
||||
- [nonportable](https://github.com/ScoopInstaller/Nonportable) - Non-portable apps (may require UAC)
|
||||
- [php](https://github.com/ScoopInstaller/PHP) - Installers for most versions of PHP
|
||||
- [versions](https://github.com/ScoopInstaller/Versions) - Alternative versions of apps found in other buckets
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ if (is_unix) {
|
||||
|
||||
function execute($cmd) {
|
||||
Write-Host $cmd -ForegroundColor Green
|
||||
$output = Invoke-Expression $cmd
|
||||
$output = Invoke-Command ([scriptblock]::Create($cmd))
|
||||
|
||||
if ($LASTEXITCODE -gt 0) {
|
||||
abort "^^^ Error! See above ^^^ (last command: $cmd)"
|
||||
|
||||
@@ -221,7 +221,7 @@ while ($in_progress -gt 0) {
|
||||
$page = $ev.SourceEventArgs.Result
|
||||
$err = $ev.SourceEventArgs.Error
|
||||
if ($json.checkver.script) {
|
||||
$page = $json.checkver.script -join "`r`n" | Invoke-Expression
|
||||
$page = Invoke-Command ([scriptblock]::Create($json.checkver.script -join "`r`n"))
|
||||
}
|
||||
|
||||
if ($err) {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#Requires -Version 5
|
||||
param($SubCommand)
|
||||
|
||||
Set-StrictMode -Off
|
||||
|
||||
. "$PSScriptRoot\..\lib\core.ps1"
|
||||
@@ -8,24 +6,22 @@ Set-StrictMode -Off
|
||||
. "$PSScriptRoot\..\lib\commands.ps1"
|
||||
. "$PSScriptRoot\..\lib\help.ps1"
|
||||
|
||||
$subCommand = $Args[0]
|
||||
|
||||
# for aliases where there's a local function, re-alias so the function takes precedence
|
||||
$aliases = Get-Alias | Where-Object { $_.Options -notmatch 'ReadOnly|AllScope' } | ForEach-Object { $_.Name }
|
||||
Get-ChildItem Function: | Where-Object -Property Name -In -Value $aliases | ForEach-Object {
|
||||
Set-Alias -Name $_.Name -Value Local:$($_.Name) -Scope Script
|
||||
}
|
||||
|
||||
switch ($SubCommand) {
|
||||
({ $SubCommand -in @($null, '--help', '/?') }) {
|
||||
if (!$SubCommand -and $Args -eq '-v') {
|
||||
$SubCommand = '--version'
|
||||
} else {
|
||||
exec 'help'
|
||||
}
|
||||
switch ($subCommand) {
|
||||
({ $subCommand -in @($null, '-h', '--help', '/?') }) {
|
||||
exec 'help'
|
||||
}
|
||||
({ $SubCommand -eq '--version' }) {
|
||||
({ $subCommand -in @('-v', '--version') }) {
|
||||
Write-Host 'Current Scoop version:'
|
||||
if ((Test-CommandAvailable git) -and (Test-Path "$PSScriptRoot\..\.git") -and (get_config SCOOP_BRANCH 'master') -ne 'master') {
|
||||
Invoke-Expression "git -C '$PSScriptRoot\..' --no-pager log --oneline HEAD -n 1"
|
||||
git -C "$PSScriptRoot\.." --no-pager log --oneline HEAD -n 1
|
||||
} else {
|
||||
$version = Select-String -Pattern '^## \[(v[\d.]+)\].*?([\d-]+)$' -Path "$PSScriptRoot\..\CHANGELOG.md"
|
||||
Write-Host $version.Matches.Groups[1].Value -ForegroundColor Cyan -NoNewline
|
||||
@@ -35,22 +31,23 @@ switch ($SubCommand) {
|
||||
|
||||
Get-LocalBucket | ForEach-Object {
|
||||
$bucketLoc = Find-BucketDirectory $_ -Root
|
||||
if ((Test-Path (Join-Path $bucketLoc '.git')) -and (Test-CommandAvailable git)) {
|
||||
if ((Test-Path "$bucketLoc\.git") -and (Test-CommandAvailable git)) {
|
||||
Write-Host "'$_' bucket:"
|
||||
Invoke-Expression "git -C '$bucketLoc' --no-pager log --oneline HEAD -n 1"
|
||||
git -C "$bucketLoc" --no-pager log --oneline HEAD -n 1
|
||||
Write-Host ''
|
||||
}
|
||||
}
|
||||
}
|
||||
({ $SubCommand -in (commands) }) {
|
||||
if ($Args -in @('-h', '--help', '/?')) {
|
||||
exec 'help' @($SubCommand)
|
||||
({ $subCommand -in (commands) }) {
|
||||
[string[]]$arguments = $Args | Select-Object -Skip 1
|
||||
if ($null -ne $arguments -and $arguments[0] -in @('-h', '--help', '/?')) {
|
||||
exec 'help' @($subCommand)
|
||||
} else {
|
||||
exec $SubCommand $Args
|
||||
exec $subCommand $arguments
|
||||
}
|
||||
}
|
||||
default {
|
||||
"scoop: '$SubCommand' isn't a scoop command. See 'scoop help'."
|
||||
"scoop: '$subCommand' isn't a scoop command. See 'scoop help'."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"nirsoft": "https://github.com/kodybrown/scoop-nirsoft",
|
||||
"php": "https://github.com/ScoopInstaller/PHP",
|
||||
"nerd-fonts": "https://github.com/matthewjberger/scoop-nerd-fonts",
|
||||
"nonportable": "https://github.com/TheRandomLabs/scoop-nonportable",
|
||||
"nonportable": "https://github.com/ScoopInstaller/Nonportable",
|
||||
"java": "https://github.com/ScoopInstaller/Java",
|
||||
"games": "https://github.com/Calinou/scoop-games"
|
||||
}
|
||||
|
||||
@@ -72,43 +72,11 @@ function buckets {
|
||||
return Get-LocalBucket
|
||||
}
|
||||
|
||||
function Find-Manifest($app, $bucket) {
|
||||
$manifest, $url = $null, $null
|
||||
|
||||
# check if app is a URL or UNC path
|
||||
if ($app -match '^(ht|f)tps?://|\\\\') {
|
||||
$url = $app
|
||||
$app = appname_from_url $url
|
||||
$manifest = url_manifest $url
|
||||
} else {
|
||||
if ($bucket) {
|
||||
$manifest = manifest $app $bucket
|
||||
} else {
|
||||
foreach ($bucket in Get-LocalBucket) {
|
||||
$manifest = manifest $app $bucket
|
||||
if ($manifest) { break }
|
||||
}
|
||||
}
|
||||
|
||||
if (!$manifest) {
|
||||
# couldn't find app in buckets: check if it's a local path
|
||||
$path = $app
|
||||
if (!$path.endswith('.json')) { $path += '.json' }
|
||||
if (Test-Path $path) {
|
||||
$url = "$(Resolve-Path $path)"
|
||||
$app = appname_from_url $url
|
||||
$manifest, $bucket = url_manifest $url
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $app, $manifest, $bucket, $url
|
||||
}
|
||||
|
||||
function Convert-RepositoryUri {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory, Position = 0, ValueFromPipeline = $true)]
|
||||
[AllowEmptyString()]
|
||||
[String] $Uri
|
||||
)
|
||||
|
||||
@@ -141,7 +109,7 @@ function list_buckets {
|
||||
Measure-Object | Select-Object -ExpandProperty Count
|
||||
$buckets += [PSCustomObject]$bucket
|
||||
}
|
||||
$buckets
|
||||
,$buckets
|
||||
}
|
||||
|
||||
function add_bucket($name, $repo) {
|
||||
@@ -161,10 +129,12 @@ function add_bucket($name, $repo) {
|
||||
return 1
|
||||
}
|
||||
foreach ($bucket in Get-LocalBucket) {
|
||||
$remote = git -C "$bucketsdir\$bucket" config --get remote.origin.url
|
||||
if ((Convert-RepositoryUri -Uri $remote) -eq $uni_repo) {
|
||||
warn "Bucket $bucket already exists for $repo"
|
||||
return 2
|
||||
if (Test-Path -Path "$bucketsdir\$bucket\.git") {
|
||||
$remote = git -C "$bucketsdir\$bucket" config --get remote.origin.url
|
||||
if ((Convert-RepositoryUri -Uri $remote) -eq $uni_repo) {
|
||||
warn "Bucket $bucket already exists for $repo"
|
||||
return 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,11 +144,10 @@ function add_bucket($name, $repo) {
|
||||
error "'$repo' doesn't look like a valid git repository`n`nError given:`n$out"
|
||||
return 1
|
||||
}
|
||||
Write-Host 'OK'
|
||||
|
||||
ensure $bucketsdir | Out-Null
|
||||
$dir = ensure $dir
|
||||
git_cmd clone "$repo" "`"$dir`"" -q
|
||||
Write-Host 'OK'
|
||||
success "The $name bucket was added successfully."
|
||||
return 0
|
||||
}
|
||||
@@ -195,12 +164,12 @@ function rm_bucket($name) {
|
||||
}
|
||||
|
||||
function new_issue_msg($app, $bucket, $title, $body) {
|
||||
$app, $manifest, $bucket, $url = Find-Manifest $app $bucket
|
||||
$app, $manifest, $bucket, $url = Get-Manifest "$bucket/$app"
|
||||
$url = known_bucket_repo $bucket
|
||||
$bucket_path = "$bucketsdir\$bucket"
|
||||
|
||||
if (Test-Path $bucket_path) {
|
||||
$remote = Invoke-Expression "git -C '$bucket_path' config --get remote.origin.url"
|
||||
$remote = git -C "$bucket_path" config --get remote.origin.url
|
||||
# Support ssh and http syntax
|
||||
# git@PROVIDER:USER/REPO.git
|
||||
# https://PROVIDER/USER/REPO.git
|
||||
|
||||
@@ -20,7 +20,7 @@ function command_path($cmd) {
|
||||
$shim_path = "$scoopdir\shims\scoop-$cmd.ps1"
|
||||
$line = ((Get-Content $shim_path) | Where-Object { $_.startswith('$path') })
|
||||
if($line) {
|
||||
Invoke-Expression -command "$line"
|
||||
Invoke-Command ([scriptblock]::Create($line)) -NoNewScope
|
||||
$cmd_path = $path
|
||||
}
|
||||
else { $cmd_path = $shim_path }
|
||||
|
||||
102
lib/core.ps1
102
lib/core.ps1
@@ -9,9 +9,9 @@ function Optimize-SecurityProtocol {
|
||||
|
||||
# If not, change it to support TLS 1.2
|
||||
if (!($isNewerNetFramework -and $isSystemDefault)) {
|
||||
# Set to TLS 1.2 (3072), then TLS 1.1 (768), and TLS 1.0 (192). Ssl3 has been superseded,
|
||||
# https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype?view=netframework-4.5
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192
|
||||
# Set to TLS 1.2 (3072). Ssl3, TLS 1.0, and 1.1 have been deprecated,
|
||||
# https://datatracker.ietf.org/doc/html/rfc8996
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = 3072
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +318,39 @@ function Get-HelperPath {
|
||||
}
|
||||
}
|
||||
|
||||
function Get-CommandPath {
|
||||
[CmdletBinding()]
|
||||
[OutputType([String])]
|
||||
param(
|
||||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
|
||||
[String]
|
||||
$Command
|
||||
)
|
||||
|
||||
begin {
|
||||
$userShims = Convert-Path (shimdir $false)
|
||||
$globalShims = fullpath (shimdir $true) # don't resolve: may not exist
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
$comm = Get-Command $Command -ErrorAction Stop
|
||||
} catch {
|
||||
return $null
|
||||
}
|
||||
$commandPath = if ($comm.Path -like "$userShims*" -or $comm.Path -like "$globalShims*") {
|
||||
Get-ShimTarget ($comm.Path -replace '\.exe$', '.shim')
|
||||
} elseif ($comm.CommandType -eq 'Application') {
|
||||
$comm.Source
|
||||
} elseif ($comm.CommandType -eq 'Alias') {
|
||||
Get-CommandPath $comm.ResolvedCommandName
|
||||
} else {
|
||||
$null
|
||||
}
|
||||
return $commandPath
|
||||
}
|
||||
}
|
||||
|
||||
function Test-HelperInstalled {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
@@ -599,6 +632,20 @@ function get_app_name_from_shim($shim) {
|
||||
return get_app_name $content
|
||||
}
|
||||
|
||||
function Get-ShimTarget($ShimPath) {
|
||||
if ($ShimPath) {
|
||||
$shimTarget = if ($ShimPath.EndsWith('.shim')) {
|
||||
(Get-Content -Path $ShimPath | Select-Object -First 1).Replace('path = ', '').Replace('"', '')
|
||||
} else {
|
||||
((Select-String -Path $ShimPath -Pattern '^(?:@rem|#)\s*(.*)$').Matches.Groups | Select-Object -Index 1).Value
|
||||
}
|
||||
if (!$shimTarget) {
|
||||
$shimTarget = ((Select-String -Path $ShimPath -Pattern '[''"]([^@&]*?)[''"]' -AllMatches).Matches.Groups | Select-Object -Last 1).Value
|
||||
}
|
||||
$shimTarget | Convert-Path
|
||||
}
|
||||
}
|
||||
|
||||
function warn_on_overwrite($shim, $path) {
|
||||
if (!(Test-Path $shim)) {
|
||||
return
|
||||
@@ -679,19 +726,11 @@ function shim($path, $global, $name, $arg) {
|
||||
@(
|
||||
"@rem $resolved_path",
|
||||
"@echo off",
|
||||
"setlocal enabledelayedexpansion",
|
||||
"set args=%*",
|
||||
":: replace problem characters in arguments",
|
||||
"set args=%args:`"='%",
|
||||
"set args=%args:(=``(%",
|
||||
"set args=%args:)=``)%",
|
||||
"set invalid=`"='",
|
||||
"if !args! == !invalid! ( set args= )",
|
||||
"where /q pwsh.exe",
|
||||
"if %errorlevel% equ 0 (",
|
||||
" pwsh -noprofile -ex unrestricted -file `"$resolved_path`" $arg %args%",
|
||||
" pwsh -noprofile -ex unrestricted -file `"$resolved_path`" $arg %*",
|
||||
") else (",
|
||||
" powershell -noprofile -ex unrestricted -file `"$resolved_path`" $arg %args%",
|
||||
" powershell -noprofile -ex unrestricted -file `"$resolved_path`" $arg %*",
|
||||
")"
|
||||
) -join "`r`n" | Out-UTF8File "$shim.cmd"
|
||||
|
||||
@@ -734,7 +773,7 @@ function shim($path, $global, $name, $arg) {
|
||||
} else {
|
||||
warn_on_overwrite "$shim.cmd" $path
|
||||
# find path to Git's bash so that batch scripts can run bash scripts
|
||||
$gitdir = (Get-Item (Get-Command git -CommandType:Application -ErrorAction:Stop).Source -ErrorAction:Stop).Directory.Parent
|
||||
$gitdir = (Get-Item (Get-CommandPath git) -ErrorAction:Stop).Directory.Parent
|
||||
if ($gitdir.FullName -imatch 'mingw') {
|
||||
$gitdir = $gitdir.Parent
|
||||
}
|
||||
@@ -902,11 +941,12 @@ function applist($apps, $global) {
|
||||
return ,@($apps | ForEach-Object { ,@($_, $global) })
|
||||
}
|
||||
|
||||
function parse_app([string] $app) {
|
||||
if($app -match '(?:(?<bucket>[a-zA-Z0-9-]+)\/)?(?<app>.*\.json$|[a-zA-Z0-9-_.]+)(?:@(?<version>.*))?') {
|
||||
return $matches['app'], $matches['bucket'], $matches['version']
|
||||
function parse_app([string]$app) {
|
||||
if ($app -match '^(?:(?<bucket>[a-zA-Z0-9-_.]+)/)?(?<app>.*\.json$|[a-zA-Z0-9-_.]+)(?:@(?<version>.*))?$') {
|
||||
return $Matches['app'], $Matches['bucket'], $Matches['version']
|
||||
} else {
|
||||
return $app, $null, $null
|
||||
}
|
||||
return $app, $null, $null
|
||||
}
|
||||
|
||||
function show_app($app, $bucket, $version) {
|
||||
@@ -1109,19 +1149,6 @@ function Out-UTF8File {
|
||||
# for all communication with api.github.com
|
||||
Optimize-SecurityProtocol
|
||||
|
||||
# Scoop root directory
|
||||
$scoopdir = $env:SCOOP, (get_config 'rootPath'), "$env:USERPROFILE\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
|
||||
|
||||
# Scoop global apps directory
|
||||
$globaldir = $env:SCOOP_GLOBAL, (get_config 'globalPath'), "$env:ProgramData\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -first 1
|
||||
|
||||
# Scoop cache directory
|
||||
# Note: Setting the SCOOP_CACHE environment variable to use a shared directory
|
||||
# is experimental and untested. There may be concurrency issues when
|
||||
# multiple users write and access cached files at the same time.
|
||||
# Use at your own risk.
|
||||
$cachedir = $env:SCOOP_CACHE, (get_config 'cachePath'), "$scoopdir\cache" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -first 1
|
||||
|
||||
# Scoop config file migration
|
||||
$configHome = $env:XDG_CONFIG_HOME, "$env:USERPROFILE\.config" | Select-Object -First 1
|
||||
$configFile = "$configHome\scoop\config.json"
|
||||
@@ -1135,5 +1162,18 @@ if ((Test-Path "$env:USERPROFILE\.scoop") -and !(Test-Path $configFile)) {
|
||||
# Load Scoop config
|
||||
$scoopConfig = load_cfg $configFile
|
||||
|
||||
# Scoop root directory
|
||||
$scoopdir = $env:SCOOP, (get_config 'rootPath'), "$env:USERPROFILE\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
|
||||
|
||||
# Scoop global apps directory
|
||||
$globaldir = $env:SCOOP_GLOBAL, (get_config 'globalPath'), "$env:ProgramData\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -first 1
|
||||
|
||||
# Scoop cache directory
|
||||
# Note: Setting the SCOOP_CACHE environment variable to use a shared directory
|
||||
# is experimental and untested. There may be concurrency issues when
|
||||
# multiple users write and access cached files at the same time.
|
||||
# Use at your own risk.
|
||||
$cachedir = $env:SCOOP_CACHE, (get_config 'cachePath'), "$scoopdir\cache" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -first 1
|
||||
|
||||
# Setup proxy globally
|
||||
setup_proxy
|
||||
|
||||
@@ -64,7 +64,12 @@ function Expand-7zipArchive {
|
||||
}
|
||||
if ($Removal) {
|
||||
# Remove original archive file
|
||||
Remove-Item $Path -Force
|
||||
if (($Path -replace '.*\.([^\.]*)$', '$1') -eq '001') {
|
||||
# Remove splited 7-zip archive parts
|
||||
Get-ChildItem "$($Path -replace '\.[^\.]*$', '').???" | Remove-Item -Force
|
||||
} else {
|
||||
Remove-Item $Path -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,8 @@ function Get-Dependency {
|
||||
$Unresolved = @()
|
||||
)
|
||||
process {
|
||||
$AppName, $bucket, $null = parse_app $AppName
|
||||
$AppName, $manifest, $bucket, $null = Get-Manifest $AppName
|
||||
$Unresolved += $AppName
|
||||
$null, $manifest, $null, $null = Find-Manifest $AppName $bucket
|
||||
|
||||
if (!$manifest) {
|
||||
if (((Get-LocalBucket) -notcontains $bucket) -and $bucket) {
|
||||
@@ -141,7 +140,7 @@ function Test-7zipRequirement {
|
||||
$Uri
|
||||
)
|
||||
return ($Uri | Where-Object {
|
||||
$_ -match '\.((gz)|(tar)|(t[abgpx]z2?)|(lzma)|(bz2?)|(7z)|(rar)|(iso)|(xz)|(lzh)|(nupkg))(\.[^.]+)?$'
|
||||
$_ -match '\.((gz)|(tar)|(t[abgpx]z2?)|(lzma)|(bz2?)|(7z)|(001)|(rar)|(iso)|(xz)|(lzh)|(nupkg))(\.[^\d.]+)?$'
|
||||
}).Count -gt 0
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ function nightly_version($date, $quiet = $false) {
|
||||
}
|
||||
|
||||
function install_app($app, $architecture, $global, $suggested, $use_cache = $true, $check_hash = $true) {
|
||||
$app, $bucket, $null = parse_app $app
|
||||
$app, $manifest, $bucket, $url = Find-Manifest $app $bucket
|
||||
$app, $manifest, $bucket, $url = Get-Manifest $app
|
||||
|
||||
if(!$manifest) {
|
||||
abort "Couldn't find manifest for '$app'$(if($url) { " at the URL $url" })."
|
||||
@@ -51,7 +50,8 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
|
||||
$persist_dir = persistdir $app $global
|
||||
|
||||
$fname = dl_urls $app $version $manifest $bucket $architecture $dir $use_cache $check_hash
|
||||
pre_install $manifest $architecture
|
||||
Invoke-HookScript -HookType 'pre_install' -Manifest $manifest -Arch $architecture
|
||||
|
||||
run_installer $fname $manifest $architecture $dir $global
|
||||
ensure_install_dir_not_in_path $dir $global
|
||||
$dir = link_current $dir
|
||||
@@ -65,7 +65,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
|
||||
persist_data $manifest $original_dir $persist_dir
|
||||
persist_permission $manifest $global
|
||||
|
||||
post_install $manifest $architecture
|
||||
Invoke-HookScript -HookType 'post_install' -Manifest $manifest -Arch $architecture
|
||||
|
||||
# save info for uninstall
|
||||
save_installed_manifest $app $bucket $dir $url
|
||||
@@ -269,7 +269,7 @@ function dl_with_cache_aria2($app, $version, $manifest, $architecture, $dir, $co
|
||||
$oriConsoleEncoding = [Console]::OutputEncoding
|
||||
[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
|
||||
|
||||
Invoke-Expression $aria2 | ForEach-Object {
|
||||
Invoke-Command ([scriptblock]::Create($aria2)) | ForEach-Object {
|
||||
# Skip blank lines
|
||||
if ([String]::IsNullOrWhiteSpace($_)) { return }
|
||||
|
||||
@@ -718,7 +718,7 @@ function run_installer($fname, $manifest, $architecture, $dir, $global) {
|
||||
$installer = installer $manifest $architecture
|
||||
if($installer.script) {
|
||||
write-output "Running installer script..."
|
||||
Invoke-Expression (@($installer.script) -join "`r`n")
|
||||
Invoke-Command ([scriptblock]::Create($installer.script -join "`r`n"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -798,7 +798,7 @@ function run_uninstaller($manifest, $architecture, $dir) {
|
||||
$version = $manifest.version
|
||||
if($uninstaller.script) {
|
||||
write-output "Running uninstaller script..."
|
||||
Invoke-Expression (@($uninstaller.script) -join "`r`n")
|
||||
Invoke-Command ([scriptblock]::Create($uninstaller.script -join "`r`n"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1031,19 +1031,25 @@ function env_rm($manifest, $global, $arch) {
|
||||
}
|
||||
}
|
||||
|
||||
function pre_install($manifest, $arch) {
|
||||
$pre_install = arch_specific 'pre_install' $manifest $arch
|
||||
if($pre_install) {
|
||||
write-output "Running pre-install script..."
|
||||
Invoke-Expression (@($pre_install) -join "`r`n")
|
||||
}
|
||||
}
|
||||
function Invoke-HookScript {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateSet('pre_install', 'post_install',
|
||||
'pre_uninstall', 'post_uninstall')]
|
||||
[String] $HookType,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[PSCustomObject] $Manifest,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateSet('32bit', '64bit')]
|
||||
[String] $Arch
|
||||
)
|
||||
|
||||
function post_install($manifest, $arch) {
|
||||
$post_install = arch_specific 'post_install' $manifest $arch
|
||||
if($post_install) {
|
||||
write-output "Running post-install script..."
|
||||
Invoke-Expression (@($post_install) -join "`r`n")
|
||||
$script = arch_specific $HookType $Manifest $Arch
|
||||
if ($script) {
|
||||
Write-Output "Running $HookType script..."
|
||||
Invoke-Command ([scriptblock]::Create($script -join "`r`n"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,48 @@ function url_manifest($url) {
|
||||
$str | convertfrom-json
|
||||
}
|
||||
|
||||
function Get-Manifest($app) {
|
||||
$bucket, $manifest, $url = $null
|
||||
# check if app is a URL or UNC path
|
||||
if ($app -match '^(ht|f)tps?://|\\\\') {
|
||||
$url = $app
|
||||
$app = appname_from_url $url
|
||||
$manifest = url_manifest $url
|
||||
} else {
|
||||
$app, $bucket, $version = parse_app $app
|
||||
if ($bucket) {
|
||||
$manifest = manifest $app $bucket
|
||||
} else {
|
||||
foreach ($bucket in Get-LocalBucket) {
|
||||
$manifest = manifest $app $bucket
|
||||
if ($manifest) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$manifest) {
|
||||
# couldn't find app in buckets: check if it's a local path
|
||||
$appPath = $app
|
||||
if (!$appPath.EndsWith('.json')) {
|
||||
$appPath += '.json'
|
||||
}
|
||||
if (Test-Path $appPath) {
|
||||
$url = Convert-Path $appPath
|
||||
$app = appname_from_url $url
|
||||
$manifest = url_manifest $url
|
||||
}
|
||||
}
|
||||
}
|
||||
return $app, $manifest, $bucket, $url
|
||||
}
|
||||
|
||||
function manifest($app, $bucket, $url) {
|
||||
if($url) { return url_manifest $url }
|
||||
if ($url) { return url_manifest $url }
|
||||
parse_json (manifest_path $app $bucket)
|
||||
}
|
||||
|
||||
function save_installed_manifest($app, $bucket, $dir, $url) {
|
||||
if($url) {
|
||||
if ($url) {
|
||||
$wc = New-Object Net.Webclient
|
||||
$wc.Headers.Add('User-Agent', (Get-UserAgent))
|
||||
$wc.downloadstring($url) > "$dir\manifest.json"
|
||||
@@ -51,7 +86,7 @@ function save_install_info($info, $dir) {
|
||||
|
||||
function install_info($app, $version, $global) {
|
||||
$path = "$(versiondir $app $version $global)\install.json"
|
||||
if(!(test-path $path)) { return $null }
|
||||
if (!(Test-Path $path)) { return $null }
|
||||
parse_json $path
|
||||
}
|
||||
|
||||
@@ -73,20 +108,21 @@ function default_architecture {
|
||||
}
|
||||
|
||||
function arch_specific($prop, $manifest, $architecture) {
|
||||
if($manifest.architecture) {
|
||||
if ($manifest.architecture) {
|
||||
$val = $manifest.architecture.$architecture.$prop
|
||||
if($val) { return $val } # else fallback to generic prop
|
||||
if ($val) { return $val } # else fallback to generic prop
|
||||
}
|
||||
|
||||
if($manifest.$prop) { return $manifest.$prop }
|
||||
if ($manifest.$prop) { return $manifest.$prop }
|
||||
}
|
||||
|
||||
function supports_architecture($manifest, $architecture) {
|
||||
return -not [String]::IsNullOrEmpty((arch_specific 'url' $manifest $architecture))
|
||||
}
|
||||
|
||||
function generate_user_manifest($app, $bucket, $version) { # 'autoupdate.ps1' 'buckets.ps1' 'manifest.ps1'
|
||||
$null, $manifest, $bucket, $null = Find-Manifest $app $bucket
|
||||
function generate_user_manifest($app, $bucket, $version) {
|
||||
# 'autoupdate.ps1' 'buckets.ps1' 'manifest.ps1'
|
||||
$app, $manifest, $bucket, $null = Get-Manifest "$bucket/$app"
|
||||
if ("$($manifest.version)" -eq "$version") {
|
||||
return manifest_path $app $bucket
|
||||
}
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
param($app)
|
||||
|
||||
. "$PSScriptRoot\..\lib\json.ps1" # 'ConvertToPrettyJson'
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Find-Manifest' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest'
|
||||
|
||||
if (!$app) { error '<app> missing'; my_usage; exit 1 }
|
||||
|
||||
$app, $bucket, $null = parse_app $app
|
||||
$app, $manifest, $bucket, $url = Find-Manifest $app $bucket
|
||||
$null, $manifest, $bucket, $url = Get-Manifest $app
|
||||
|
||||
if ($manifest) {
|
||||
$style = get_config cat_style
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
. "$PSScriptRoot\..\lib\getopt.ps1"
|
||||
. "$PSScriptRoot\..\lib\json.ps1" # 'autoupdate.ps1' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\autoupdate.ps1" # 'generate_user_manifest' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'generate_user_manifest' 'Find-Manifest' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'generate_user_manifest' 'Get-Manifest'
|
||||
. "$PSScriptRoot\..\lib\install.ps1"
|
||||
|
||||
$opt, $apps, $err = getopt $args 'fhua:' 'force', 'no-hash-check', 'no-update-scoop', 'arch='
|
||||
@@ -51,7 +51,7 @@ foreach ($curr_app in $apps) {
|
||||
$bucket = $version = $app = $manifest = $url = $null
|
||||
|
||||
$app, $bucket, $version = parse_app $curr_app
|
||||
$app, $manifest, $bucket, $url = Find-Manifest $app $bucket
|
||||
$app, $manifest, $bucket, $url = Get-Manifest $curr_app
|
||||
|
||||
info "Starting download for $app..."
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Summary: Opens the app homepage
|
||||
param($app)
|
||||
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Find-Manifest' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest'
|
||||
|
||||
if ($app) {
|
||||
$null, $manifest, $bucket, $null = Find-Manifest $app
|
||||
$null, $manifest, $bucket, $null = Get-Manifest $app
|
||||
if ($manifest) {
|
||||
if ($manifest.homepage) {
|
||||
Start-Process $manifest.homepage
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# -v, --verbose Show full paths and URLs
|
||||
|
||||
. "$PSScriptRoot\..\lib\getopt.ps1"
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Find-Manifest' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest'
|
||||
. "$PSScriptRoot\..\lib\versions.ps1" # 'Get-InstalledVersion'
|
||||
|
||||
$opt, $app, $err = getopt $args 'v' 'verbose'
|
||||
@@ -13,31 +13,21 @@ $verbose = $opt.v -or $opt.verbose
|
||||
|
||||
if (!$app) { my_usage; exit 1 }
|
||||
|
||||
if ($app -match '^(ht|f)tps?://|\\\\') {
|
||||
# check if $app is a URL or UNC path
|
||||
$url = $app
|
||||
$app = appname_from_url $url
|
||||
$global = installed $app $true
|
||||
$status = app_status $app $global
|
||||
$manifest = url_manifest $url
|
||||
$manifest_file = $url
|
||||
} else {
|
||||
# else $app is a normal app name
|
||||
$global = installed $app $true
|
||||
$app, $bucket, $null = parse_app $app
|
||||
$status = app_status $app $global
|
||||
$app, $manifest, $bucket, $url = Find-Manifest $app $bucket
|
||||
}
|
||||
$app, $manifest, $bucket, $url = Get-Manifest $app
|
||||
|
||||
if (!$manifest) {
|
||||
abort "Could not find manifest for '$(show_app $app $bucket)'."
|
||||
abort "Could not find manifest for '$(show_app $app)' in local buckets."
|
||||
}
|
||||
|
||||
$global = installed $app $true
|
||||
$status = app_status $app $global
|
||||
$install = install_info $app $status.version $global
|
||||
$status.installed = $bucket -and $install.bucket -eq $bucket
|
||||
$version_output = $manifest.version
|
||||
if (!$manifest_file) {
|
||||
$manifest_file = if ($bucket) { manifest_path $app $bucket } else { $url }
|
||||
$manifest_file = if ($bucket) {
|
||||
manifest_path $app $bucket
|
||||
} else {
|
||||
$url
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
. "$PSScriptRoot\..\lib\getopt.ps1"
|
||||
. "$PSScriptRoot\..\lib\json.ps1" # 'autoupdate.ps1' 'manifest.ps1' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\autoupdate.ps1" # 'generate_user_manifest' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'generate_user_manifest' 'Select-CurrentVersion' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'generate_user_manifest' 'Get-Manifest' 'Select-CurrentVersion' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\install.ps1"
|
||||
. "$PSScriptRoot\..\lib\decompress.ps1"
|
||||
. "$PSScriptRoot\..\lib\shortcuts.ps1"
|
||||
|
||||
@@ -63,7 +63,7 @@ function search_remote($bucket, $query) {
|
||||
$repo_name = $Matches[2]
|
||||
$api_link = "https://api.github.com/repos/$user/$repo_name/git/trees/HEAD?recursive=1"
|
||||
$result = download_json $api_link | Select-Object -ExpandProperty tree |
|
||||
Where-Object -Value "^(?:bucket/)?(.*$query.*)\.json$" -Property Path -Match |
|
||||
Where-Object -Value "^bucket/(.*$query.*)\.json$" -Property Path -Match |
|
||||
ForEach-Object { $Matches[1] }
|
||||
}
|
||||
|
||||
|
||||
@@ -108,20 +108,6 @@ function Get-ShimPath($ShimName, $Global) {
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ShimTarget($ShimPath) {
|
||||
if ($ShimPath) {
|
||||
$shimTarget = if ($ShimPath.EndsWith('.shim')) {
|
||||
(Get-Content -Path $ShimPath | Select-Object -First 1).Replace('path = ', '').Replace('"', '')
|
||||
} else {
|
||||
((Select-String -Path $ShimPath -Pattern '^(?:@rem|#)\s*(.*)$').Matches.Groups | Select-Object -Index 1).Value
|
||||
}
|
||||
if (!$shimTarget) {
|
||||
$shimTarget = ((Select-String -Path $ShimPath -Pattern '[''"]([^@&]*?)[''"]' -AllMatches).Matches.Groups | Select-Object -Last 1).Value
|
||||
}
|
||||
$shimTarget | Convert-Path
|
||||
}
|
||||
}
|
||||
|
||||
switch ($SubCommand) {
|
||||
'add' {
|
||||
if ($commandPath -notmatch '[\\/]') {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# -p, --purge Remove all persistent data
|
||||
|
||||
. "$PSScriptRoot\..\lib\getopt.ps1"
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Select-CurrentVersion' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest' 'Select-CurrentVersion' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\install.ps1"
|
||||
. "$PSScriptRoot\..\lib\shortcuts.ps1"
|
||||
. "$PSScriptRoot\..\lib\psmodules.ps1"
|
||||
@@ -54,6 +54,12 @@ if (!$apps) { exit 0 }
|
||||
$dir = versiondir $app $version $global
|
||||
$persist_dir = persistdir $app $global
|
||||
|
||||
$manifest = installed_manifest $app $version $global
|
||||
$install = install_info $app $version $global
|
||||
$architecture = $install.architecture
|
||||
|
||||
Invoke-HookScript -HookType 'pre_uninstall' -Manifest $manifest -Arch $architecture
|
||||
|
||||
#region Workaround for #2952
|
||||
if (test_running_process $app $global) {
|
||||
continue
|
||||
@@ -67,10 +73,6 @@ if (!$apps) { exit 0 }
|
||||
continue
|
||||
}
|
||||
|
||||
$manifest = installed_manifest $app $version $global
|
||||
$install = install_info $app $version $global
|
||||
$architecture = $install.architecture
|
||||
|
||||
run_uninstaller $manifest $architecture $dir
|
||||
rm_shims $app $manifest $global $architecture
|
||||
rm_startmenu_shortcuts $manifest $global $architecture
|
||||
@@ -95,6 +97,8 @@ if (!$apps) { exit 0 }
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-HookScript -HookType 'post_uninstall' -Manifest $manifest -Arch $architecture
|
||||
}
|
||||
# remove older versions
|
||||
$oldVersions = @(Get-ChildItem $appDir -Name -Exclude 'current')
|
||||
|
||||
@@ -66,49 +66,60 @@ function update_scoop() {
|
||||
$show_update_log = get_config 'show_update_log' $true
|
||||
$currentdir = fullpath $(versiondir 'scoop' 'current')
|
||||
if (!(Test-Path "$currentdir\.git")) {
|
||||
$newdir = fullpath $(versiondir 'scoop' 'new')
|
||||
$newdir = "$currentdir\..\new"
|
||||
$olddir = "$currentdir\..\old"
|
||||
|
||||
# get git scoop
|
||||
git_cmd clone -q $configRepo --branch $configBranch --single-branch "`"$newdir`""
|
||||
|
||||
# check if scoop was successful downloaded
|
||||
if (!(Test-Path "$newdir")) {
|
||||
abort 'Scoop update failed.'
|
||||
if (!(Test-Path "$newdir\bin\scoop.ps1")) {
|
||||
Remove-Item $newdir -Force -Recurse
|
||||
abort "Scoop download failed. If this appears several times, try removing SCOOP_REPO by 'scoop config rm SCOOP_REPO'"
|
||||
} else {
|
||||
# replace non-git scoop with the git version
|
||||
try {
|
||||
Rename-Item $currentdir 'old' -ErrorAction Stop
|
||||
Rename-Item $newdir 'current' -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Warning $_
|
||||
abort "Scoop update failed. Folder in use. Paste $newdir into $currentdir."
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Test-Path "$currentdir\..\old") {
|
||||
Remove-Item "$currentdir\..\old" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# replace non-git scoop with the git version
|
||||
Remove-Item -r -force $currentdir -ea stop
|
||||
Move-Item $newdir $currentdir
|
||||
} else {
|
||||
$previousCommit = Invoke-Expression "git -C '$currentdir' rev-parse HEAD"
|
||||
$currentRepo = Invoke-Expression "git -C '$currentdir' config remote.origin.url"
|
||||
$currentBranch = Invoke-Expression "git -C '$currentdir' branch"
|
||||
$previousCommit = git -C "$currentdir" rev-parse HEAD
|
||||
$currentRepo = git -C "$currentdir" config remote.origin.url
|
||||
$currentBranch = git -C "$currentdir" branch
|
||||
|
||||
$isRepoChanged = !($currentRepo -match $configRepo)
|
||||
$isBranchChanged = !($currentBranch -match "\*\s+$configBranch")
|
||||
|
||||
# Change remote url if the repo is changed
|
||||
if ($isRepoChanged) {
|
||||
Invoke-Expression "git -C '$currentdir' config remote.origin.url '$configRepo'"
|
||||
git -C "$currentdir" config remote.origin.url "$configRepo"
|
||||
}
|
||||
|
||||
# Fetch and reset local repo if the repo or the branch is changed
|
||||
if ($isRepoChanged -or $isBranchChanged) {
|
||||
# Reset git fetch refs, so that it can fetch all branches (GH-3368)
|
||||
Invoke-Expression "git -C '$currentdir' config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'"
|
||||
git -C "$currentdir" config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
|
||||
# fetch remote branch
|
||||
git_cmd -C "`"$currentdir`"" fetch --force origin "refs/heads/`"$configBranch`":refs/remotes/origin/$configBranch" -q
|
||||
# checkout and track the branch
|
||||
git_cmd -C "`"$currentdir`"" checkout -B $configBranch -t origin/$configBranch -q
|
||||
# reset branch HEAD
|
||||
Invoke-Expression "git -C '$currentdir' reset --hard origin/$configBranch -q"
|
||||
git -C "$currentdir" reset --hard origin/$configBranch -q
|
||||
} else {
|
||||
git_cmd -C "`"$currentdir`"" pull -q
|
||||
}
|
||||
|
||||
$res = $lastexitcode
|
||||
if ($show_update_log) {
|
||||
Invoke-Expression "git -C '$currentdir' --no-pager log --no-decorate --grep='^(chore)' --invert-grep --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' '$previousCommit..HEAD'"
|
||||
git -C "$currentdir" --no-pager log --no-decorate --grep='^(chore)' --invert-grep --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' "$previousCommit..HEAD"
|
||||
}
|
||||
|
||||
if ($res -ne 0) {
|
||||
@@ -133,19 +144,25 @@ function update_scoop() {
|
||||
if (!(Test-Path (Join-Path $bucketLoc '.git'))) {
|
||||
if ($bucket -eq 'main') {
|
||||
# Make sure main bucket, which was downloaded as zip, will be properly "converted" into git
|
||||
Write-Host " Converting 'main' bucket to git..."
|
||||
rm_bucket 'main'
|
||||
add_bucket 'main'
|
||||
Write-Host " Converting 'main' bucket to git repo..."
|
||||
$status = rm_bucket 'main'
|
||||
if ($status -ne 0) {
|
||||
abort "Failed to remove local 'main' bucket."
|
||||
}
|
||||
$status = add_bucket 'main' (known_bucket_repo 'main')
|
||||
if ($status -ne 0) {
|
||||
abort "Failed to add remote 'main' bucket."
|
||||
}
|
||||
} else {
|
||||
Write-Host "'$bucket' is not a git repository. Skipped."
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
$previousCommit = (Invoke-Expression "git -C '$bucketLoc' rev-parse HEAD")
|
||||
$previousCommit = git -C "$bucketLoc" rev-parse HEAD
|
||||
git_cmd -C "`"$bucketLoc`"" pull -q
|
||||
if ($show_update_log) {
|
||||
Invoke-Expression "git -C '$bucketLoc' --no-pager log --no-decorate --grep='^(chore)' --invert-grep --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' '$previousCommit..HEAD'"
|
||||
git -C "$bucketLoc" --no-pager log --no-decorate --grep='^(chore)' --invert-grep --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' "$previousCommit..HEAD"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
# -u, --no-update-scoop Don't update Scoop before checking if it's outdated
|
||||
|
||||
. "$PSScriptRoot\..\lib\getopt.ps1"
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Find-Manifest' (indirectly)
|
||||
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Get-Manifest'
|
||||
. "$PSScriptRoot\..\lib\json.ps1" # 'json_path'
|
||||
. "$PSScriptRoot\..\lib\install.ps1" # 'hash_for_url'
|
||||
. "$PSScriptRoot\..\lib\depends.ps1" # 'Get-Dependency'
|
||||
@@ -155,8 +155,8 @@ Function Submit-ToVirusTotal ($url, $app, $do_scan, $retrying = $False) {
|
||||
$api_key = get_config virustotal_api_key
|
||||
if ($do_scan -and !$api_key -and !$warned_no_api_key) {
|
||||
$warned_no_api_key = $true
|
||||
info "Submitting unknown apps needs a VirusTotal API key. " +
|
||||
"Set it up with`n`tscoop config virustotal_api_key <API key>"
|
||||
info 'Submitting unknown apps needs a VirusTotal API key. ' +
|
||||
"Set it up with`n`tscoop config virustotal_api_key <API key>"
|
||||
|
||||
}
|
||||
if (!$do_scan -or !$api_key) {
|
||||
@@ -167,14 +167,14 @@ Function Submit-ToVirusTotal ($url, $app, $do_scan, $retrying = $False) {
|
||||
try {
|
||||
# Follow redirections (for e.g. sourceforge URLs) because
|
||||
# VirusTotal analyzes only "direct" download links
|
||||
$url = $url.Split("#").GetValue(0)
|
||||
$url = $url.Split('#').GetValue(0)
|
||||
$new_redir = $url
|
||||
do {
|
||||
$orig_redir = $new_redir
|
||||
$new_redir = Submit-RedirectedUrl $orig_redir
|
||||
} while ($orig_redir -ne $new_redir)
|
||||
$requests += 1
|
||||
$result = Invoke-WebRequest -Uri "https://www.virustotal.com/vtapi/v2/url/scan" -Body @{apikey=$api_key;url=$new_redir} -Method Post -UseBasicParsing
|
||||
$result = Invoke-WebRequest -Uri 'https://www.virustotal.com/vtapi/v2/url/scan' -Body @{apikey = $api_key; url = $new_redir } -Method Post -UseBasicParsing
|
||||
$submitted = $result.StatusCode -eq 200
|
||||
if ($submitted) {
|
||||
warn "$app`: not found`: submitted $url"
|
||||
@@ -191,7 +191,7 @@ Function Submit-ToVirusTotal ($url, $app, $do_scan, $retrying = $False) {
|
||||
Submit-ToVirusTotal $new_redir $app $do_scan $True
|
||||
} else {
|
||||
warn "$app`: VirusTotal submission of $url failed`:`n" +
|
||||
"`tAPI returned $($result.StatusCode) after retrying"
|
||||
"`tAPI returned $($result.StatusCode) after retrying"
|
||||
}
|
||||
} catch [Exception] {
|
||||
warn "$app`: VirusTotal submission failed`: $($_.Exception.Message)"
|
||||
@@ -199,14 +199,13 @@ Function Submit-ToVirusTotal ($url, $app, $do_scan, $retrying = $False) {
|
||||
}
|
||||
}
|
||||
|
||||
$apps | ForEach-Object {
|
||||
$app = $_
|
||||
foreach ($app in $apps) {
|
||||
# write-host $app
|
||||
$null, $manifest, $bucket, $null = Find-Manifest $app
|
||||
if(!$manifest) {
|
||||
$null, $manifest, $bucket, $null = Get-Manifest $app
|
||||
if (!$manifest) {
|
||||
$exit_code = $exit_code -bor $_ERR_NO_INFO
|
||||
warn "$app`: manifest not found"
|
||||
return
|
||||
continue
|
||||
}
|
||||
|
||||
$urls = script:url $manifest $architecture
|
||||
@@ -215,17 +214,17 @@ $apps | ForEach-Object {
|
||||
$hash = hash_for_url $manifest $url $architecture
|
||||
|
||||
try {
|
||||
if($hash) {
|
||||
if ($hash) {
|
||||
$exit_code = $exit_code -bor (Search-VirusTotal $hash $app)
|
||||
} else {
|
||||
warn "$app`: Can't find hash for $url"
|
||||
}
|
||||
} catch [Exception] {
|
||||
$exit_code = $exit_code -bor $_ERR_EXCEPTION
|
||||
if ($_.Exception.Message -like "*(404)*") {
|
||||
if ($_.Exception.Message -like '*(404)*') {
|
||||
Submit-ToVirusTotal $url $app ($opt.scan -or $opt.s)
|
||||
} else {
|
||||
if ($_.Exception.Message -match "\(204|429\)") {
|
||||
if ($_.Exception.Message -match '\(204|429\)') {
|
||||
abort "$app`: VirusTotal request failed`: $($_.Exception.Message)", $exit_code
|
||||
}
|
||||
warn "$app`: VirusTotal request failed`: $($_.Exception.Message)"
|
||||
|
||||
@@ -9,40 +9,12 @@ if (!$command) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
try {
|
||||
$gcm = Get-Command "$command" -ErrorAction Stop
|
||||
} catch {
|
||||
abort "'$command' not found" 3
|
||||
}
|
||||
$path = Get-CommandPath $command
|
||||
|
||||
$path = $gcm.Path
|
||||
$usershims = Convert-Path (shimdir $false)
|
||||
$globalshims = fullpath (shimdir $true) # don't resolve: may not exist
|
||||
|
||||
if ($path -like "$usershims*" -or $path -like "$globalshims*") {
|
||||
$exepath = if ($path.EndsWith('.exe') -or $path.EndsWith('.shim')) {
|
||||
(Get-Content ($path -replace '\.exe$', '.shim') | Select-Object -First 1).Replace('path = ', '').Replace('"', '')
|
||||
} else {
|
||||
((Select-String -Path $path -Pattern '^(?:@rem|#)\s*(.*)$').Matches.Groups | Select-Object -Index 1).Value
|
||||
}
|
||||
if (!$exepath) {
|
||||
$exepath = ((Select-String -Path $path -Pattern '[''"]([^@&]*?)[''"]' -AllMatches).Matches.Groups | Select-Object -Last 1).Value
|
||||
}
|
||||
|
||||
if (![System.IO.Path]::IsPathRooted($exepath)) {
|
||||
# Expand relative path
|
||||
$exepath = Convert-Path $exepath
|
||||
}
|
||||
|
||||
friendly_path $exepath
|
||||
} elseif ($gcm.CommandType -eq 'Application') {
|
||||
$gcm.Source
|
||||
} elseif ($gcm.CommandType -eq 'Alias') {
|
||||
scoop which $gcm.ResolvedCommandName
|
||||
} else {
|
||||
Write-Host 'Not a scoop shim.'
|
||||
$path
|
||||
if ($null -eq $path) {
|
||||
Write-Host "'$command' not found / not a scoop shim."
|
||||
exit 2
|
||||
} else {
|
||||
friendly_path $path
|
||||
exit 0
|
||||
}
|
||||
|
||||
exit 0
|
||||
|
||||
12
schema.json
12
schema.json
@@ -134,9 +134,15 @@
|
||||
"post_install": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"post_uninstall": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"pre_install": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"pre_uninstall": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"shortcuts": {
|
||||
"$ref": "#/definitions/shortcutsArray"
|
||||
},
|
||||
@@ -567,9 +573,15 @@
|
||||
"post_install": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"post_uninstall": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"pre_install": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"pre_uninstall": {
|
||||
"$ref": "#/definitions/stringOrArrayOfStrings"
|
||||
},
|
||||
"psmodule": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
Param([Switch]$Fast)
|
||||
Push-Location $PSScriptRoot
|
||||
. "$PSScriptRoot\..\..\lib\core.ps1"
|
||||
. "$PSScriptRoot\..\..\lib\install.ps1"
|
||||
|
||||
if (!$Fast) {
|
||||
Write-Host "Install dependencies ..."
|
||||
Invoke-Expression "$PSScriptRoot\install.ps1"
|
||||
& "$PSScriptRoot\install.ps1"
|
||||
}
|
||||
|
||||
$output = "$PSScriptRoot\bin"
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
Param([Switch]$Fast)
|
||||
Push-Location $PSScriptRoot
|
||||
. "$PSScriptRoot\..\..\lib\core.ps1"
|
||||
. "$PSScriptRoot\..\..\lib\install.ps1"
|
||||
|
||||
if (!$Fast) {
|
||||
Write-Host "Install dependencies ..."
|
||||
Invoke-Expression "$PSScriptRoot\install.ps1"
|
||||
& "$PSScriptRoot\install.ps1"
|
||||
}
|
||||
|
||||
$output = "$PSScriptRoot\bin"
|
||||
|
||||
@@ -17,7 +17,7 @@ Describe 'add_alias' -Tag 'Scoop' {
|
||||
$alias_file | Should -Not -Exist
|
||||
|
||||
add_alias 'rm' '"hello, world!"'
|
||||
Invoke-Expression $alias_file | Should -Be 'hello, world!'
|
||||
& $alias_file | Should -Be 'hello, world!'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Describe 'Decompression function' -Tag 'Scoop', 'Decompress' {
|
||||
It 'Decompression test cases should exist' {
|
||||
$testcases = "$working_dir\TestCases.zip"
|
||||
$testcases | Should -Exist
|
||||
compute_hash $testcases 'sha256' | Should -Be '3a442e85b466833eeafbd08c57d8f51bf7ff041867ee0bdb7db1f12480b3624a'
|
||||
compute_hash $testcases 'sha256' | Should -Be '16507166814dbd02be80c14b737eb6b0245c47439ca3ed308b5625d64babecc8'
|
||||
if (!$isUnix) {
|
||||
Microsoft.PowerShell.Archive\Expand-Archive $testcases $working_dir
|
||||
}
|
||||
@@ -41,6 +41,9 @@ Describe 'Decompression function' -Tag 'Scoop', 'Decompress' {
|
||||
$test2 = "$working_dir\7ZipTest2.tgz"
|
||||
$test3 = "$working_dir\7ZipTest3.tar.bz2"
|
||||
$test4 = "$working_dir\7ZipTest4.tar.gz"
|
||||
$test5_1 = "$working_dir\7ZipTest5.7z.001"
|
||||
$test5_2 = "$working_dir\7ZipTest5.7z.002"
|
||||
$test5_3 = "$working_dir\7ZipTest5.7z.003"
|
||||
}
|
||||
|
||||
It 'extract normal compressed file' -Skip:$isUnix {
|
||||
@@ -71,10 +74,24 @@ Describe 'Decompression function' -Tag 'Scoop', 'Decompress' {
|
||||
(Get-ChildItem $to).Count | Should -Be 1
|
||||
}
|
||||
|
||||
It 'extract splited 7z archives (.001, .002, ...)' -Skip:$isUnix {
|
||||
$to = test_extract 'Expand-7zipArchive' $test5_1
|
||||
$to | Should -Exist
|
||||
"$to\empty" | Should -Exist
|
||||
(Get-ChildItem $to).Count | Should -Be 1
|
||||
}
|
||||
|
||||
It 'works with "-Removal" switch ($removal param)' -Skip:$isUnix {
|
||||
$test1 | Should -Exist
|
||||
test_extract 'Expand-7zipArchive' $test1 $true
|
||||
$test1 | Should -Not -Exist
|
||||
$test5_1 | Should -Exist
|
||||
$test5_2 | Should -Exist
|
||||
$test5_3 | Should -Exist
|
||||
test_extract 'Expand-7zipArchive' $test5_1 $true
|
||||
$test5_1 | Should -Not -Exist
|
||||
$test5_2 | Should -Not -Exist
|
||||
$test5_3 | Should -Not -Exist
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,30 +69,30 @@ Describe 'Package Dependencies' -Tag 'Scoop' {
|
||||
BeforeAll {
|
||||
Mock Test-HelperInstalled { $false }
|
||||
Mock get_config { $true } -ParameterFilter { $name -eq 'MSIEXTRACT_USE_LESSMSI' }
|
||||
Mock Find-Manifest { $null, @{}, $null, $null } -ParameterFilter { $AppName -eq 'lessmsi' }
|
||||
Mock Find-Manifest { $null, @{ url = 'test.msi' }, $null, $null } -ParameterFilter { $AppName -eq '7zip' }
|
||||
Mock Find-Manifest { $null, @{}, $null, $null } -ParameterFilter { $AppName -eq 'innounp' }
|
||||
Mock Get-Manifest { 'lessmsi', @{}, $null, $null } -ParameterFilter { $app -eq 'lessmsi' }
|
||||
Mock Get-Manifest { '7zip', @{ url = 'test.msi' }, $null, $null } -ParameterFilter { $app -eq '7zip' }
|
||||
Mock Get-Manifest { 'innounp', @{}, $null, $null } -ParameterFilter { $app -eq 'innounp' }
|
||||
}
|
||||
|
||||
It 'Resolve install dependencies' {
|
||||
Mock Find-Manifest { $null, @{ url = 'test.7z' }, $null, $null }
|
||||
Mock Get-Manifest { 'test', @{ url = 'test.7z' }, $null, $null }
|
||||
Get-Dependency -AppName 'test' -Architecture '32bit' | Should -Be @('lessmsi', '7zip', 'test')
|
||||
Mock Find-Manifest { $null, @{ innosetup = $true }, $null, $null }
|
||||
Mock Get-Manifest { 'test', @{ innosetup = $true }, $null, $null }
|
||||
Get-Dependency -AppName 'test' -Architecture '32bit' | Should -Be @('innounp', 'test')
|
||||
}
|
||||
It 'Resolve script dependencies' {
|
||||
Mock Find-Manifest { $null, @{ pre_install = 'Expand-7zipArchive ' }, $null, $null }
|
||||
Mock Get-Manifest { 'test', @{ pre_install = 'Expand-7zipArchive ' }, $null, $null }
|
||||
Get-Dependency -AppName 'test' -Architecture '32bit' | Should -Be @('lessmsi', '7zip', 'test')
|
||||
}
|
||||
It 'Resolve runtime dependencies' {
|
||||
Mock Find-Manifest { $null, @{}, $null, $null } -ParameterFilter { $AppName -eq 'depends' }
|
||||
Mock Find-Manifest { $null, @{ depends = 'depends' }, $null, $null }
|
||||
Mock Get-Manifest { 'depends', @{}, $null, $null } -ParameterFilter { $app -eq 'depends' }
|
||||
Mock Get-Manifest { 'test', @{ depends = 'depends' }, $null, $null }
|
||||
Get-Dependency -AppName 'test' -Architecture '32bit' | Should -Be @('depends', 'test')
|
||||
}
|
||||
It 'Keep bucket name of app' {
|
||||
Mock Find-Manifest { $null, @{}, $null, $null } -ParameterFilter { $AppName -eq 'bucket/depends' }
|
||||
Mock Find-Manifest { $null, @{ depends = 'bucket/depends' }, $null, $null }
|
||||
Get-Dependency -AppName 'anotherbucket/test' -Architecture '32bit' | Should -Be @('bucket/depends', 'anotherbucket/test')
|
||||
Mock Get-Manifest { 'depends', @{}, 'anotherbucket', $null } -ParameterFilter { $app -eq 'anotherbucket/depends' }
|
||||
Mock Get-Manifest { 'test', @{ depends = 'anotherbucket/depends' }, 'bucket', $null }
|
||||
Get-Dependency -AppName 'bucket/test' -Architecture '32bit' | Should -Be @('anotherbucket/depends', 'bucket/test')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
test/fixtures/decompress/TestCases.zip
vendored
BIN
test/fixtures/decompress/TestCases.zip
vendored
Binary file not shown.
Reference in New Issue
Block a user