Skip to content

Commit 5e3040b

Browse files
authored
Merge pull request #55 from jsburckhardt/copilot/fix-54
feat: Add BAT feature for syntax highlighting and Git integration
2 parents fea59fc + 7e1b64d commit 5e3040b

14 files changed

Lines changed: 211 additions & 72 deletions

.gic.yaml

Lines changed: 0 additions & 41 deletions
This file was deleted.

.github/copilot-instructions.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
## Commit Messages.
1+
# General Instructions
22

3-
We follow conventional commit specification for commit messages. This means that each commit message should start with a type, followed by an optional scope, and then a description. The types we use are:
3+
- Ensure any code you produce is correct.
4+
- for commit messages use conventional commit format, e.g. `feat: add new feature`, `fix: correct a bug`, `docs: update documentation`, etc. https://www.conventionalcommits.org/en/v1.0.0/
45

5-
- **feat**: A new feature
6-
- **fix**: A bug fix
7-
- **docs**: Documentation only changes
8-
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
9-
- **refactor**: A code change that neither fixes a bug nor adds a feature
10-
- **perf**: A code change that improves performance
11-
- **test**: Adding missing or correcting existing tests
12-
- **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
13-
- **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
14-
- **chore**: Other changes that don't modify src or test files
6+
## New Feature Instructions
157

16-
More details in here https://www.conventionalcommits.org/en/v1.0.0/
8+
When creating a new feature, follow these steps:
9+
- Update the README.md to include the new feature in the list of features.
10+
- Each feature should be implemented under src/feature-name. Include a devcontainer-feature.json and install.sh file.
11+
- The install.sh file should install the package from the source repository. Not using a package manager like apt.
12+
- Each feature should have a test under test/feature-name/test.sh
13+
- Each feature should include a global test under test/_global/feature-name-specific-version.sh if a specific version can be installed.
14+
- Update the ../../test/_global/all-tools.sh to validate the new feature is installed.
15+
- Update the ../../test/_global/scenarios.json to include the new feature.
16+
- include the feature in the workflows
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Generate a Git commit message using the Conventional Commits format. Then, include three --trailer fields:
2+
3+
Assistant-model: The name of the AI model (e.g., GPT-4o)
4+
5+
LLM-Contrib: An estimated percentage of contribution from the AI (e.g., 60%)
6+
7+
Prompt: A brief human instruction or goal (e.g., "Refactor for readability")
8+
9+
Format the final output like this:
10+
11+
bash
12+
Copy
13+
Edit
14+
git commit --message "type(scope): concise description" \
15+
--trailer "Assistant-model: GPT-4o" \
16+
--trailer "LLM-Contrib: 60%" \
17+
--trailer "Prompt: <short description of prompt>"
18+
Use an appropriate Conventional Commit type (like feat, fix, refactor, docs, etc.) and optionally include a scope if relevant.

.github/prompts/new-feature.prompt.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

.github/workflows/test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jobs:
2727
- skopeo
2828
- uv
2929
- codex
30+
- bat
3031
baseImage:
3132
- debian:latest
3233
- ubuntu:latest

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This repository contains a _collection_ of Features.
88

99
| Name | URL | Description |
1010
| --- | --- | --- |
11+
| bat | https://github.com/sharkdp/bat | A cat(1) clone with syntax highlighting and Git integration. |
1112
| flux | https://fluxcd.io/flux/installation/ | Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration |
1213
| notation | https://notaryproject.dev/ | Notation is a CLI project to add signatures as standard items in the registry ecosystem, and to build a set of simple tooling for signing and verifying these signatures. This should be viewed as similar security to checking git commit signatures, although the signatures are generic and can be used for additional purposes. Notation is an implementation of the Notary v2 specifications.|
1314
| crane | https://github.com/google/go-containerregistry/blob/main/cmd/crane/README.md | crane is a tool for interacting with remote images and registries.|
@@ -26,6 +27,23 @@ This repository contains a _collection_ of Features.
2627

2728

2829

30+
### `bat`
31+
32+
Running `bat` inside the built container will print the help menu of bat.
33+
34+
```jsonc
35+
{
36+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
37+
"features": {
38+
"ghcr.io/jsburckhardt/devcontainer-features/bat:1": {}
39+
}
40+
}
41+
```
42+
43+
```bash
44+
bat --version
45+
```
46+
2947
### `flux`
3048

3149
Running `flux` inside the built container will print the help menu of flux.

src/bat/devcontainer-feature.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "bat",
3+
"id": "bat",
4+
"version": "1.0.0",
5+
"description": "A cat(1) clone with syntax highlighting and Git integration.",
6+
"options": {
7+
"version": {
8+
"type": "string",
9+
"default": "latest",
10+
"description": "Version of bat to install from GitHub releases e.g. v0.22.0"
11+
}
12+
}
13+
}

src/bat/install.sh

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

test/_global/all-tools.sh

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

33
set -e
44
source dev-container-features-test-lib
5+
check "bat" bat --version
56
check "flux" flux version --client
67
check "notation" notation version
78
check "crane" crane version
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
3+
set -e
4+
source dev-container-features-test-lib
5+
check "bat with specific version" /bin/bash -c "bat --version | grep '0.25.0'"
6+
7+
reportResults

0 commit comments

Comments
 (0)