Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/scripts/postCreate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euo pipefail
echo "🔧 Installing devcontainer CLI..."
npm install -g @devcontainers/cli

FEATURES=("amazon-q-cli" "zip")
FEATURES=("ag" "amazon-q-cli" "zip")
BASE_IMAGES=("debian:latest" "ubuntu:latest" "mcr.microsoft.com/devcontainers/base:ubuntu")

# Run autogenerated tests for each image
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
strategy:
matrix:
features:
- ag
- amazon-q-cli
- zip
baseImage:
Expand All @@ -34,6 +35,7 @@ jobs:
strategy:
matrix:
features:
- ag
- amazon-q-cli
- zip
steps:
Expand Down
75 changes: 75 additions & 0 deletions src/ag/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# ag - The Silver Searcher (ag)

Installs `ag` (The Silver Searcher), a fast grep-like text search tool.

## Example Usage

```json
"features": {
"ghcr.io/jajera/features/ag:1": {}
}
```

## Options

This feature has no configurable options.

## Description

The Silver Searcher is a code search tool similar to ack, with a focus on speed. It's faster than ack and grep, and respects .gitignore files.

Key features of ag:

- Fast text searching
- Respects .gitignore and .hgignore files
- Searches specific file types
- Supports regular expressions
- Color-coded output
- Multi-threaded for speed

## Supported Platforms

This feature works on:

- Debian/Ubuntu (via `apt-get`)
- RHEL/CentOS/Fedora (via `yum`/`dnf`)
- Alpine Linux (via `apk`)
- Arch Linux (via `pacman`)
- openSUSE (via `zypper`)

## Installation

The feature automatically detects the platform and uses the appropriate package manager to install `ag`.

### Package Names by Platform

- Debian/Ubuntu: `silversearcher-ag`
- RHEL/CentOS/Fedora: `the_silver_searcher`
- Alpine: `the_silver_searcher`
- Arch: `the_silver_searcher`
- openSUSE: `the_silver_searcher`

## Usage Examples

After installation, you can use `ag` to search for text:

```bash
# Search for a string in current directory
ag "search_term"

# Search only in specific file types
ag "search_term" --go

# Search with regular expressions
ag "function\s+\w+" --python

# Show context lines
ag "search_term" -A 3 -B 3
```

## Documentation

For more information about The Silver Searcher, see:

- [Official GitHub Repository](https://github.com/ggreer/the_silver_searcher)
- [ag man page](https://linux.die.net/man/1/ag)
7 changes: 7 additions & 0 deletions src/ag/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "ag - The Silver Searcher",
"id": "ag",
"version": "1.0.0",
"description": "Installs ag (The Silver Searcher), a fast grep-like text search tool.",
"documentationURL": "https://github.com/ggreer/the_silver_searcher"
}
102 changes: 102 additions & 0 deletions src/ag/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/sh
set -e

echo "Activating feature 'ag'"

# Detect OS and architecture
OS="$(uname -s)"
ARCH="$(uname -m)"

echo "✅ Detected OS: $OS"
echo "✅ Detected ARCH: $ARCH"

# Skip install if already present
if command -v ag >/dev/null 2>&1; then
echo "✅ ag (The Silver Searcher) is already installed. Skipping install."
exit 0
fi

echo "Installing ag (The Silver Searcher)..."

# Function to run package managers with appropriate privileges
run_cmd() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
elif command -v sudo >/dev/null 2>&1; then
sudo "$@"
else
echo "⚠️ Warning: Running as non-root user without sudo. Package installation may fail."
"$@"
fi
}

# Retry apt-get update up to 3 times
try_apt_update() {
for i in 1 2 3; do
echo "Running apt-get update (attempt $i)..."
if run_cmd apt-get update -y; then
return 0
fi
echo "apt-get update failed, retrying in 2 seconds..."
sleep 2
done
echo "ERROR: apt-get update failed after multiple attempts."
return 1
}

# Function to install ag based on the OS/package manager
install_ag() {
if command -v apt-get >/dev/null 2>&1; then
# Debian/Ubuntu
echo "📦 Installing ag via apt-get..."
if ! try_apt_update; then
echo "⚠️ Warning: Could not update package lists. Proceeding anyway..."
fi
run_cmd apt-get install -y silversearcher-ag
elif command -v yum >/dev/null 2>&1; then
# RHEL/CentOS/Fedora (older)
echo "📦 Installing ag via yum..."
# Enable EPEL repository for CentOS/RHEL
run_cmd yum install -y epel-release || echo "⚠️ EPEL repository may already be enabled"
run_cmd yum install -y the_silver_searcher
elif command -v dnf >/dev/null 2>&1; then
# Fedora (newer)
echo "📦 Installing ag via dnf..."
run_cmd dnf install -y the_silver_searcher
elif command -v apk >/dev/null 2>&1; then
# Alpine Linux
echo "📦 Installing ag via apk..."
run_cmd apk add --no-cache the_silver_searcher
elif command -v pacman >/dev/null 2>&1; then
# Arch Linux
echo "📦 Installing ag via pacman..."
run_cmd pacman -S --noconfirm the_silver_searcher
elif command -v zypper >/dev/null 2>&1; then
# openSUSE
echo "📦 Installing ag via zypper..."
run_cmd zypper install -y the_silver_searcher
else
echo "❌ ERROR: No supported package manager found (apt-get, yum, dnf, apk, pacman, zypper)"
echo "Please install ag (The Silver Searcher) manually"
exit 1
fi
}

# Install ag
echo "Installing ag (The Silver Searcher)..."
if ! install_ag; then
echo "❌ ERROR: Could not install ag via package manager"
exit 1
fi

# Verify installation
echo "🔍 Verifying installation..."
if command -v ag >/dev/null 2>&1; then
echo "✅ ag installed successfully."
ag --version
else
echo "❌ ERROR: 'ag' command not found in PATH"
exit 1
fi

echo "✅ ag (The Silver Searcher) installation complete!"
37 changes: 37 additions & 0 deletions test/ag/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

set -e

# Import test library bundled with the devcontainer CLI
source dev-container-features-test-lib

# Feature-specific tests
check "ag command exists" bash -c "command -v ag"

# Test basic ag functionality
check "ag version" bash -c "ag --version"

# Create test files for searching
mkdir -p test_dir
echo "hello world" >test_dir/file1.txt
echo "hello universe" >test_dir/file2.txt
echo "goodbye world" >test_dir/file3.txt

# Test basic search functionality
check "ag can search text" bash -c "ag 'hello' test_dir/ | grep -q 'hello'"
check "ag can search with results" bash -c "ag 'world' test_dir/ | wc -l | grep -q '[1-9]'"
check "ag respects case sensitivity" bash -c "ag 'Hello' test_dir/ || true" # Should not find anything
check "ag case insensitive search" bash -c "ag -i 'Hello' test_dir/ | grep -q 'hello'"

# Test ag with regex
check "ag regex search" bash -c "ag 'h[a-z]+o' test_dir/ | grep -q 'hello'"

# Test file type filtering (create a simple text file)
echo "console.log('test');" >test_dir/script.js
check "ag file type search" bash -c "ag 'console' --js test_dir/"

# Clean up
rm -rf test_dir

# Report results
reportResults