Last active
April 26, 2019 03:38
-
-
Save Pagliacii/40003338dab7e9a977c97d6fd009b4ee to your computer and use it in GitHub Desktop.
This script is used to install the vscode extension manually. Or to install an extension to the code-server.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
#=============================================================================== | |
# This script is used to install the vscode extension manually. | |
# Or to install an extension to the code-server. | |
# Inspire by https://github.com/codercom/code-server/issues/171#issuecomment-473690326 | |
# | |
# It has two way to install the extension: | |
# 1. by the extension ID | |
# 2. by the local vsix file | |
# | |
# Author: Pagliacii | |
# Date: 2019-04-25 | |
#=============================================================================== | |
# 1. Setup the color variables | |
# ref: https://github.com/robbyrussell/oh-my-zsh/blob/master/tools/install.sh | |
# Use colors, but only if connected to a terminal, and that terminal | |
# supports them. | |
if which tput >/dev/null 2>&1; then | |
ncolors=$(tput colors) | |
fi | |
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then | |
RED="$(tput setaf 1)" | |
GREEN="$(tput setaf 2)" | |
YELLOW="$(tput setaf 3)" | |
BLUE="$(tput setaf 4)" | |
BOLD="$(tput bold)" | |
NORMAL="$(tput sgr0)" | |
else | |
RED="" | |
GREEN="" | |
YELLOW="" | |
BLUE="" | |
BOLD="" | |
NORMAL="" | |
fi | |
# Only enable exit-on-error after the non-critical colorization stuff, | |
# which may fail on systems lacking tput or terminfo | |
set -e | |
# 2. Tool functions | |
usage() { | |
echo "" | |
echo "Usage: install-ext.sh [-i|--id <id>] [-f|--file <file>]" | |
echo " [-v|--version <version>] [-d|--destination <folder>]" | |
echo " [-s|--silent] [-c|--skip-check] [-h|--help]" | |
echo "" | |
echo " -i, --id <id> install by the extension" | |
echo " -f, --file <file> install by the vsix file" | |
echo " -v, --version <version> install the specify version" | |
echo " -d, --destination <folder> which folder to install the extension" | |
echo " -s, --silent keep silent" | |
echo " -c, --skip-check skip check dependencies" | |
echo " -h, --help to show this message and exit" | |
exit 1 | |
} | |
green() { | |
if ! ${SILENT}; then | |
printf "${GREEN}$1\n${NORMAL}" | |
fi | |
} | |
yellow() { | |
if ! ${SILENT}; then | |
printf "${YELLOW}$1\n${NORMAL}" | |
fi | |
} | |
red() { | |
if ! ${SILENT}; then | |
printf "${RED}$1\n${NORMAL}" | |
fi | |
} | |
blue() { | |
if ! ${SILENT}; then | |
printf "${BLUE}$1\n${NORMAL}" | |
fi | |
} | |
run() { | |
if ${SILENT}; then | |
$1 &>/dev/null | |
else | |
$1 | |
fi | |
} | |
check-dependencies() { | |
local DEPENDENCIES=$@ | |
echo "${BOLD}Check dependencies: ${NORMAL}${BLUE}${DEPENDENCIES}${NORMAL}" | |
for DEP in ${DEPENDENCIES} | |
do | |
printf "\t${BLUE}${DEP}" | |
if which ${DEP} >/dev/null 2>&1; then | |
printf "${GREEN} installed\n${NORMAL}" | |
else | |
printf "${YELLOW} not installed\n${NORMAL}" | |
exit 1 | |
fi | |
done | |
echo | |
} | |
progress-bar() { | |
local PID=$1 | |
while kill -0 $PID 2>/dev/null; do | |
for s in / - \\ \|; do | |
printf "\r$s" | |
sleep 0.1 | |
done | |
done | |
echo -e "\r " | |
} | |
# 3. Parse the command line parameters | |
[ $# -eq 0 ] && usage | |
POSITIONAL=() | |
VERSION=latest | |
SILENT=false | |
SKIP=false | |
while [[ $# -gt 0 ]] | |
do | |
key="$1" | |
case $key in | |
-i|--id) | |
USEID=true | |
EXTENSION="$2" | |
shift # past argument | |
shift # past value | |
;; | |
-f|--file) | |
USEID=false | |
EXTENSION="$2" | |
shift | |
shift | |
;; | |
-v|--version) | |
VERSION="$2" | |
shift | |
shift | |
;; | |
-d|--destination) | |
DESTINATION="$2" | |
shift | |
shift | |
;; | |
-s|--silent) | |
SILENT=true | |
shift | |
;; | |
-c|--skip-check) | |
SKIP=true | |
shift | |
;; | |
-h|--help) | |
usage | |
;; | |
-*|--*) | |
red "Unknown arguments: $1" | |
usage | |
;; | |
*) | |
POSITINAL+=("$1") | |
shift # past argument | |
;; | |
esac | |
done | |
set -- "${POSITINAL[@]}" # restore positinal parameters | |
[ -z "${EXTENSION}" ] && red "Please specify an extension id or vsix file" && usage | |
# 4. Check the environment | |
${USEID} && DEPENDENCIES="curl bsdtar" || DEPENDENCIES="bsdtar jq" | |
${SKIP} && yellow "Skip check dependencies" || run "check-dependencies ${DEPENDENCIES}" | |
[ -d "extension" ] && red "Please remove the extension directory in ${PWD}" && exit 1 | |
[ -z ${DESTINATION} ] && DESTINATION=${HOME}/.local/share/code-server/extensions | |
[ ! -d ${DESTINATION} ] && mkdir -p ${DESTINATION} | |
green "Local extensions directory: ${BLUE}${DESTINATION}" | |
# 5. The install function | |
install-by-id() { | |
[ -z "$1" ] && red "Invoke install function without extension id" && exit 1 | |
local ID=$1 | |
local BASEURL="https://marketplace.visualstudio.com" | |
local URL=${BASEURL}"/itemdetails?itemName="${ID} | |
local TEMP=/tmp/response | |
green "Ready to search extension: ${BLUE}${ID}${GREEN} on <${BASEURL}>" | |
green "Search URL: ${BLUE}${URL}" | |
green "Searching..." | |
if ${SILENT}; then | |
local RESPONSE=$(curl -sSL -w "HTTPSTATUS:%{http_code}" ${URL}) | |
else | |
curl -sSL -w "HTTPSTATUS:%{http_code}" ${URL} >${TEMP} & | |
progress-bar $! | |
local RESPONSE=$(cat ${TEMP}) | |
rm ${TEMP} | |
fi | |
local BODY=$(echo ${RESPONSE} | sed -e 's/HTTPSTATUS\:.*//g') | |
local STATUS=$(echo ${RESPONSE} | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') | |
if [ ! ${STATUS} -eq 200 ]; then | |
[ ${STATUS} -eq 404 ] && red "Extension not found: ${ID}" && exit 127 | |
red "Error [HTTP status: ${STATUS}]" && exit 1 | |
fi | |
local PUBLISHER=$(echo ${BODY} | perl -nle 'print $& while m{(?<=\"PublisherName\":\")[\w-]+}g') | |
local NAME=$(echo ${BODY} | perl -nle 'print $& while m{(?<=\"ExtensionName\":\")[\w-]+}g') | |
local VER=$(echo ${BODY} | perl -nle 'print $& while m{(?<=\"Version\":\")[\d|\.]+}g') | |
green "Extension : ${BLUE}${NAME}" | |
green "Publisher : ${BLUE}${PUBLISHER}" | |
green "Version : ${BLUE}${VER}" | |
green | |
if [[ -z "$2" || "$2" = latest ]]; then | |
green "Download latest version: ${BLUE}${VER}" | |
else | |
VER="$2" | |
green "Download specify version: ${BLUE}${VER}" | |
fi | |
local DOWNLOADURL="${BASEURL}/_apis/public/gallery/publishers/${PUBLISHER}/vsextensions/${NAME}/${VER}/vspackage" | |
green "Download URL: ${BLUE}${DOWNLOADURL}" | |
green "Downloading..." | |
if ${SILENT}; then | |
curl -sSJL ${DOWNLOADURL} | bsdtar -xf - extension &>/dev/null | |
else | |
$(curl -sSJL ${DOWNLOADURL} | bsdtar -xf - extension) & | |
progress-bar $! | |
fi | |
green "Installing..." | |
if ${SILENT}; then | |
mv extension ${DESTINATION}/${ID}.${VER} &>/dev/null | |
else | |
mv extension ${DESTINATION}/${ID}.${VER} & | |
progress-bar $! | |
fi | |
green "DONE" | |
} | |
install-by-file() { | |
[ -z "$1" ] && red "Invoke install function without vsix file" && exit 1 | |
local FILE="$1" | |
[ ! -e ${FILE} ] && red "No such file: ${FILE}" && exit 127 | |
green "Decompressing..." | |
if ${SILENT}; then | |
bsdtar -xf ${FILE} extension &>/dev/null | |
else | |
bsdtar -xf ${FILE} extension & | |
progress-bar $! | |
fi | |
local JSONFILE="extension/package.json" | |
[ ! -e ${JSONFILE} ] && red "No such file: ${JSONFILE}" && exit 127 | |
local NAME=$(cat ${JSONFILE} | jq -rM ".name") | |
local PUBLISHER=$(cat ${JSONFILE} | jq -rM ".publisher") | |
local VER=$(cat ${JSONFILE} | jq -rM ".version") | |
green "Extension : ${NAME}" | |
green "Publisher : ${PUBLISHER}" | |
green "Version : ${VER}" | |
green | |
local PACKAGE=${PUBLISHER}.${NAME}.${VER} | |
green "Install..." | |
if ${SILENT}; then | |
mv extension ${DESTINATION}/${PACKAGE} &>/dev/null | |
else | |
mv extension ${DESTINATION}/${PACKAGE} & | |
progress-bar $! | |
fi | |
green "DONE" | |
} | |
# 6. Ready to install | |
if ${USEID}; then | |
install-by-id ${EXTENSION} ${VERSION} | |
else | |
install-by-file ${EXTENSION} | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment