Skip to content

Commit 4dd77fc

Browse files
Copilotsebst
andauthored
Add yq feature (#120)
* Initial plan * Add yq feature with install script, feature metadata, test, and CI integration Co-authored-by: sebst <592313+sebst@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sebst <592313+sebst@users.noreply.github.com>
1 parent 4ebdf64 commit 4dd77fc

4 files changed

Lines changed: 158 additions & 0 deletions

File tree

‎.github/workflows/test.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ jobs:
4949
- swc.rs
5050
- tailscale.com
5151
- webinstall.dev
52+
- yq
5253
- zellij.dev
5354
- zyedidia-eget
5455
baseImage:
@@ -105,6 +106,7 @@ jobs:
105106
- swc.rs
106107
- tailscale.com
107108
- webinstall.dev
109+
- yq
108110
- zellij.dev
109111
- zyedidia-eget
110112
steps:

‎src/yq/devcontainer-feature.json‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "yq",
3+
"id": "yq",
4+
"version": "1.0.0",
5+
"description": "Install \"yq\" binary",
6+
"documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/yq",
7+
"options": {
8+
"version": {
9+
"type": "string",
10+
"default": "latest",
11+
"proposals": [
12+
"latest"
13+
],
14+
"description": "Version of \"yq\" to install."
15+
}
16+
}
17+
}

‎src/yq/install.sh‎

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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 githubRepository='mikefarah/yq'
8+
readonly binaryName='yq'
9+
readonly versionArgument='--version'
10+
readonly binaryTargetFolder='/usr/local/bin'
11+
readonly name="${githubRepository##*/}"
12+
apt_get_update() {
13+
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
14+
echo "Running apt-get update..."
15+
apt-get update -y
16+
fi
17+
}
18+
apt_get_checkinstall() {
19+
if ! dpkg -s "$@" >/dev/null 2>&1; then
20+
apt_get_update
21+
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends --no-install-suggests --option 'Debug::pkgProblemResolver=true' --option 'Debug::pkgAcquire::Worker=1' "$@"
22+
fi
23+
}
24+
apt_get_cleanup() {
25+
apt-get clean
26+
rm -rf /var/lib/apt/lists/*
27+
}
28+
curl_check_url() {
29+
local url=$1
30+
local status_code
31+
status_code=$(curl -s -o /dev/null -w '%{http_code}' "$url")
32+
if [ "$status_code" -ne 200 ] && [ "$status_code" -ne 302 ]; then
33+
echo "Failed to download '$url'. Status code: $status_code."
34+
return 1
35+
fi
36+
}
37+
curl_download_stdout() {
38+
local url=$1
39+
curl \
40+
--silent \
41+
--location \
42+
--output '-' \
43+
--connect-timeout 5 \
44+
"$url"
45+
}
46+
debian_get_arch() {
47+
echo "$(dpkg --print-architecture)"
48+
}
49+
debian_get_target_arch() {
50+
case $(debian_get_arch) in
51+
amd64) echo 'amd64' ;;
52+
arm64) echo 'arm64' ;;
53+
armhf) echo 'arm' ;;
54+
i386) echo '386' ;;
55+
*) echo 'unknown' ;;
56+
esac
57+
}
58+
echo_banner() {
59+
local text="$1"
60+
echo -e "\e[1m\e[97m\e[41m$text\e[0m"
61+
}
62+
github_list_releases() {
63+
if [ -z "$1" ]; then
64+
echo "Usage: list_github_releases <owner/repo>"
65+
return 1
66+
fi
67+
local repo="$1"
68+
local url="https://api.github.com/repos/$repo/releases"
69+
curl -s "$url" | grep -Po '"tag_name": "\K.*?(?=")' | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | sed 's/^v//'
70+
}
71+
github_get_latest_release() {
72+
if [ -z "$1" ]; then
73+
echo "Usage: get_latest_github_release <owner/repo>"
74+
return 1
75+
fi
76+
github_list_releases "$1" | head -n 1
77+
}
78+
github_get_tag_for_version() {
79+
if [ -z "$1" ] || [ -z "$2" ]; then
80+
echo "Usage: github_get_tag_for_version <owner/repo> <version>"
81+
return 1
82+
fi
83+
local repo="$1"
84+
local version="$2"
85+
local url="https://api.github.com/repos/$repo/releases"
86+
local escaped_version
87+
escaped_version="$(printf '%s' "$version" | sed 's/\./\\./g')"
88+
curl -s "$url" | grep -Po '"tag_name": "\K.*?(?=")' | grep -E "^v?${escaped_version}$" | head -n 1
89+
}
90+
utils_check_version() {
91+
local version=$1
92+
if ! [[ "${version:-}" =~ ^(latest|[0-9]+\.[0-9]+\.[0-9]+)$ ]]; then
93+
printf >&2 '=== [ERROR] Option "version" (value: "%s") is not "latest" or valid semantic version format "X.Y.Z" !\n' \
94+
"$version"
95+
exit 1
96+
fi
97+
}
98+
install() {
99+
utils_check_version "$VERSION"
100+
apt_get_checkinstall curl ca-certificates
101+
readonly architecture="$(debian_get_target_arch)"
102+
if [ "$VERSION" == 'latest' ] || [ -z "$VERSION" ]; then
103+
VERSION=$(github_get_latest_release "$githubRepository")
104+
fi
105+
readonly version="${VERSION:?}"
106+
readonly releaseTag="$(github_get_tag_for_version "$githubRepository" "$version")"
107+
if [ -z "$releaseTag" ]; then
108+
printf >&2 '=== [ERROR] Could not find release tag for version "%s" in "%s"!\n' "$version" "$githubRepository"
109+
exit 1
110+
fi
111+
readonly downloadUrl="https://github.com/${githubRepository}/releases/download/${releaseTag}/yq_linux_${architecture}"
112+
curl_check_url "$downloadUrl"
113+
readonly binaryTargetPath="${binaryTargetFolder}/${binaryName}"
114+
curl_download_stdout "$downloadUrl" > "$binaryTargetPath"
115+
chmod 755 "$binaryTargetPath"
116+
apt_get_cleanup
117+
}
118+
echo_banner "devcontainer.community"
119+
echo "Installing $name..."
120+
install "$@"
121+
echo "(*) Done!"

‎test/yq/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 "execute command" bash -c "yq --version | grep 'yq'"
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)