forked from ScoopInstaller/Scoop
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathManifestHelpers.ps1
227 lines (207 loc) · 7.79 KB
/
ManifestHelpers.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
@(
@('core', 'Test-ScoopDebugEnabled'),
@('Helpers', 'New-IssuePrompt'),
@('Versions', 'Clear-InstalledVersion')
) | ForEach-Object {
if (!([bool] (Get-Command $_[1] -ErrorAction 'Ignore'))) {
Write-Verbose "Import of lib '$($_[0])' initiated from '$PSCommandPath'"
. (Join-Path $PSScriptRoot "$($_[0]).ps1")
}
}
#region Persistence
function Test-Persistence {
<#
.SYNOPSIS
Persistence check helper for files.
.DESCRIPTION
This will save some lines to not always write `if (!(Test-Path "$persist_dir\$file")) { New-item "$dir\$file" | Out-Null }` inside manifests.
variables `$currentFile`, `$currentFilePersist`, `$currentFileDir` are exposed and could be used inside `Execution` block.
.PARAMETER File
Specifies the file to be checked.
Do not prefix with $dir. All files are already checked against $dir and $persist_dir.
.PARAMETER Content
Specifies the content/value of the created file.
Value should be array of strings or string.
.PARAMETER Execution
Specifies custom scriptblock to run when file is not persisted.
https://github.com/ScoopInstaller/Extras/blob/a84b257fd9636d02295b48c3fd32826487ca9bd3/bucket/ditto.json#L25-L33
.PARAMETER Force
If file does not exist in $persist_dir, but in $dir, -Force has to be used to overwrite $dir file.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[Alias('Path', 'LiteralPath', 'Name', 'InputObject')]
[String[]] $File,
[Parameter(ValueFromPipelineByPropertyName)]
[Alias('Value')]
[Object[]] $Content,
[Parameter(ValueFromPipelineByPropertyName)]
[Alias('ScriptBlock')]
[ScriptBlock] $Execution,
[Switch] $Force
)
process {
for ($ind = 0; $ind -lt $File.Count; ++$ind) {
$currentFile = $File[$ind]
$currentFileDir = Join-Path $dir $currentFile
$currentFilePersist = Join-Path $persist_dir $currentFile
if (!(Test-Path -LiteralPath $currentFilePersist -PathType 'Leaf')) {
if ($Execution) {
if ($Force -or !(Test-Path -LiteralPath $currentFileDir -PathType 'Leaf')) {
Write-Verbose -Message "Executing ScriptBlock for '$currentFile' before persisting"
& $Execution
}
} else {
# Do not overwrite file in $dir, Only if does not exist or Force
if ($Force -or !(Test-Path -LiteralPath $currentFileDir -PathType 'Leaf')) {
# Handle edge case when there is only one file and multiple contents caused by
# If `Test-Persistence alfa.txt @('new', 'beta')` is used,
# Powershell will bind Content as simple array with 2 values instead of Array with nested array with 2 values.
if (($File.Count -eq 1) -and ($Content.Count -gt 1)) {
$cont = $Content
} elseif ($ind -lt $Content.Count) {
$cont = $Content[$ind]
} else {
$cont = $null
}
Write-Verbose -Message "Pre-creating file '$currentFile' before persisting"
# File needs to be precreated in case of nested directories
New-Item -Path $currentFileDir -ItemType 'File' -Force | Out-Null
if ($cont) { Out-UTF8File -Path $currentFileDir -Value $cont }
}
}
}
}
}
}
#endregion Persistence
function Remove-AppDirItem {
<#
.SYNOPSIS
Removes the given item from application directory.
.PARAMETER Item
Specifies the item, which should be removed from $dir.
Wildcards are supported.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[SupportsWildcards()]
[String[]] $Item
)
process {
# GCI is not suitable as it do not support nested folder with include
foreach ($it in $Item) {
Join-Path $dir $it | Remove-Item -ErrorAction 'SilentlyContinue' -Force -Recurse
}
}
}
function Edit-File {
<#
.SYNOPSIS
Finds and replaces text in given file.
.PARAMETER File
Specifies the file, which will be loaded.
File could be passed as full path (used for changing files outside $dir) or just relative path to $dir.
.PARAMETER Find
Specifies the string to be replaced.
.PARAMETER Replace
Specifies the string for replacing all occurrences.
Empty string is default => Found string will be removed.
.PARAMETER Regex
Specifies to use regular expression instead of simple match.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[System.IO.FileInfo] $File,
[Parameter(Mandatory)]
[String[]] $Find,
[String[]] $Replace,
[Switch] $Regex
)
begin {
# Use file from $dir
if (Join-Path $dir $File | Test-Path -PathType 'Leaf') { $File = Join-Path $dir $File }
}
process {
if (!(Test-Path $File -PathType 'Leaf')) {
Write-UserMessage -Message "File '$File' does not exist" -Err
return
}
$content = Get-Content $File
for ($i = 0; $i -lt $Find.Count; ++$i) {
$toFind = $Find[$i]
if (!$Replace -or ($null -eq $Replace[$i])) {
$toReplace = ''
} else {
$toReplace = $Replace[$i]
}
if ($Regex) {
$content = $content -replace $toFind, $toReplace
} else {
$content = $content.Replace($toFind, $toReplace)
}
}
Out-UTF8File -Path $File -Value $content
}
}
function New-JavaShortcutWrapper {
<#
.SYNOPSIS
Creates new shim-like batch file wrapper to spawn jar files within start menu (using shortcut).
.PARAMETER FileName
Specifies the jar executable filename without .jar extension.
Do not pass fullpath, just FILENAME!
#>
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[Alias('Name', 'InputObject')]
[System.IO.FileInfo[]] $FileName
)
process {
foreach ($f in $FileName) {
Join-Path $dir "$f.bat" | Out-UTF8Content -Value "@start javaw.exe -jar `"%~dp0$f.jar`" %*"
}
}
}
#region Asserts
function Assert-Administrator {
<#
.SYNOPSIS
Test administrator privileges.
#>
if (!(is_admin)) { throw [ScoopException]::new('Administrator privileges are required') }
}
function Assert-WindowsMinimalVersion {
<#
.SYNOPSIS
Test minimal windows version requirement.
#>
param([String] $Version)
$cmp = Compare-Version -ReferenceVersion ([Environment]::OSVersion.Version.ToString()) -DifferenceVersion $Version
if ($cmp -eq 1) {
throw [ScoopException]::new("Application requires at least '$Version' Windows version")
}
}
function Assert-ScoopConfigValue {
<#
.SYNOPSIS
Test specific value of scoop's configuration.
#>
param(
[Parameter(Mandatory)]
[String] $ConfigOption,
[Parameter(Mandatory)]
$ExpectedValue
# TODO: Add parameter to define operator (Where-Object)
)
process {
$actualValue = get_config $ConfigOption
if ($actualValue -ne $ExpectedValue) { throw [ScoopException]::new("Configuration option '$ConfigOption' needs to be set to '$ExpectedValue'") }
}
}
#endregion Asserts