Repository navigation
Expand file tree
/
Copy pathsetup.ps1
More file actions
245 lines (210 loc) · 9.1 KB
/
Copy pathsetup.ps1
File metadata and controls
245 lines (210 loc) · 9.1 KB
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
<#
.SYNOPSIS
Sets tools4devs up from a clean checkout: prerequisites, dependencies, the pinned
tool artifacts, the checks, and the Windows installer.
.DESCRIPTION
Every step checks whether its work is already done, so running this again is safe and
fast. Nothing is installed on the machine unless you pass -InstallPrerequisites;
without it the script reports exactly what is missing and the command that fixes it.
.PARAMETER InstallPrerequisites
Install anything missing (Node.js, Rust, the Visual Studio C++ build tools) with
winget. Off by default, because installing a compiler toolchain is the machine
owner's decision, not a build script's.
.PARAMETER SkipTests
Skip the domain, interface and host test suites.
.PARAMETER SkipBuild
Set everything up but do not produce the installer.
.PARAMETER Start
Launch the app when the build finishes.
.PARAMETER Dev
Skip the release build and open the development window instead.
.EXAMPLE
.\setup.ps1
Checks the toolchain, installs dependencies, stages the bundled tools, runs the
tests and builds the installer.
.EXAMPLE
.\setup.ps1 -InstallPrerequisites -Start
Installs whatever is missing, builds, then opens the app.
#>
[CmdletBinding()]
param(
[switch]$InstallPrerequisites,
[switch]$SkipTests,
[switch]$SkipBuild,
[switch]$Start,
[switch]$Dev
)
$ErrorActionPreference = 'Stop'
Set-Location -LiteralPath $PSScriptRoot
$script:StepNumber = 0
$script:Started = Get-Date
function Write-Step {
param([string]$Text)
$script:StepNumber++
Write-Host ''
Write-Host (" {0} {1}" -f $script:StepNumber, $Text) -ForegroundColor Cyan
}
function Write-Ok {
param([string]$Text)
Write-Host " $Text" -ForegroundColor Green
}
function Write-Info {
param([string]$Text)
Write-Host " $Text" -ForegroundColor DarkGray
}
function Write-Warn {
param([string]$Text)
Write-Host " $Text" -ForegroundColor Yellow
}
function Invoke-Native {
param([scriptblock]$Action)
# Many of these tools write progress to stderr. Under $ErrorActionPreference = Stop,
# PowerShell 5.1 turns each of those lines into a terminating error even when the
# command succeeds, so the exit code is the only thing worth trusting here.
$previous = $ErrorActionPreference
$ErrorActionPreference = 'Continue'
try { & $Action } finally { $ErrorActionPreference = $previous }
}
function Invoke-Step {
param([string]$Command, [string]$Description)
Write-Info $Command
Invoke-Native { cmd /c "$Command" }
if ($LASTEXITCODE -ne 0) { throw "$Description failed (exit $LASTEXITCODE)" }
}
function Test-Command {
param([string]$Name)
return [bool](Get-Command $Name -ErrorAction SilentlyContinue)
}
function Install-WithWinget {
param([string]$Id, [string]$Label)
if (-not $InstallPrerequisites) {
Write-Warn "$Label is missing. Install it with:"
Write-Warn " winget install -e --id $Id"
Write-Warn " or re-run this script with -InstallPrerequisites."
throw "$Label is required"
}
if (-not (Test-Command 'winget')) {
throw "$Label is missing and winget is not available to install it."
}
Write-Info "winget install -e --id $Id"
Invoke-Native { winget install -e --id $Id --accept-source-agreements --accept-package-agreements --disable-interactivity }
if ($LASTEXITCODE -ne 0) { throw "Could not install $Label" }
Write-Ok "$Label installed. A new terminal may be needed for PATH changes."
}
function Get-VisualStudioBuildTools {
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
if (-not (Test-Path $vswhere)) { return $null }
$found = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath 2>$null
if ([string]::IsNullOrWhiteSpace($found)) { return $null }
return $found
}
Write-Host ''
Write-Host ' tools4devs setup' -ForegroundColor White
Write-Host ' Windows x64 - local tools, no cloud, no AI' -ForegroundColor DarkGray
# ---------------------------------------------------------------- prerequisites
Write-Step 'Checking the toolchain'
if (Test-Command 'node') {
$nodeVersion = (node --version).TrimStart('v')
$nodeMajor = [int]($nodeVersion.Split('.')[0])
if ($nodeMajor -lt 24) {
Write-Warn "Node $nodeVersion found; this project needs 24 or newer."
Install-WithWinget -Id 'OpenJS.NodeJS' -Label 'Node.js 24+'
}
else {
Write-Ok "Node $nodeVersion"
}
}
else {
Install-WithWinget -Id 'OpenJS.NodeJS' -Label 'Node.js'
}
if (Test-Command 'cargo') {
Write-Ok ((cargo --version) -replace '\s+$', '')
}
else {
Install-WithWinget -Id 'Rustlang.Rustup' -Label 'Rust'
}
if (Test-Command 'rustup') {
$targets = rustup target list --installed 2>$null
if ($targets -notcontains 'x86_64-pc-windows-msvc') {
Write-Info 'rustup target add x86_64-pc-windows-msvc'
Invoke-Native { rustup target add x86_64-pc-windows-msvc }
if ($LASTEXITCODE -ne 0) { throw 'Could not add the MSVC target' }
}
Write-Ok 'Rust target x86_64-pc-windows-msvc'
}
$buildTools = Get-VisualStudioBuildTools
if ($buildTools) {
Write-Ok "Visual Studio C++ build tools at $buildTools"
}
else {
Write-Warn 'The Visual Studio C++ build tools were not found. Tauri needs them to link.'
Install-WithWinget -Id 'Microsoft.VisualStudio.2022.BuildTools' -Label 'VS 2022 Build Tools'
Write-Warn 'Open the Visual Studio Installer and add the "Desktop development with C++" workload if the build still fails.'
}
# ---------------------------------------------------------------- dependencies
Write-Step 'Installing the npm dependencies'
if (Test-Path 'node_modules') {
Write-Ok 'node_modules is already there; refreshing against the lockfile'
}
Invoke-Step -Command 'npm install --no-fund --no-audit' -Description 'npm install'
# ---------------------------------------------------------------- tool artifacts
Write-Step 'Downloading and verifying the tools that ship in the installer'
Write-Info 'Nine executables, pinned by version and SHA-256 in tooling/tools.json.'
Write-Info 'A digest that does not match aborts the setup on purpose.'
Invoke-Step -Command 'npm run tools:stage' -Description 'Staging the bundled tools'
$staged = Get-ChildItem 'apps\desktop\src-tauri\resources\tools' -Filter '*.exe' -ErrorAction SilentlyContinue
if (-not $staged -or $staged.Count -eq 0) { throw 'No tool was staged; the installer would ship empty.' }
$stagedMb = [math]::Round((($staged | Measure-Object Length -Sum).Sum / 1MB), 1)
Write-Ok "$($staged.Count) executables staged, $stagedMb MB"
# ---------------------------------------------------------------- checks
if ($SkipTests) {
Write-Step 'Tests skipped (-SkipTests)'
}
else {
Write-Step 'Running the checks'
Invoke-Step -Command 'npm run validate:tools' -Description 'Manifest validation'
Invoke-Step -Command 'npm run audit:capabilities' -Description 'Capability audit'
Invoke-Step -Command 'npx tsc --noEmit -p apps/desktop/tsconfig.json' -Description 'TypeScript'
Invoke-Step -Command 'npm test' -Description 'Domain and interface tests'
Invoke-Step -Command 'cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml' -Description 'Host tests'
Write-Ok 'Everything green'
Write-Info 'The suite that runs every operation against the real binaries is opt-in:'
Write-Info ' cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml -- --include-ignored --nocapture'
}
# ---------------------------------------------------------------- build
if ($Dev) {
Write-Step 'Opening the development window'
Write-Info 'Close the window to come back to this prompt.'
Invoke-Native { npm run tauri:dev }
return
}
if ($SkipBuild) {
Write-Step 'Build skipped (-SkipBuild)'
Write-Host ''
Write-Host ' Ready. Build it with: npm run tauri:build' -ForegroundColor White
return
}
Write-Step 'Building the Windows installer'
Write-Info 'The first Rust build takes a few minutes; later ones are incremental.'
Invoke-Step -Command 'npm run tauri:build' -Description 'Tauri build'
$release = 'apps\desktop\src-tauri\target\release'
$executable = Join-Path $release 'tools4devs.exe'
$installers = Get-ChildItem (Join-Path $release 'bundle\nsis\*.exe'), (Join-Path $release 'bundle\msi\*.msi') -ErrorAction SilentlyContinue
Write-Host ''
Write-Host ' Done' -ForegroundColor Green
foreach ($installer in $installers) {
Write-Host (" {0} {1} MB" -f $installer.Name, [math]::Round($installer.Length / 1MB, 1)) -ForegroundColor White
Write-Host (" {0}" -f $installer.FullName) -ForegroundColor DarkGray
}
Write-Host (" took {0:mm\:ss}" -f ((Get-Date) - $script:Started)) -ForegroundColor DarkGray
if ($Start) {
Write-Host ''
Write-Host ' Opening tools4devs' -ForegroundColor Cyan
Start-Process -FilePath (Resolve-Path $executable)
}
else {
Write-Host ''
Write-Host ' Run it without installing:' -ForegroundColor White
Write-Host (" {0}" -f $executable) -ForegroundColor DarkGray
Write-Host ' Or install it with either bundle above.' -ForegroundColor White
}