-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathrun_onchange_windows-install-packages.ps1.tmpl
More file actions
130 lines (110 loc) · 4.65 KB
/
run_onchange_windows-install-packages.ps1.tmpl
File metadata and controls
130 lines (110 loc) · 4.65 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
#!/usr/bin/env pwsh
{{ if eq .chezmoi.os "windows" -}}
# Choco packages
if (-not (Get-Command gsudo -ErrorAction SilentlyContinue)) {
choco install gsudo -y -s'https://chocolatey.org/api/v2/'
}
$desiredPackages = @({{ range .packages.chocolatey }}'{{ . }}', {{ end }}'')
$desiredPackages = $desiredPackages | Where-Object { $_ -ne '' }
# Check which packages are already installed
$installedRaw = choco list --limit-output 2>$null
$installed = @{}
foreach ($line in $installedRaw) {
$parts = $line -split '\|'
if ($parts.Count -ge 1) {
$installed[$parts[0].ToLower()] = $true
}
}
# Find packages that need to be installed
$toInstall = $desiredPackages | Where-Object { -not $installed[$_.ToLower()] }
if ($toInstall) {
Write-Host "Installing new packages: $($toInstall -join ', ')" -ForegroundColor Cyan
gsudo choco install $toInstall -y -s'https://chocolatey.org/api/v2/'
}
# Check for outdated packages among our desired set
$outdatedRaw = choco outdated --limit-output 2>$null
$toUpgrade = @()
foreach ($line in $outdatedRaw) {
$parts = $line -split '\|'
if ($parts.Count -ge 1 -and $desiredPackages -contains $parts[0]) {
$toUpgrade += $parts[0]
Write-Host " $($parts[0]): $($parts[1]) -> $($parts[2])" -ForegroundColor Yellow
}
}
# powershell-core cannot be upgraded while pwsh is running
$pwshRunning = Get-Process -Name pwsh -ErrorAction SilentlyContinue
if ($pwshRunning -and $toUpgrade -contains 'powershell-core') {
Write-Warning "Skipping powershell-core upgrade: pwsh is currently running. Close all pwsh instances and run 'chezmoi apply --force' to upgrade."
$toUpgrade = $toUpgrade | Where-Object { $_ -ne 'powershell-core' }
}
# chezmoi cannot be upgraded while it is running
$chezmoiRunning = Get-Process -Name chezmoi -ErrorAction SilentlyContinue
if ($chezmoiRunning -and $toUpgrade -contains 'chezmoi') {
Write-Warning "Skipping chezmoi upgrade: chezmoi is currently running. Run 'gsudo choco upgrade chezmoi -y' manually after chezmoi finishes."
$toUpgrade = $toUpgrade | Where-Object { $_ -ne 'chezmoi' }
}
if ($toUpgrade) {
Write-Host "Upgrading outdated packages: $($toUpgrade -join ', ')" -ForegroundColor Cyan
gsudo choco upgrade $toUpgrade -y -s'https://chocolatey.org/api/v2/'
} else {
Write-Host "All Chocolatey packages are up to date." -ForegroundColor Green
}
{{ end -}}
# Install npm global packages
if (Get-Command npm -ErrorAction SilentlyContinue) {
$desiredNpmPackages = @({{ range .packages.npm_globals }}'{{ . }}', {{ end }}'')
$desiredNpmPackages = $desiredNpmPackages | Where-Object { $_ -ne '' }
$installedNpm = npm list -g --depth=0 --json 2>$null | ConvertFrom-Json
$installedNpmNames = $installedNpm.dependencies.PSObject.Properties.Name
foreach ($pkg in $desiredNpmPackages) {
if ($installedNpmNames -notcontains $pkg) {
Write-Host "Installing npm package: $pkg" -ForegroundColor Cyan
npm install -g $pkg
}
}
Write-Host "Updating npm global packages..." -ForegroundColor Cyan
npm update -g $desiredNpmPackages
} else {
Write-Warning "npm not found; skipping npm global installs."
}
# Install Modules to a local path to avoid OneDrive Documents redirection
$ModulePath = [IO.Path]::Combine($HOME, '.local', 'share', 'powershell', 'Modules')
if (-not (Test-Path $ModulePath)) {
New-Item -ItemType Directory -Path $ModulePath -Force | Out-Null
}
# Set persistent user-level PSModulePath so PowerShell 5.1 discovers modules here
# (PS 5.1 doesn't read powershell.config.json)
$currentUserModulePath = [Environment]::GetEnvironmentVariable('PSModulePath', 'User')
if (-not $currentUserModulePath -or -not ($currentUserModulePath -split [IO.Path]::PathSeparator -contains $ModulePath)) {
[Environment]::SetEnvironmentVariable('PSModulePath', $ModulePath, 'User')
}
# Trust PSGallery so Save-Module doesn't prompt
if ((Get-PSRepository -Name PSGallery).InstallationPolicy -ne 'Trusted') {
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
}
$installModules = {
param($ModulePath)
$json = @"
{{.packages.ps_modules | toPrettyJson}}
"@
$modules = $json | ConvertFrom-Json
foreach ($property in $modules.PSObject.Properties) {
$saveSplat = @{
Name = $property.Name
Path = $ModulePath
Repository = 'PSGallery'
Force = $true
}
if ($property.Value.Prerelease) {
$saveSplat['AllowPrerelease'] = $true
}
Write-Host "Saving module $($property.Name)..." -ForegroundColor Cyan
Save-Module @saveSplat
}
}
# Install modules in pwsh
& $installModules $ModulePath
# Install modules in Windows PowerShell
{{ if eq .chezmoi.os "windows" -}}
powershell.exe -NoProfile -Command "& { $($installModules.ToString()) } '$ModulePath'"
{{ end -}}