Skip to content

Commit 70cb0e4

Browse files
learned to install specify-cli
1 parent 4442146 commit 70cb0e4

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ The `:latest` version annotation is added implicitly if omitted. To pin to a spe
4747
| [`gem`](./src/gem/) | Installs RubyGems using the [gem cli](https://guides.rubygems.org/command-reference/#gem-install).
4848
| [`kf-cli`](./src/kf-cli) | Installs [Kf CLI](https://cloud.google.com/migrate/kf/docs/). Kf offers developers the Cloud Foundry experience while empowering operators to adopt declarative Kubernetes practice.
4949
| [`shellspec-cli`](./src/shellspec-cli) | Installs the [ShellSpec](https://github.com/shellspec/shellspec) BDD unit testing framework CLI.
50+
| [`specify-cli`](./src/specify-cli) | Installs the [GitHub Specify CLI](https://github.com/github/spec-kit) for Spec-Driven Development.
5051

5152
## Contributing
5253

src/specify-cli/NOTES.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## About
2+
3+
This feature installs the [GitHub Specify CLI](https://github.com/github/spec-kit) for Spec-Driven Development. The Specify CLI helps you build high-quality software faster by focusing on product scenarios rather than writing undifferentiated code through a structured, specification-driven development process.
4+
5+
## Learn More
6+
7+
- [GitHub spec-kit Repository](https://github.com/github/spec-kit) - Main project repository
8+
- [Spec-Driven Development Guide](https://github.com/github/spec-kit/blob/main/spec-driven.md) - Complete methodology documentation
9+
- [Video Overview](https://www.youtube.com/watch?v=a9eR1xsfvHg) - Introduction to Spec-Driven Development
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "GitHub Specify CLI",
3+
"id": "specify-cli",
4+
"version": "1.0.0",
5+
"description": "Installs the GitHub Specify CLI for Spec-Driven Development.",
6+
"options": {
7+
"version": {
8+
"type": "string",
9+
"proposals": [
10+
"latest",
11+
"none"
12+
],
13+
"default": "latest",
14+
"description": "Select or enter a Specify CLI version. Use 'latest' for the latest version from the main branch."
15+
}
16+
},
17+
"installsAfter": [
18+
"ghcr.io/devcontainers/features/common-utils",
19+
"ghcr.io/devcontainers/features/python"
20+
]
21+
}

src/specify-cli/install.sh

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env bash
2+
3+
: ${VERSION:="latest"}
4+
5+
USERNAME=${USERNAME:-${_REMOTE_USER:-"automatic"}}
6+
7+
set -e
8+
9+
export TMPDIR=$(mktemp -d /tmp/feature.XXXXXX)
10+
trap "rm -rf $TMPDIR" EXIT
11+
12+
# Clean up
13+
rm -rf /var/lib/apt/lists/*
14+
15+
if [ "$(id -u)" -ne 0 ]; then
16+
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
17+
exit 1
18+
fi
19+
20+
architecture="$(dpkg --print-architecture)"
21+
if [ "${architecture}" != "amd64" ] && [ "${architecture}" != "arm64" ]; then
22+
echo "(!) Architecture $architecture unsupported"
23+
exit 1
24+
fi
25+
26+
# Determine the appropriate non-root user
27+
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
28+
USERNAME=""
29+
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
30+
for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do
31+
if id -u "${CURRENT_USER}" >/dev/null 2>&1; then
32+
USERNAME=${CURRENT_USER}
33+
break
34+
fi
35+
done
36+
if [ "${USERNAME}" = "" ]; then
37+
USERNAME=root
38+
fi
39+
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} >/dev/null 2>&1; then
40+
USERNAME=root
41+
fi
42+
43+
apt_get_update() {
44+
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
45+
echo "Running apt-get update..."
46+
apt-get update -y
47+
fi
48+
}
49+
50+
# Checks if packages are installed and installs them if not
51+
check_packages() {
52+
if ! dpkg -s "$@" >/dev/null 2>&1; then
53+
apt_get_update
54+
apt-get -y install --no-install-recommends "$@"
55+
fi
56+
}
57+
58+
check_git() {
59+
if [ ! -x "$(command -v git)" ]; then
60+
check_packages git
61+
fi
62+
}
63+
64+
export DEBIAN_FRONTEND=noninteractive
65+
66+
### BEGIN install
67+
68+
if [ "${VERSION}" = "none" ]; then
69+
echo "Skipping Specify CLI installation..."
70+
exit 0
71+
fi
72+
73+
# Install prerequisites
74+
# echo "Installing prerequisites..."
75+
# check_packages python3 python3-pip python3-venv ca-certificates curl
76+
# check_git
77+
78+
# Install uv (the modern Python package manager)
79+
echo "Installing uv..."
80+
if [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "" ]; then
81+
# Install uv for the specific user
82+
sudo -u "${USERNAME}" bash -c 'curl -LsSf https://astral.sh/uv/install.sh | sh'
83+
UV_PATH="/home/${USERNAME}/.local/bin/uv"
84+
else
85+
# Install uv for root
86+
curl -LsSf https://astral.sh/uv/install.sh | sh
87+
UV_PATH="$HOME/.local/bin/uv"
88+
fi
89+
90+
# Make uv available system-wide
91+
ln -sf "$UV_PATH" /usr/local/bin/uv
92+
93+
# Install specify-cli
94+
echo "Installing Specify CLI..."
95+
if [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "" ]; then
96+
# Install for the specific user
97+
sudo -u "${USERNAME}" bash -c "
98+
export PATH=\"/home/${USERNAME}/.local/bin:\$PATH\"
99+
if [ \"${VERSION}\" = \"latest\" ]; then
100+
uv tool install specify-cli --from \"git+https://github.com/github/spec-kit.git\"
101+
else
102+
uv tool install specify-cli --from \"git+https://github.com/github/spec-kit.git@${VERSION}\"
103+
fi
104+
"
105+
SPECIFY_PATH="/home/${USERNAME}/.local/bin"
106+
else
107+
# Install for root
108+
if [ "${VERSION}" = "latest" ]; then
109+
uv tool install specify-cli --from "git+https://github.com/github/spec-kit.git"
110+
else
111+
uv tool install specify-cli --from "git+https://github.com/github/spec-kit.git@${VERSION}"
112+
fi
113+
SPECIFY_PATH="$HOME/.local/bin"
114+
fi
115+
116+
# Make specify available system-wide
117+
ln -sf "${SPECIFY_PATH}/specify" /usr/local/bin/specify
118+
119+
### END install
120+
121+
# Clean up
122+
rm -rf /var/lib/apt/lists/*
123+
124+
echo "Specify CLI installation completed!"
125+
echo "You can now use 'specify' command to create spec-driven development projects."

test/specify-cli/test.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
# This test can be run with the following command (from the root of this repo)
4+
# devcontainer features test --features specify-cli --base-image mcr.microsoft.com/devcontainers/base:ubuntu .
5+
6+
set -e
7+
8+
# Import 'check' command
9+
source dev-container-features-test-lib
10+
11+
# Test that specify command is available
12+
check "specify command available" command -v specify
13+
14+
# Test that specify can show help/version
15+
check "specify help" specify --help
16+
17+
# Test that specify check command works
18+
check "specify check" specify check
19+
20+
reportResults

0 commit comments

Comments
 (0)