Skip to content

Commit 5c39e5b

Browse files
authored
Merge pull request #40 from jsburckhardt/feat/add-python-uv
feat(uv): add uv/uvx devcontainer feature
2 parents ebcc0ab + 5503442 commit 5c39e5b

14 files changed

Lines changed: 232 additions & 23 deletions

.devcontainer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"features": {
3535
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
3636
"ghcr.io/stuartleeks/dev-container-features/shell-history:0": {},
37+
"ghcr.io/jsburckhardt/devcontainer-features/gic:1": {}
38+
3739

3840
},
3941
"updateContentCommand": "npm install -g @devcontainers/cli",

.gic.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
llm_instructions: |
2+
You are a commit message generator that follows the semantic release format based on Angular commit guidelines. The user will provide a git diff, and your task is to analyze the changes and generate a SINGLE appropriate git commit message. The message should clearly indicate the type of changes (e.g., feat, fix, chore, docs, style, refactor, test, build, ci, perf, or revert), a brief summary of the change in imperative mood, and optionally include a scope in parentheses. If applicable, include a body with additional details and a footer with references to any related issues or breaking changes.
3+
Commit message can have more than one scope and can be multiline.
4+
5+
Use breaking change only and only if the change is a feature based on code changes.
6+
7+
Example Format between ~~~:
8+
9+
~~~
10+
<type>(<scope>): <short description>
11+
12+
[optional body]
13+
14+
[optional footer(s)]
15+
~~~
16+
17+
return ONLY and ONLY the commit message with no ~~~ and no ```.
18+
19+
If more than one action is performed, use the following order:
20+
feat, fix, chore, docs, refactor, test, build, ci, perf, revert
21+
22+
Example Usage:
23+
24+
Input: git commit diff: ...
25+
Output: A commit message following the format based on the analysis of the diff.
26+
27+
Example Commit Messages:
28+
29+
feat(api): add new endpoint for user authentication
30+
fix(ui): resolve button alignment issue on mobile devices
31+
chore(deps): update dependencies to latest versions
32+
docs(readme): add instructions for setting up the project locally
33+
refactor(auth): simplify token validation logic
34+
test(auth): add unit tests for login functionality
35+
perf(core): improve rendering performance by optimizing the DOM updates
36+
api_version: 2024-02-15-preview
37+
azure_endpoint: https://generic-aoai-01.openai.azure.com/
38+
connection_type: azure
39+
model_deployment_name: gpt-4o
40+
should_commit: true
41+
tokens: 4000

.github/workflows/test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
- cyclonedx
2222
- copa
2323
- gic
24+
- uv
2425
- gitleaks
2526
- jnv
2627
baseImage:

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This repository contains a _collection_ of Features.
1616
| cyclonedx | https://cyclonedx.org/ | cyclonedx is a command-line tool for working with Software Bill of Materials (SBOM). |
1717
| Copacelic | https://project-copacetic.github.io/copacetic/website/ | Project Copacetic: Directly patch container image vulnerabilities. Copa is a CLI tool written in Go and based on buildkit that can be used to directly patch container images given the vulnerability scanning results from popular tools like Trivy. |
1818
| Gic | https://github.com/jsburckhardt/gic | Reducing cognitive load by automating commit message generation, allowing developers to focus on coding instead of crafting messages. |
19+
| UV/UVX | https://docs.astral.sh/uv/ | An extremely fast Python package and project manager, written in Rust. A single tool to replace pip, pip-tools, pipx, poetry, pyenv, virtualenv, and more. |
1920
| Gitleaks | https://gitleaks.io/ | Gitleaks is a SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos. Gitleaks is an easy-to-use, all-in-one solution for detecting secrets, past or present, in your code. |
2021
| Zarf | https://zarf.dev/ | Zarf eliminates the complexity of air gap software delivery for Kubernetes clusters and cloud-native workloads using a declarative packaging strategy to support DevSecOps in offline and semi-connected environments. |
2122
| jnv | https://github.com/ynqa/jnv | jnv is designed for navigating JSON, offering an interactive JSON viewer and jq filter editor. |
@@ -208,3 +209,20 @@ Running `jnv -h` inside the built container will print the help menu of jnv.
208209
```bash
209210
$ jnv -h
210211
```
212+
213+
### `UV/UVX`
214+
215+
Running `uv` or `uvx` inside the built container will print the help menu of gic.
216+
217+
```jsonc
218+
{
219+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
220+
"features": {
221+
"ghcr.io/jsburckhardt/devcontainer-features/uv:1": {}
222+
}
223+
}
224+
```
225+
226+
```bash
227+
$ uv --version
228+
```

src/gic/install.sh

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,39 @@ BINARY_NAME="gic"
88
set -e
99

1010
if [ "$(id -u)" -ne 0 ]; then
11-
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
12-
exit 1
11+
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
12+
exit 1
1313
fi
1414

1515
# Clean up
1616
rm -rf /var/lib/apt/lists/*
1717

1818
check_packages() {
19-
if ! dpkg -s "$@" >/dev/null 2>&1; then
20-
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
21-
echo "Running apt-get update..."
22-
apt-get update -y
23-
fi
24-
apt-get -y install --no-install-recommends "$@"
25-
fi
19+
if ! dpkg -s "$@" >/dev/null 2>&1; then
20+
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
21+
echo "Running apt-get update..."
22+
apt-get update -y
23+
fi
24+
apt-get -y install --no-install-recommends "$@"
25+
fi
2626
}
2727

28-
2928
# make sure we have packages
3029
check_packages curl tar jq ca-certificates
3130

32-
3331
# Function to get the latest version from GitHub API
3432
get_latest_version() {
3533
LATEST_URL="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases/latest"
3634
curl -s "$LATEST_URL" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
3735
}
3836

39-
# Check if a version is passed as an argument
40-
if [ -z "$1" ]; then
41-
# No version provided, get the latest version
37+
# Check if a version is provided via environment variable or passed as an argument
38+
if [ -z "$VERSION" ] || [ "$VERSION" == "latest" ]; then
4239
VERSION=$(get_latest_version)
43-
echo "No version provided, installing the latest version: $VERSION"
40+
echo "No version provided or 'latest' specified, installing the latest version: $VERSION"
4441
else
45-
VERSION=$1
46-
echo "Installing specified version: $VERSION"
42+
# trim the v from the version
43+
echo "Installing version from environment variable: $VERSION"
4744
fi
4845

4946
# Determine the OS and architecture following the naming template

src/kyverno/install.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env bash
2-
32
KYVERNO_VERSION="${VERSION:-"latest"}"
43
GITHUB_API_REPO_URL="https://api.github.com/repos/kyverno/kyverno/releases"
54
URL_RELEASES="https://github.com/kyverno/kyverno/releases"
@@ -73,7 +72,7 @@ echo "Downloading ${KYVERNO_FILENAME}..."
7372

7473
url="${URL_RELEASES}/download/${KYVERNO_VERSION}/${KYVERNO_FILENAME}"
7574
echo "Downloading ${url}..."
76-
curl -sSL $url -o "${KYVERNO_FILENAME}"
75+
curl -sSL "$url" -o "${KYVERNO_FILENAME}"
7776
tar -zxvf "${KYVERNO_FILENAME}" -C /usr/local/bin/ kyverno
7877
rm "${KYVERNO_FILENAME}"
7978

src/uv/devcontainer-feature.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "uv/uvx",
3+
"id": "uv",
4+
"version": "1.0.0",
5+
"description": "A single tool to replace pip, pip-tools, pipx, poetry, pyenv, virtualenv, and more.",
6+
"options": {
7+
"version": {
8+
"type": "string",
9+
"default": "latest",
10+
"description": "Version of UV to install. Accepts versions with 'v' prefix."
11+
}
12+
}
13+
}

src/uv/install.sh

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/bin/bash
2+
3+
# Variables
4+
REPO_OWNER="astral-sh"
5+
REPO_NAME="uv"
6+
BINARY_NAME="uv"
7+
8+
set -e
9+
10+
if [ "$(id -u)" -ne 0 ]; then
11+
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
12+
exit 1
13+
fi
14+
15+
# Clean up
16+
rm -rf /var/lib/apt/lists/*
17+
18+
check_packages() {
19+
if ! dpkg -s "$@" >/dev/null 2>&1; then
20+
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
21+
echo "Running apt-get update..."
22+
apt-get update -y
23+
fi
24+
apt-get -y install --no-install-recommends "$@"
25+
fi
26+
}
27+
28+
# make sure we have packages
29+
check_packages curl tar jq ca-certificates
30+
31+
# Function to get the latest version from GitHub API
32+
get_latest_version() {
33+
LATEST_URL="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases/latest"
34+
curl -s "$LATEST_URL" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
35+
}
36+
37+
# Check if a version is passed as an argument
38+
if [ -z "$VERSION" ] || [ "$VERSION" == "latest" ]; then
39+
# No version provided, get the latest version
40+
VERSION=$(get_latest_version)
41+
echo "No version provided or 'latest' specified, installing the latest version: $VERSION"
42+
else
43+
VERSION=${VERSION#"v"}
44+
echo "Installing version from environment variable: $VERSION"
45+
fi
46+
47+
# Determine the OS and architecture following the naming template
48+
OS=$(uname | tr '[:upper:]' '[:lower:]')
49+
ARCH=$(uname -m)
50+
51+
case "$ARCH" in
52+
x86_64)
53+
ARCH="x86_64"
54+
;;
55+
i686)
56+
ARCH="i686"
57+
;;
58+
armv7l)
59+
ARCH="armv7"
60+
;;
61+
aarch64)
62+
ARCH="aarch64"
63+
;;
64+
powerpc64)
65+
ARCH="powerpc64"
66+
;;
67+
powerpc64le)
68+
ARCH="powerpc64le"
69+
;;
70+
s390x)
71+
ARCH="s390x"
72+
;;
73+
*)
74+
echo "Unsupported architecture: $ARCH"
75+
exit 1
76+
;;
77+
esac
78+
79+
# Construct the download URL to match the naming template
80+
if [[ "$OS" == "darwin" ]]; then
81+
OS="apple-darwin"
82+
elif [[ "$OS" == "linux" ]]; then
83+
OS="unknown-linux-gnu"
84+
else
85+
echo "Unsupported OS: $OS"
86+
exit 1
87+
fi
88+
89+
DOWNLOAD_URL="https://github.com/$REPO_OWNER/$REPO_NAME/releases/download/$VERSION/${REPO_NAME}-${ARCH}-${OS}.tar.gz"
90+
91+
# Create a temporary directory for the download
92+
TMP_DIR=$(mktemp -d)
93+
cd "$TMP_DIR" || exit
94+
95+
# Download the binary tarball
96+
echo "Downloading $BINARY_NAME from $DOWNLOAD_URL"
97+
curl -LO "$DOWNLOAD_URL"
98+
99+
# Extract the tarball
100+
echo "Extracting the tarball"
101+
tar -xzf "${REPO_NAME}-${ARCH}-${OS}.tar.gz"
102+
103+
# Move the binary to /usr/local/bin
104+
echo "Installing $BINARY_NAME"
105+
mv ${REPO_NAME}-${ARCH}-${OS}/* /usr/local/bin/
106+
107+
108+
# Cleanup
109+
cd - || exit
110+
rm -rf "$TMP_DIR"
111+
112+
# Verify installation
113+
echo "Verifying installation"
114+
$BINARY_NAME --version

test/_global/all-tools.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ check "kyverno" kyverno version
1010
check "cyclonedx" cyclonedx --version
1111
check "gitleaks" gitleaks version
1212
check "gic" gic --version
13+
check "uv" uv --version
1314
check "jnv" jnv -V
1415
check "zarf" zarf version
1516

test/_global/kyverno-specific-version.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
set -e
44
source dev-container-features-test-lib
5-
check "kyverno with specific version" /bin/bash -c "kyverno version | grep '1.11.4'"
5+
check "kyverno with specific version" /bin/bash -c "kyverno version | grep '1.12.6'"
66

77
reportResults

0 commit comments

Comments
 (0)