1#!/bin/bash 2# Copyright 2020 the V8 project authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6# The purpose of this script is to make it easy to download/update 7# Visual Studio Code on Linux distributions where for whatever reason there 8# is no good way to do so via the package manager. 9 10# Version of this script: 2020.07.04 11 12# Basic checking of arguments: want at least one, and it's not --help. 13VERSION="$1" 14[ -z "$VERSION" -o \ 15 "$VERSION" == "-h" -o \ 16 "$VERSION" == "--help" -o \ 17 "$VERSION" == "help" ] && { 18 echo "Usage: $0 <version>" 19 echo "<version> may be --auto for auto-detecting the latest available." 20 exit 1 21} 22 23die() { 24 echo "Error: $1" 25 exit 1 26} 27 28if [ "$VERSION" == "--auto" -o "$VERSION" == "auto" ]; then 29 echo "Searching online for latest available version..." 30 # Where to find the latest available version (we assume that it's mentioned 31 # in the first 1000 characters, which is true as of 2020-07). 32 AVAILABLE_PACKAGES_URL="https://packages.microsoft.com/repos/vscode/dists/stable/main/binary-amd64/Packages" 33 VERSION=$(curl "$AVAILABLE_PACKAGES_URL" --range 0-1000 --silent \ 34 | grep "^Version: " \ 35 | sed 's/[^0-9]*\([0-9.]*\).*/\1/') 36 if [ -z "$VERSION" ]; then 37 die "Detecting latest version failed, please specify it manually." 38 else 39 echo "Latest version found: $VERSION" 40 fi 41fi 42 43# Constant definitions for local paths. Edit these to your liking. 44VSCODE_DIR="$HOME/vscode" 45BACKUP_DIR="$HOME/vscode.prev" 46DOWNLOADS_DIR="$HOME/Downloads" 47DOWNLOAD_FILE="$DOWNLOADS_DIR/vscode-$VERSION.tar.gz" 48DESKTOP_FILE_DIR="$HOME/.local/share/applications" 49DESKTOP_FILE="$DESKTOP_FILE_DIR/code.desktop" 50 51# Constant definitions for remote/upstream things. Might need to be updated 52# when upstream changes things. 53# Where to find the version inside VS Code's installation directory. 54PACKAGE_JSON="$VSCODE_DIR/resources/app/package.json" 55ICON="$VSCODE_DIR/resources/app/resources/linux/code.png" 56# Where to download the archive. 57DOWNLOAD_URL="https://update.code.visualstudio.com/$VERSION/linux-x64/stable" 58CODE_BIN="$VSCODE_DIR/bin/code" 59 60# Check for "code" in $PATH; create a symlink if we can find a good place. 61SYMLINK=$(which code) 62if [ -z "$SYMLINK" ]; then 63 IFS=':' read -ra PATH_ARRAY <<< "$PATH" 64 for P in "${PATH_ARRAY[@]}"; do 65 if [ "$P" == "$HOME/bin" -o \ 66 "$P" == "$HOME/local/bin" -o \ 67 "$P" == "$HOME/.local/bin" ]; then 68 LOCALBIN="$P" 69 break 70 fi 71 done 72 if [ -n "$LOCALBIN" ]; then 73 echo "Adding symlink to $LOCALBIN..." 74 if [ ! -d "$LOCALBIN" ]; then 75 mkdir -p "$LOCALBIN" || die "Failed to create $LOCALBIN." 76 fi 77 ln -s "$CODE_BIN" "$LOCALBIN/code" || die "Failed to create symlink." 78 else 79 echo "Please put a symlink to $CODE_BIN somewhere on your \$PATH." 80 fi 81fi 82 83if [ ! -r "$DESKTOP_FILE" ]; then 84 echo "Creating .desktop file..." 85 mkdir -p "$DESKTOP_FILE_DIR" || die "Failed to create .desktop directory." 86 cat <<EOF > "$DESKTOP_FILE" 87#!/usr/bin/env xdg-open 88[Desktop Entry] 89Name=Visual Studio Code 90Comment=Code Editing. Redefined. 91GenericName=Text Editor 92Exec=$CODE_BIN --unity-launch %F 93Icon=$ICON 94Type=Application 95StartupNotify=false 96StartupWMClass=Code 97Categories=Utility;TextEditor;Development;IDE; 98MimeType=text/plain;inode/directory; 99Actions=new-empty-window; 100Keywords=vscode; 101 102X-Desktop-File-Install-Version=0.24 103 104[Desktop Action new-empty-window] 105Name=New Empty Window 106Exec=$CODE_BIN --new-window %F 107Icon=$ICON 108EOF 109 chmod +x "$DESKTOP_FILE" || die "Failed to make .desktop file executable." 110fi 111 112# Find currently installed version. 113if [ -d "$VSCODE_DIR" ]; then 114 if [ ! -r "$PACKAGE_JSON" ]; then 115 die "$PACKAGE_JSON file not found, this script must be updated." 116 fi 117 INSTALLED=$(grep '"version":' "$PACKAGE_JSON" \ 118 | sed 's/[^0-9]*\([0-9.]*\).*/\1/') 119 echo "Detected installed version: $INSTALLED" 120 if [ "$VERSION" == "$INSTALLED" ] ; then 121 echo "You already have that version." 122 exit 0 123 else 124 echo "Updating from $INSTALLED to $VERSION..." 125 fi 126fi 127 128if [ ! -r "$DOWNLOAD_FILE" ]; then 129 echo "Downloading..." 130 if [ ! -d "$DOWNLOADS_DIR" ]; then 131 mkdir -p "$DOWNLOADS_DIR" || die "Failed to create $DOWNLOADS_DIR." 132 fi 133 wget "$DOWNLOAD_URL" -O "$DOWNLOAD_FILE" || die "Downloading failed." 134else 135 echo "$DOWNLOAD_FILE already exists; delete it to force re-download." 136fi 137 138echo "Extracting..." 139TAR_DIR=$(tar -tf "$DOWNLOAD_FILE" | head -1) 140[ -z "$TAR_DIR" ] && die "Couldn't read archive." 141TMP_DIR=$(mktemp -d) 142tar -C "$TMP_DIR" -xf "$DOWNLOAD_FILE" || { 143 rm -rf "$TMP_DIR" 144 die "Extracting failed." 145} 146 147if [ -d "$BACKUP_DIR" ]; then 148 echo "Deleting previous backup..." 149 rm -rf "$BACKUP_DIR" 150fi 151 152if [ -d "$VSCODE_DIR" ]; then 153 echo "Moving previous installation..." 154 mv "$VSCODE_DIR" "$BACKUP_DIR" 155fi 156 157echo "Installing new version..." 158mv "$TMP_DIR/$TAR_DIR" "$VSCODE_DIR" 159rmdir "$TMP_DIR" 160 161echo "All done, enjoy coding!" 162