Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

| Feature | Description | Install method | Version |
| ------- | ----------- | -------------- | ------- |
| [add-script](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/add-script) | Add a script from a URL or inline text to /usr/local/bin during devcontainer build | custom | 1.0.0 |
| [alexpasmantier/television](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/alexpasmantier-television) | `tv` — fuzzy finder for files, text, and more | gh release | 1.0.1 |
| [ankitpokhrel/jira-cli](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/ankitpokhrel-jira-cli) | `jira` — feature-rich interactive Jira command line client | gh release | 1.0.0 |
| [apt-build-essential](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/apt-build-essential) | `gcc`/`g++`/`make` — C/C++ compiler toolchain via the build-essential package | apt | 1.0.0 |
Expand Down
19 changes: 19 additions & 0 deletions src/add-script/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# add-script

## Project

_No upstream project — this is a utility feature._

## Description

A utility feature that adds a custom script to `/usr/local/bin` during devcontainer build. Accepts either a URL pointing to a script to download, or an inline script supplied directly as text. The script is placed at `/usr/local/bin/<name>` and made executable, but is **not** executed during install. Exactly one of `url` or `script` must be provided along with a `name`.

## Installation Method

No binary is installed. The feature downloads (via `wget` or `curl`) or writes the provided script to `/usr/local/bin/<name>` and sets its permissions to executable (`755`). If neither `wget` nor `curl` is available, `curl` is installed automatically via `apt`.

## Other Notes

- If both `url` and `script` are provided the feature fails with an error.
- If neither `url` nor `script` is provided, or if `name` is not provided, the feature exits successfully without doing anything.
- The script is **not** executed during the devcontainer build — it is only placed at the target path for later use.
24 changes: 24 additions & 0 deletions src/add-script/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "add-script",
"id": "add-script",
"version": "1.0.0",
"description": "Add a script from a URL or inline text to /usr/local/bin during devcontainer build",
"documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/add-script",
"options": {
"name": {
"type": "string",
"default": "",
"description": "Name for the script placed in /usr/local/bin."
},
"url": {
"type": "string",
"default": "",
"description": "URL of a script to download."
},
"script": {
"type": "string",
"default": "",
"description": "Inline script text to add."
}
}
}
74 changes: 74 additions & 0 deletions src/add-script/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash
set -o errexit
set -o pipefail
set -o noclobber
set -o nounset
set -o allexport
readonly name="add-script"

apt_get_update() {
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update -y
fi
}

apt_get_checkinstall() {
if ! dpkg -s "$@" >/dev/null 2>&1; then
apt_get_update
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends --no-install-suggests --option 'Debug::pkgProblemResolver=true' --option 'Debug::pkgAcquire::Worker=1' "$@"
fi
}

apt_get_cleanup() {
apt-get clean
rm -rf /var/lib/apt/lists/*
}

echo_banner() {
local text="$1"
echo -e "\e[1m\e[97m\e[41m$text\e[0m"
}

install() {
if [ -z "${NAME}" ]; then
echo "No script name provided. Nothing to do."
return 0
fi

if [ -n "${URL}" ] && [ -n "${SCRIPT}" ]; then
printf >&2 '=== [ERROR] Both "url" and "script" options are provided. Please provide only one.\n'
exit 1
fi

if [ -z "${URL}" ] && [ -z "${SCRIPT}" ]; then
echo "No script URL or inline script provided. Nothing to do."
return 0
fi

local scriptTargetPath="/usr/local/bin/${NAME}"

if [ -n "${URL}" ]; then
echo "Downloading script from: ${URL}"
if command -v wget >/dev/null 2>&1; then
wget -qO "${scriptTargetPath}" "${URL}"
elif command -v curl >/dev/null 2>&1; then
curl -fsSL -o "${scriptTargetPath}" "${URL}"
else
apt_get_checkinstall curl ca-certificates
apt_get_cleanup
curl -fsSL -o "${scriptTargetPath}" "${URL}"
fi
else
echo "Writing inline script to /usr/local/bin/${NAME}..."
printf '%s' "${SCRIPT}" | tee "${scriptTargetPath}" >/dev/null
fi

chmod 755 "${scriptTargetPath}"
echo "Script added at: ${scriptTargetPath}"
}

echo_banner "devcontainer.community"
echo "Running $name..."
install "$@"
echo "(*) Done!"
18 changes: 18 additions & 0 deletions test/add-script/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash


set -e

# Optional: Import test library bundled with the devcontainer CLI
# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib
# Provides the 'check' and 'reportResults' commands.
source dev-container-features-test-lib

# Feature-specific tests
# The 'check' command comes from the dev-container-features-test-lib. Syntax is...
# check <LABEL> <cmd> [args...]
check "bash is available" bash -c "bash --version"

# Report results
# If any of the checks above exited with a non-zero exit code, the test will fail.
reportResults
Loading