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")
FEATURES=("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 @@ -14,6 +14,7 @@ jobs:
matrix:
features:
- amazon-q-cli
- zip
baseImage:
- debian:latest
- ubuntu:latest
Expand All @@ -34,6 +35,7 @@ jobs:
matrix:
features:
- amazon-q-cli
- zip
steps:
- uses: actions/checkout@v4

Expand Down
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,25 @@
This repository contains following features:

- [amazon-q-cli](./src/amazon-q-cli/README.md): Install Amazon Q CLI for AWS development
- [zip](./src/zip/README.md): Installs zip and unzip CLI tools for compression and extraction

## Usage

To use the features from this repository, add the desired features to devcontainer.json.

This example uses amazon-q-cli feature on devcontainer:
These examples show how to use features from this repository in a devcontainer:

```jsonc
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/jajera/features/amazon-q-cli:1": {},
"ghcr.io/jajera/features/zip:1": {}
}
}
```

Or use individual features:

```jsonc
{
Expand All @@ -29,7 +42,15 @@ Similar to the [`devcontainers/features`](https://github.com/devcontainers/featu
├── src
│ ├── amazon-q-cli
│ │ ├── devcontainer-feature.json
│ │ └── install.sh
│ │ ├── install.sh
│ │ └── README.md
│ ├── zip
│ │ ├── devcontainer-feature.json
│ │ ├── install.sh
│ │ └── README.md
├── test
│ ├── amazon-q-cli
│ └── zip
...
```

Expand Down
67 changes: 67 additions & 0 deletions src/zip/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Zip Utility (zip)

Installs zip and unzip CLI tools for compression and extraction.

## Example Usage

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

## Options

This feature has no configurable options.

## Description

This feature installs the `zip` and `unzip` command-line utilities for creating and extracting ZIP archives. The installation is compatible with multiple Linux distributions and package managers including:

- **Debian/Ubuntu**: Uses `apt-get`
- **RHEL/CentOS/Fedora**: Uses `yum`/`dnf`
- **Alpine Linux**: Uses `apk`
- **Arch Linux**: Uses `pacman`
- **openSUSE**: Uses `zypper`

## Features

- ✅ Cross-platform support for major Linux distributions
- ✅ Automatic package manager detection
- ✅ Retry logic for package updates
- ✅ Privilege escalation handling (sudo when needed)
- ✅ Comprehensive error handling
- ✅ Installation verification

## Usage Examples

After installation, you can use the zip utilities:

```bash
# Create a zip archive
zip archive.zip file1.txt file2.txt

# Extract a zip archive
unzip archive.zip

# View zip archive contents
unzip -l archive.zip

# Create zip with compression
zip -9 archive.zip file.txt

# Extract to specific directory
unzip archive.zip -d /target/directory
```

## Verification

The feature automatically verifies successful installation by:

- Checking if `zip` command is available
- Checking if `unzip` command is available
- Running version checks for both utilities

---

_Note, this file was auto-generated from the [devcontainer-feature.json](https://github.com/jajera/features/blob/main/src/zip/devcontainer-feature.json). Add additional notes to a `NOTES.md`._
7 changes: 7 additions & 0 deletions src/zip/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "Zip Utility",
"id": "zip",
"version": "1.0.0",
"description": "Installs zip and unzip CLI tools for compression and extraction.",
"documentationURL": "https://linux.die.net/man/1/zip"
}
119 changes: 119 additions & 0 deletions src/zip/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/bin/sh
set -e

echo "Activating feature 'zip'"

# 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 zip >/dev/null 2>&1 && command -v unzip >/dev/null 2>&1; then
echo "✅ Zip utilities are already installed. Skipping install."
exit 0
fi

echo "Installing required dependencies..."

# Function to run apt-get with appropriate privileges
run_apt() {
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_apt 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 packages based on the OS/package manager
install_zip_packages() {
if command -v apt-get >/dev/null 2>&1; then
# Debian/Ubuntu
echo "📦 Installing zip utilities via apt-get..."
if ! try_apt_update; then
echo "⚠️ Warning: Could not update package lists. Proceeding anyway..."
fi
run_apt apt-get install -y zip unzip
elif command -v yum >/dev/null 2>&1; then
# RHEL/CentOS/Fedora (older)
echo "📦 Installing zip utilities via yum..."
run_apt yum install -y zip unzip
elif command -v dnf >/dev/null 2>&1; then
# Fedora (newer)
echo "📦 Installing zip utilities via dnf..."
run_apt dnf install -y zip unzip
elif command -v apk >/dev/null 2>&1; then
# Alpine Linux
echo "📦 Installing zip utilities via apk..."
run_apt apk add --no-cache zip unzip
elif command -v pacman >/dev/null 2>&1; then
# Arch Linux
echo "📦 Installing zip utilities via pacman..."
run_apt pacman -S --noconfirm zip unzip
elif command -v zypper >/dev/null 2>&1; then
# openSUSE
echo "📦 Installing zip utilities via zypper..."
run_apt zypper install -y zip unzip
else
echo "❌ ERROR: No supported package manager found (apt-get, yum, dnf, apk, pacman, zypper)"
echo "Please install zip and unzip manually"
exit 1
fi
}

# Install zip utilities
if ! command -v zip >/dev/null 2>&1 || ! command -v unzip >/dev/null 2>&1; then
echo "Installing zip and unzip..."
if ! install_zip_packages; then
echo "⚠️ Warning: Could not install zip utilities via package manager. Checking if already available..."
if ! command -v zip >/dev/null 2>&1; then
echo "❌ ERROR: zip is required but not available"
exit 1
fi
if ! command -v unzip >/dev/null 2>&1; then
echo "❌ ERROR: unzip is required but not available"
exit 1
fi
fi
else
echo "✅ zip and unzip are already available"
fi

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

if command -v unzip >/dev/null 2>&1; then
echo "✅ unzip installed successfully."
unzip -v | head -n 1
else
echo "❌ ERROR: 'unzip' command not found in PATH"
exit 1
fi

echo "✅ Zip utilities installation complete!"
22 changes: 22 additions & 0 deletions test/zip/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

set -e

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

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

# Test basic zip functionality
check "zip can create archive" bash -c "echo 'test content' > test.txt && zip test.zip test.txt && ls test.zip"
check "unzip can extract archive" bash -c "rm test.txt && unzip test.zip && cat test.txt | grep 'test content'"
check "zip version" bash -c "zip --version"
check "unzip version" bash -c "unzip -v"

# Clean up
rm -f test.txt test.zip

# Report results
reportResults