<# .SYNOPSIS Installs the extensions into VS Code, from a Gitea release or from dist/. .DESCRIPTION By default this downloads the .vsix assets from the -Tag release and installs them, so a fresh machine needs nothing but VS Code and this repo -- no Node, no toolchain. Pass -Local to install what build.ps1 produced instead. Every install passes --force. Without it VS Code declines to reinstall a version it already has, which would silently do nothing every time you republish the same version number. .PARAMETER Tag Release tag to install from. Defaults to "latest". .PARAMETER Local Install from dist/ rather than downloading. .PARAMETER Only Restrict to these extension ids. .PARAMETER Uninstall Remove the extensions instead of installing them. .EXAMPLE .\scripts\install.ps1 .\scripts\install.ps1 -Local .\scripts\install.ps1 -Tag v0.1.0 .\scripts\install.ps1 -Uninstall #> [CmdletBinding()] param( [string] $Tag = 'latest', [string] $Token, [string[]] $Only, [switch] $Local, [switch] $Uninstall ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' . (Join-Path $PSScriptRoot 'common.ps1') $config = Get-SetupConfig $code = Get-CodeCommand function Select-Configured { param([string[]] $Ids) $chosen = $config.extensions if ($Ids) { $chosen = $chosen | Where-Object { $Ids -contains $_.id } $missing = $Ids | Where-Object { $config.extensions.id -notcontains $_ } if ($missing) { throw "not in config.json: $($missing -join ', ')" } } $chosen } if ($Uninstall) { foreach ($extension in Select-Configured $Only) { # The manifest's publisher is "local", so the installed id is local.. $id = "local.$($extension.id)" Write-Host "uninstalling $id" -ForegroundColor DarkGray & $code --uninstall-extension $id } Write-Host 'Reload the window for this to take effect.' -ForegroundColor Cyan return } $wanted = Select-Configured $Only $packages = @() if ($Local) { $dist = Get-DistDir foreach ($extension in $wanted) { $found = @(Get-ChildItem -Path $dist -Filter "$($extension.id)-*.vsix" | Sort-Object Name -Descending) if ($found.Count -eq 0) { throw "no package for $($extension.id) in $dist. Run build.ps1 first." } $packages += $found[0].FullName } } else { $Token = Get-GiteaToken -Token $Token $release = Get-GiteaRelease -Tag $Tag -Token $Token if (-not $release) { throw ("no release tagged '$Tag' in " + "$($config.gitea.owner)/$($config.gitea.repo). Run publish.ps1 first.") } $assets = @() if ($release.PSObject.Properties.Name -contains 'assets' -and $release.assets) { $assets = @($release.assets) } if ($assets.Count -eq 0) { throw "release '$Tag' has no assets" } # Downloads go to a temp folder, not dist/, so an install never disturbs a build. $staging = Join-Path ([System.IO.Path]::GetTempPath()) "vsix-$Tag-$PID" New-Item -ItemType Directory -Path $staging -Force | Out-Null foreach ($extension in $wanted) { $match = @($assets | Where-Object { $_.name -like "$($extension.id)-*.vsix" } | Sort-Object name -Descending) if ($match.Count -eq 0) { Write-Warning "release '$Tag' has no asset for $($extension.id), skipping" continue } $asset = $match[0] $target = Join-Path $staging $asset.name Write-Host "downloading $($asset.name)" -ForegroundColor DarkGray Save-GiteaAsset -Url $asset.browser_download_url -Destination $target -Token $Token $packages += $target } } if ($packages.Count -eq 0) { throw 'nothing to install' } $failed = @() foreach ($package in $packages) { Write-Host "installing $(Split-Path -Leaf $package)" -NoNewline & $code --install-extension $package --force if ($LASTEXITCODE -eq 0) { Write-Host ' ok' -ForegroundColor Green } else { Write-Host ' FAILED' -ForegroundColor Red $failed += $package } } Write-Host '' if ($failed.Count -gt 0) { throw "$($failed.Count) of $($packages.Count) failed to install: $($failed -join ', ')" } Write-Host "installed $($packages.Count) extension(s). Reload the window." -ForegroundColor Cyan