Skip to content

Commit 2a79d75

Browse files
authored
Add add-script feature (#260)
1 parent 3d77fa2 commit 2a79d75

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
| Feature | Description | Install method | Version |
1212
| ------- | ----------- | -------------- | ------- |
13+
| [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 |
1314
| [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 |
1415
| [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 |
1516
| [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 |

src/add-script/NOTES.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# add-script
2+
3+
## Project
4+
5+
_No upstream project — this is a utility feature._
6+
7+
## Description
8+
9+
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`.
10+
11+
## Installation Method
12+
13+
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`.
14+
15+
## Other Notes
16+
17+
- If both `url` and `script` are provided the feature fails with an error.
18+
- If neither `url` nor `script` is provided, or if `name` is not provided, the feature exits successfully without doing anything.
19+
- The script is **not** executed during the devcontainer build — it is only placed at the target path for later use.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "add-script",
3+
"id": "add-script",
4+
"version": "1.0.0",
5+
"description": "Add a script from a URL or inline text to /usr/local/bin during devcontainer build",
6+
"documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/add-script",
7+
"options": {
8+
"name": {
9+
"type": "string",
10+
"default": "",
11+
"description": "Name for the script placed in /usr/local/bin."
12+
},
13+
"url": {
14+
"type": "string",
15+
"default": "",
16+
"description": "URL of a script to download."
17+
},
18+
"script": {
19+
"type": "string",
20+
"default": "",
21+
"description": "Inline script text to add."
22+
}
23+
}
24+
}

src/add-script/install.sh

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/bin/bash
2+
set -o errexit
3+
set -o pipefail
4+
set -o noclobber
5+
set -o nounset
6+
set -o allexport
7+
readonly name="add-script"
8+
9+
apt_get_update() {
10+
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
11+
echo "Running apt-get update..."
12+
apt-get update -y
13+
fi
14+
}
15+
16+
apt_get_checkinstall() {
17+
if ! dpkg -s "$@" >/dev/null 2>&1; then
18+
apt_get_update
19+
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends --no-install-suggests --option 'Debug::pkgProblemResolver=true' --option 'Debug::pkgAcquire::Worker=1' "$@"
20+
fi
21+
}
22+
23+
apt_get_cleanup() {
24+
apt-get clean
25+
rm -rf /var/lib/apt/lists/*
26+
}
27+
28+
echo_banner() {
29+
local text="$1"
30+
echo -e "\e[1m\e[97m\e[41m$text\e[0m"
31+
}
32+
33+
install() {
34+
if [ -z "${NAME}" ]; then
35+
echo "No script name provided. Nothing to do."
36+
return 0
37+
fi
38+
39+
if [ -n "${URL}" ] && [ -n "${SCRIPT}" ]; then
40+
printf >&2 '=== [ERROR] Both "url" and "script" options are provided. Please provide only one.\n'
41+
exit 1
42+
fi
43+
44+
if [ -z "${URL}" ] && [ -z "${SCRIPT}" ]; then
45+
echo "No script URL or inline script provided. Nothing to do."
46+
return 0
47+
fi
48+
49+
local scriptTargetPath="/usr/local/bin/${NAME}"
50+
51+
if [ -n "${URL}" ]; then
52+
echo "Downloading script from: ${URL}"
53+
if command -v wget >/dev/null 2>&1; then
54+
wget -qO "${scriptTargetPath}" "${URL}"
55+
elif command -v curl >/dev/null 2>&1; then
56+
curl -fsSL -o "${scriptTargetPath}" "${URL}"
57+
else
58+
apt_get_checkinstall curl ca-certificates
59+
apt_get_cleanup
60+
curl -fsSL -o "${scriptTargetPath}" "${URL}"
61+
fi
62+
else
63+
echo "Writing inline script to /usr/local/bin/${NAME}..."
64+
printf '%s' "${SCRIPT}" | tee "${scriptTargetPath}" >/dev/null
65+
fi
66+
67+
chmod 755 "${scriptTargetPath}"
68+
echo "Script added at: ${scriptTargetPath}"
69+
}
70+
71+
echo_banner "devcontainer.community"
72+
echo "Running $name..."
73+
install "$@"
74+
echo "(*) Done!"

test/add-script/test.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
4+
set -e
5+
6+
# Optional: Import test library bundled with the devcontainer CLI
7+
# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib
8+
# Provides the 'check' and 'reportResults' commands.
9+
source dev-container-features-test-lib
10+
11+
# Feature-specific tests
12+
# The 'check' command comes from the dev-container-features-test-lib. Syntax is...
13+
# check <LABEL> <cmd> [args...]
14+
check "bash is available" bash -c "bash --version"
15+
16+
# Report results
17+
# If any of the checks above exited with a non-zero exit code, the test will fail.
18+
reportResults

0 commit comments

Comments
 (0)