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
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
My collection of bash scripts.
My collection of bash scripts.

## Tools

### create-package

A tool to create new package directories with bash script templates.

**Usage:**

```bash
# Using command-line arguments
./create-package "My Tool"

# Using stdin (piped input)
echo "My Tool" | ./create-package
```

**Behavior:**

- Creates a directory with the sanitized package name
- Generates an executable bash script inside the directory with the same name
- The generated script includes a shebang, error handling, and a simple hello message

**Name Sanitization Rules:**

Package names are automatically sanitized:
- Converted to lowercase
- Spaces and underscores are replaced with dashes
- Only `[a-z0-9-]` characters are retained (letters, numbers, dashes)
- Multiple consecutive dashes are collapsed into one
- Leading and trailing dashes are removed

**Examples:**

```bash
# Creates: my-tool/my-tool
./create-package "My Tool"

# Creates: hello-world/hello-world
echo "Hello_World" | ./create-package

# Creates: test123/test123
./create-package "test123"
```

**Error Handling:**

- If the sanitized name is empty (e.g., only special characters), the script exits with an error
- If a directory with that name already exists, the script exits with an error message
87 changes: 87 additions & 0 deletions create-package
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash
set -euo pipefail

# create-package: Create a new package directory with a bash script template
# Usage: ./create-package <package-name>
# echo "<package-name>" | ./create-package

# Color helper functions
red() {
if [[ -t 1 ]]; then
echo -e "\033[31m$*\033[0m" >&2
else
echo "$*" >&2
fi
}

green() {
if [[ -t 1 ]]; then
echo -e "\033[32m$*\033[0m"
else
echo "$*"
fi
}

# Read package name from stdin or CLI args
if [[ $# -gt 0 ]]; then
package_name="$*"
elif [[ ! -t 0 ]]; then
# Reading from pipe
read -r package_name
else
red "Error: Package name required"
echo "Usage: ./create-package <package-name>" >&2
echo " echo \"<package-name>\" | ./create-package" >&2
exit 1
fi

# Sanitize the package name:
# 1. Convert to lowercase
# 2. Replace spaces and underscores with dashes
# 3. Remove any characters that are not [a-z0-9-]
# 4. Collapse multiple consecutive dashes into one
# 5. Remove leading/trailing dashes
sanitized=$(echo "$package_name" | \
tr '[:upper:]' '[:lower:]' | \
tr ' _' '-' | \
sed 's/[^a-z0-9-]//g' | \
sed 's/-\+/-/g' | \
sed 's/^-//;s/-$//')

# Check if sanitized name is empty
if [[ -z "$sanitized" ]]; then
red "Error: Package name '$package_name' results in empty string after sanitization"
echo "Package names must contain at least one alphanumeric character" >&2
exit 1
fi

# Check if directory already exists
if [[ -d "$sanitized" ]]; then
red "Error: Directory '$sanitized' already exists"
exit 1
fi

# Create the package directory (using mkdir without -p to avoid race condition)
if ! mkdir "$sanitized" 2>/dev/null; then
red "Error: Failed to create directory '$sanitized' (may have been created concurrently)"
exit 1
fi

# Create the package script
script_path="$sanitized/$sanitized"
cat > "$script_path" <<EOF
#!/usr/bin/env bash
set -euo pipefail

# $sanitized: Package script
# Generated by create-package

echo "Hello from $sanitized!"
EOF

# Make the script executable
chmod +x "$script_path"

green "✓ Created package '$sanitized'"
echo " Script: $script_path"