Skip to content

feat: VSCode Tasks Runner and deckdebug.sh Enhancements #763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 23, 2025
19 changes: 18 additions & 1 deletion scripts/deckdebug.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
# Usage: deckdebug.sh DECKIP:8081
# Dependencies: websocat jq curl chromium

if [ "$#" -ne 1 ]; then
echo "Error: Missing or incorrect argument." >&2
echo "Usage: deckdebug.sh DECKIP:8081" >&2
exit 1
fi


# https://jackson.dev/post/a-portable-nix-shell-shebang/
if [ -z "$INSIDE_NIX_RANDOMSTRING" ] && command -v nix &> /dev/null; then
# If the user has nix, relaunch in nix shell with dependencies added
Expand All @@ -13,6 +20,16 @@ if [ -z "$INSIDE_NIX_RANDOMSTRING" ] && command -v nix &> /dev/null; then
exit $?
fi

required_dependencies=(websocat jq curl chromium)

# Check if the dependencies are installed
for cmd in "${required_dependencies[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
echo "Error: '$cmd' is not installed. Please install it and try again." >&2
exit 1
fi
done

chromium --remote-debugging-port=9222 &
sleep 2

Expand Down Expand Up @@ -41,4 +58,4 @@ while :; do
fi

sleep 5
done
done
Empty file modified scripts/plugin-info.sh
100644 → 100755
Empty file.
120 changes: 120 additions & 0 deletions scripts/tasks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env bash
# ./script/task.sh: Run a VSCode task from tasks.json including its dependencies.
#
# Usage: ./scripts/task.sh TASK_LABEL
#
# This script looks for .vscode/tasks.json in your workspace folder (or current directory)
# and executes the command associated with the given task label.
#
# It also handles the "dependsOn" field recursively.
#
# Requirements: jq sed

# https://jackson.dev/post/a-portable-nix-shell-shebang/
if [ -z "$INSIDE_NIX_RANDOMSTRING" ] && command -v nix &> /dev/null; then
# If the user has nix, relaunch in nix shell with dependencies added
INSIDE_NIX_RANDOMSTRING=1 nix shell \
nixpkgs#jq \
nixpkgs#gnused \
--command "$0" "$@"
exit $?
fi

required_dependencies=(jq sed)

# Check if the dependencies are installed
for cmd in "${required_dependencies[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
echo "Error: '$cmd' is not installed. Please install it and try again." >&2
exit 1
fi
done


set -euo pipefail

# Use WORKSPACE_FOLDER if set; otherwise, assume current directory.
WORKSPACE_FOLDER="${WORKSPACE_FOLDER:-$(pwd)}"
TASKS_FILE="$WORKSPACE_FOLDER/.vscode/tasks.json"

if [ ! -f "$TASKS_FILE" ]; then
echo "Error: tasks.json not found at $TASKS_FILE" >&2
exit 1
fi

if [ $# -lt 1 ]; then
echo "Usage: $0 TASK_LABEL" >&2
exit 1
fi

# Remove comment lines (lines starting with //) from the tasks file to be compliant with the JSON format.
TASKS_JSON=$(sed '/^[[:space:]]*\/\//d' "$TASKS_FILE")

TASK_LABEL="$1"
shift

# run_task recursively looks up the task by label,
# runs any dependencies first, then executes its command.
run_task() {
local label="$1"
echo "Looking up task: $label"

# Get the task object from the cleaned JSON.
local task
task=$(echo "$TASKS_JSON" | jq --arg label "$label" -r '.tasks[] | select(.label == $label)')
if [ -z "$task" ]; then
echo "Error: Task with label '$label' not found in $TASKS_FILE" >&2
exit 1
fi

# If the task has dependencies, run them first.
local depends
depends=$(echo "$task" | jq -r '.dependsOn? // empty')
if [ -n "$depends" ] && [ "$depends" != "null" ]; then
# "dependsOn" can be an array or a string.
if echo "$depends" | jq -e 'if type=="array" then . else empty end' >/dev/null; then
for dep in $(echo "$depends" | jq -r '.[]'); do
run_task "$dep"
done
else
run_task "$depends"
fi
fi

# Check if the task has either a command or script.
local has_command has_script
has_command=$(echo "$task" | jq -r 'has("command")')
has_script=$(echo "$task" | jq -r 'has("script")')
if [[ "$has_command" != "true" && "$has_script" != "true" ]]; then
echo "Task '$label' has no command or script; skipping execution."
return
fi

# Determine the command to run:
local cmd=""
if echo "$task" | jq 'has("command")' | grep -q "true"; then
cmd=$(echo "$task" | jq -r '.command')
elif echo "$task" | jq 'has("script")' | grep -q "true"; then
local script
script=$(echo "$task" | jq -r '.script')
local path
path=$(echo "$task" | jq -r '.path // empty')
if [ -n "$path" ]; then
cmd="cd $path && npm run $script"
else
cmd="npm run $script"
fi
else
echo "Error: Task '$label' does not have a command or script." >&2
exit 1
fi

# Substitute ${workspaceFolder} with the actual folder path.
cmd="${cmd//\$\{workspaceFolder\}/$WORKSPACE_FOLDER}"

echo "Running task '$label': $cmd"
# Run the task in a subshell so that directory changes don't persist.
( eval "$cmd" )
}

run_task "$TASK_LABEL"