Skip to content

Commit f5d4152

Browse files
feat(vscode-web): add offline, use_cached, extensions_dir and auto_install_extensions (#235)
1 parent cd0c730 commit f5d4152

File tree

3 files changed

+138
-12
lines changed

3 files changed

+138
-12
lines changed

Diff for: vscode-web/main.test.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { describe, expect, it } from "bun:test";
2+
import { runTerraformApply, runTerraformInit } from "../test";
3+
4+
describe("vscode-web", async () => {
5+
await runTerraformInit(import.meta.dir);
6+
7+
it("accept_license should be set to true", () => {
8+
const t = async () => {
9+
await runTerraformApply(import.meta.dir, {
10+
agent_id: "foo",
11+
accept_license: "false",
12+
});
13+
};
14+
expect(t).toThrow("Invalid value for variable");
15+
});
16+
17+
it("use_cached and offline can not be used together", () => {
18+
const t = async () => {
19+
await runTerraformApply(import.meta.dir, {
20+
agent_id: "foo",
21+
accept_license: "true",
22+
use_cached: "true",
23+
offline: "true",
24+
});
25+
};
26+
expect(t).toThrow("Offline and Use Cached can not be used together");
27+
});
28+
29+
it("offline and extensions can not be used together", () => {
30+
const t = async () => {
31+
await runTerraformApply(import.meta.dir, {
32+
agent_id: "foo",
33+
accept_license: "true",
34+
offline: "true",
35+
extensions: '["1", "2"]',
36+
});
37+
};
38+
expect(t).toThrow("Offline mode does not allow extensions to be installed");
39+
});
40+
41+
// More tests depend on shebang refactors
42+
});

Diff for: vscode-web/main.tf

+41
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,30 @@ variable "settings" {
9797
default = {}
9898
}
9999

100+
variable "offline" {
101+
type = bool
102+
description = "Just run VS Code Web in the background, don't fetch it from the internet."
103+
default = false
104+
}
105+
106+
variable "use_cached" {
107+
type = bool
108+
description = "Uses cached copy of VS Code Web in the background, otherwise fetches it from internet."
109+
default = false
110+
}
111+
112+
variable "extensions_dir" {
113+
type = string
114+
description = "Override the directory to store extensions in."
115+
default = ""
116+
}
117+
118+
variable "auto_install_extensions" {
119+
type = bool
120+
description = "Automatically install recommended extensions when VS Code Web starts."
121+
default = false
122+
}
123+
100124
resource "coder_script" "vscode-web" {
101125
agent_id = var.agent_id
102126
display_name = "VS Code Web"
@@ -109,8 +133,25 @@ resource "coder_script" "vscode-web" {
109133
TELEMETRY_LEVEL : var.telemetry_level,
110134
// This is necessary otherwise the quotes are stripped!
111135
SETTINGS : replace(jsonencode(var.settings), "\"", "\\\""),
136+
OFFLINE : var.offline,
137+
USE_CACHED : var.use_cached,
138+
EXTENSIONS_DIR : var.extensions_dir,
139+
FOLDER : var.folder,
140+
AUTO_INSTALL_EXTENSIONS : var.auto_install_extensions,
112141
})
113142
run_on_start = true
143+
144+
lifecycle {
145+
precondition {
146+
condition = !var.offline || length(var.extensions) == 0
147+
error_message = "Offline mode does not allow extensions to be installed"
148+
}
149+
150+
precondition {
151+
condition = !var.offline || !var.use_cached
152+
error_message = "Offline and Use Cached can not be used together"
153+
}
154+
}
114155
}
115156

