#!/usr/bin/env bash # Installs the extensions into VS Code, from a Gitea release or from dist/. # # The bash twin of install.ps1, for a Linux or macOS machine without PowerShell. By # default it downloads the .vsix assets of the "latest" release and installs them, so a # fresh machine needs nothing but VS Code, curl, and this repo. --local installs what is # already in dist/ instead. # # Every install passes --force: without it VS Code declines to reinstall a version it # already has, which would silently do nothing every time the same version number is # republished. # # Usage: # scripts/install.sh install the "latest" release # scripts/install.sh --tag v0.1.0 a specific release # scripts/install.sh --local from dist/ # scripts/install.sh --only vertical-tabs --only colored-references # scripts/install.sh --uninstall # scripts/install.sh --token otherwise GITEA_TOKEN or ~/.gitea-token # shellcheck source=common.sh . "$(dirname "${BASH_SOURCE[0]}")/common.sh" tag=latest token="" only="" local_install="" uninstall="" while [ $# -gt 0 ]; do case "$1" in --tag) tag="$2"; shift 2 ;; --token) token="$2"; shift 2 ;; --only) only="$only $2"; shift 2 ;; --local) local_install=1; shift ;; --uninstall) uninstall=1; shift ;; -h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; *) die "unknown argument: $1 (try --help)" ;; esac done load_config code="$(code_command)" extensions="$(configured_extensions "$only")" if [ -n "$uninstall" ]; then while IFS=$'\t' read -r id _path _repo; do [ -n "$id" ] || continue # The manifest's publisher is "local", so the installed id is local.. note "uninstalling local.$id" "$code" --uninstall-extension "local.$id" || true done <<<"$extensions" echo "Reload the window for this to take effect." exit 0 fi packages=() staging="" if [ -n "$local_install" ]; then while IFS=$'\t' read -r id _path _repo; do [ -n "$id" ] || continue found="$(ls -1 "$setup_dist"/"$id"-*.vsix 2>/dev/null | sort -r | head -n1 || true)" [ -n "$found" ] || die "no package for $id in $setup_dist. Run build.ps1 or ci-release.sh first." packages+=("$found") done <<<"$extensions" else require_gitea token="$(gitea_token "$token")" release="$(gitea_release "$tag" "$token")" [ -n "$release" ] || die "no release tagged '$tag' in $gitea_owner/$gitea_repo. Run publish.ps1 first." assets="$(json_rows - assets name browser_download_url <<<"$release")" [ -n "$assets" ] || die "release '$tag' has no assets" # Downloads go to a temp folder, not dist/, so an install never disturbs a build. staging="$(mktemp -d -t vsix-XXXXXX)" trap 'rm -rf "$staging"' EXIT while IFS=$'\t' read -r id _path _repo; do [ -n "$id" ] || continue match="$(grep -P "^$id-.*\.vsix\t" <<<"$assets" | sort -r | head -n1 || true)" if [ -z "$match" ]; then warn "release '$tag' has no asset for $id, skipping" continue fi name="${match%%$'\t'*}" url="${match#*$'\t'}" note "downloading $name" gitea_download "$url" "$staging/$name" "$token" packages+=("$staging/$name") done <<<"$extensions" fi [ ${#packages[@]} -gt 0 ] || die "nothing to install" failed=0 for package in "${packages[@]}"; do printf 'installing %s' "$(basename "$package")" if "$code" --install-extension "$package" --force >/dev/null 2>&1; then ok ' ok' else printf '\033[31m FAILED\033[0m\n' failed=$((failed + 1)) fi done echo [ "$failed" -eq 0 ] || die "$failed of ${#packages[@]} failed to install" echo "installed ${#packages[@]} extension(s). Reload the window."