116157
resource "coder_app" "vscode-web" {

Diff for: vscode-web/run.sh

+55-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,40 @@
22

33
BOLD='\033[0;1m'
44
EXTENSIONS=("${EXTENSIONS}")
5+
VSCODE_WEB="${INSTALL_PREFIX}/bin/code-server"
6+
7+
# Set extension directory
8+
EXTENSION_ARG=""
9+
if [ -n "${EXTENSIONS_DIR}" ]; then
10+
EXTENSION_ARG="--extensions-dir=${EXTENSIONS_DIR}"
11+
fi
12+
13+
run_vscode_web() {
14+
echo "👷 Running $VSCODE_WEB serve-local $EXTENSION_ARG --port ${PORT} --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level ${TELEMETRY_LEVEL} in the background..."
15+
echo "Check logs at ${LOG_PATH}!"
16+
"$VSCODE_WEB" serve-local "$EXTENSION_ARG" --port "${PORT}" --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level "${TELEMETRY_LEVEL}" > "${LOG_PATH}" 2>&1 &
17+
}
18+
19+
# Check if the settings file exists...
20+
if [ ! -f ~/.vscode-server/data/Machine/settings.json ]; then
21+
echo "⚙️ Creating settings file..."
22+
mkdir -p ~/.vscode-server/data/Machine
23+
echo "${SETTINGS}" > ~/.vscode-server/data/Machine/settings.json
24+
fi
25+
26+
# Check if vscode-server is already installed for offline or cached mode
27+
if [ -f "$VSCODE_WEB" ]; then
28+
if [ "${OFFLINE}" = true ] || [ "${USE_CACHED}" = true ]; then
29+
echo "🥳 Found a copy of VS Code Web"
30+
run_vscode_web
31+
exit 0
32+
fi
33+
fi
34+
# Offline mode always expects a copy of vscode-server to be present
35+
if [ "${OFFLINE}" = true ]; then
36+
echo "Failed to find a copy of VS Code Web"
37+
exit 1
38+
fi
539

640
# Create install prefix
741
mkdir -p ${INSTALL_PREFIX}
@@ -26,9 +60,7 @@ if [ $? -ne 0 ]; then
2660
echo "Failed to install Microsoft Visual Studio Code Server: $output"
2761
exit 1
2862
fi
29-
printf "$${BOLD}Microsoft Visual Studio Code Server has been installed.\n"
30-
31-
VSCODE_SERVER="${INSTALL_PREFIX}/bin/code-server"
63+
printf "$${BOLD}VS Code Web has been installed.\n"
3264

3365
# Install each extension...
3466
IFS=',' read -r -a EXTENSIONLIST <<< "$${EXTENSIONS}"
@@ -37,20 +69,31 @@ for extension in "$${EXTENSIONLIST[@]}"; do
3769
continue
3870
fi
3971
printf "🧩 Installing extension $${CODE}$extension$${RESET}...\n"
40-
output=$($VSCODE_SERVER --install-extension "$extension" --force)
72+
output=$($VSCODE_WEB "$EXTENSION_ARG" --install-extension "$extension" --force)
4173
if [ $? -ne 0 ]; then
4274
echo "Failed to install extension: $extension: $output"
4375
exit 1
4476
fi
4577
done
4678

47-
# Check if the settings file exists...
48-
if [ ! -f ~/.vscode-server/data/Machine/settings.json ]; then
49-
echo "⚙️ Creating settings file..."
50-
mkdir -p ~/.vscode-server/data/Machine
51-
echo "${SETTINGS}" > ~/.vscode-server/data/Machine/settings.json
79+
if [ "${AUTO_INSTALL_EXTENSIONS}" = true ]; then
80+
if ! command -v jq > /dev/null; then
81+
echo "jq is required to install extensions from a workspace file."
82+
exit 0
83+
fi
84+
85+
WORKSPACE_DIR="$HOME"
86+
if [ -n "${FOLDER}" ]; then
87+
WORKSPACE_DIR="${FOLDER}"
88+
fi
89+
90+
if [ -f "$WORKSPACE_DIR/.vscode/extensions.json" ]; then
91+
printf "🧩 Installing extensions from %s/.vscode/extensions.json...\n" "$WORKSPACE_DIR"
92+
extensions=$(jq -r '.recommendations[]' "$WORKSPACE_DIR"/.vscode/extensions.json)
93+
for extension in $extensions; do
94+
$VSCODE_WEB "$EXTENSION_ARG" --install-extension "$extension" --force
95+
done
96+
fi
5297
fi
5398

54-
echo "👷 Running ${INSTALL_PREFIX}/bin/code-server serve-local --port ${PORT} --host 127.0.0.1 --accept-server-license-terms serve-local --without-connection-token --telemetry-level ${TELEMETRY_LEVEL} in the background..."
55-
echo "Check logs at ${LOG_PATH}!"
56-
"${INSTALL_PREFIX}/bin/code-server" serve-local --port "${PORT}" --host 127.0.0.1 --accept-server-license-terms serve-local --without-connection-token --telemetry-level "${TELEMETRY_LEVEL}" > "${LOG_PATH}" 2>&1 &
99+
run_vscode_web

0 commit comments

Comments
 (0)