An open API service indexing awesome lists of open source software.

https://github.com/axeforging/yankrun

Template smarter: clone repos and replace tokens safely with size limits, custom delimiters, and JSON/YAML inputs
https://github.com/axeforging/yankrun

Last synced: 13 days ago
JSON representation

Template smarter: clone repos and replace tokens safely with size limits, custom delimiters, and JSON/YAML inputs

Awesome Lists containing this project

README

          

# YankRun


YankRun


Go Version
OS Support
License


**Template smarter**: Clone repos, replace tokens, or template existing projects — safely, with custom delimiters that won't clash with Helm, Jinja, or any other template language.

## TL;DR

```sh
# Install
curl -L https://github.com/AxeForging/yankrun/releases/latest/download/yankrun-linux-amd64.tar.gz | tar xz
sudo mv yankrun-linux-amd64 /usr/local/bin/yankrun

# Clone a template and replace placeholders
yankrun clone --repo https://github.com/AxeForging/template-tester.git \
--input values.yaml --outputDir ./my-project --verbose

# Or template an existing directory
yankrun template --dir ./my-project --input values.yaml --verbose

# Or use the local web workbench
yankrun serve --dir ./my-project --input values.yaml

# Works alongside Helm/Jinja/Go templates — default [[ ]] won't touch {{ }}
yankrun template --dir ./helm-chart --input values.yaml

# Or pick your own delimiters if [[ ]] conflicts with something
yankrun template --dir ./project --input values.yaml --startDelim "<%" --endDelim "%>"
```

## Features

- **Template values replacement** across a directory tree
- **Git clone** with post-clone templating
- **Custom delimiters** — use `[[` `]]`, `<%` `%>`, or anything that won't collide with your existing templates (Helm `{{ }}`, Jinja `{% %}`, etc.)
- **Safe on real projects** — template a repo that already uses Helm/Go templates without breaking `{{ .Values.x }}`
- **Size-based skipping** (default 3 MB)
- **Verbose reporting** with per-file replacement counts
- **JSON/YAML inputs** and ignore patterns
- **Transformation functions** (`toUpperCase`, `toLowerCase`, `gsub`)
- **Template file processing** (`.tpl` files processed and renamed)
- **Caching** for `generate` - caches GitHub repos and template variables in `~/.yankrun/cache.yaml`
- **Interactive workbench** (`serve`) for local/clone/generate workflows with file trees, evaluated transform previews, saved presets, and JSON import/export
- **Safe terminal workflow** (`tui`) for preview-first directory templating

## Documentation

| Audience | Link |
|----------|------|
| **Users** | [docs/user/README.md](docs/user/README.md) - Installation, usage, examples |
| **Commands** | [COMMANDS.md](COMMANDS.md) - Quick command and flag reference |
| **Examples** | [EXAMPLES.md](EXAMPLES.md) - Copy-paste workflows for common use cases |
| **AI Assistants** | [docs/AI/README.md](docs/AI/README.md) - Architecture, testing, common tasks |
| **Transformations** | [doc/functions.md](doc/functions.md) - Function reference |

---

## Install

Linux/macOS (AMD64)

```sh
curl -L https://github.com/AxeForging/yankrun/releases/latest/download/yankrun-linux-amd64.tar.gz | tar xz
chmod +x yankrun-linux-amd64
sudo mv yankrun-linux-amd64 /usr/local/bin/yankrun
```

Linux/macOS (ARM64 / Apple Silicon)

```sh
# Linux ARM64
curl -L https://github.com/AxeForging/yankrun/releases/latest/download/yankrun-linux-arm64.tar.gz | tar xz
chmod +x yankrun-linux-arm64
sudo mv yankrun-linux-arm64 /usr/local/bin/yankrun

# macOS Apple Silicon
curl -L https://github.com/AxeForging/yankrun/releases/latest/download/yankrun-darwin-arm64.tar.gz | tar xz
chmod +x yankrun-darwin-arm64
sudo mv yankrun-darwin-arm64 /usr/local/bin/yankrun
```

Windows (PowerShell)

```powershell
Invoke-WebRequest -Uri https://github.com/AxeForging/yankrun/releases/latest/download/yankrun-windows-amd64.zip -OutFile yankrun.zip
Expand-Archive -Path yankrun.zip -DestinationPath .
Move-Item -Path yankrun-windows-amd64.exe -Destination yankrun.exe
```

From Source (Go 1.25+)

```sh
go install github.com/AxeForging/yankrun@latest
```

Or build locally:

```sh
git clone https://github.com/AxeForging/yankrun.git
cd yankrun
go build -o yankrun .
sudo mv yankrun /usr/local/bin/
```

---

SSH Key Configuration

For SSH repos (`git@github.com:...`), yankrun auto-detects your SSH key in this order:

1. `~/.ssh/id_ed25519`
2. `~/.ssh/id_ecdsa`
3. `~/.ssh/id_rsa`

If your key has a different name or location, use the `--ssh-key` flag:

```sh
yankrun clone --repo git@github.com:org/repo.git \
--outputDir ./out --ssh-key ~/.ssh/my_custom_key
```

For HTTPS repos, no SSH key is needed.

---

## Quick Start

### 1. Create a values file

```yaml
# values.yaml
variables:
- key: APP_NAME
value: MyAwesomeApp
- key: AUTHOR
value: Jane Developer
- key: VERSION
value: 1.0.0
```

### 2. Clone and template

```sh
yankrun clone \
--repo https://github.com/AxeForging/template-tester.git \
--input values.yaml \
--outputDir ./my-new-project \
--verbose
```

### 3. Result

All `[[APP_NAME]]`, `[[AUTHOR]]`, `[[VERSION]]` placeholders are replaced with your values.

---

## Commands

clone - Clone a repo and replace placeholders

```sh
# Non-interactive with values file
yankrun clone \
--repo https://github.com/AxeForging/template-tester.git \
--input values.yaml \
--outputDir ./my-project \
--verbose

# Interactive mode - prompts for each placeholder
yankrun clone \
--repo git@github.com:AxeForging/template-tester.git \
--outputDir ./my-project \
--prompt --verbose

# With custom delimiters
yankrun clone \
--repo https://github.com/example/repo.git \
--input values.json \
--outputDir ./out \
--startDelim "{{" --endDelim "}}"

# Process .tpl files (README.md.tpl → README.md)
yankrun clone \
--repo https://github.com/example/repo.git \
--input values.yaml \
--outputDir ./out \
--processTemplates
```

**Flags:**

| Flag | Alias | Description | Default |
|------|-------|-------------|---------|
| `--repo` | | Git URL (HTTPS or SSH) | required |
| `--outputDir` | `-o` | Output directory | required |
| `--input` | `-i` | Values file (JSON/YAML) | - |
| `--startDelim` | | Start delimiter | `[[` |
| `--endDelim` | | End delimiter | `]]` |
| `--fileSizeLimit` | | Skip files larger than | `3 mb` |
| `--prompt` | `-p` | Interactive mode | `false` |
| `--processTemplates` | `--pt` | Process `.tpl` files | `false` |
| `--onlyTemplates` | `--ot` | Only process `.tpl` files | `false` |
| `--verbose` | `-v` | Verbose output | `false` |
| `--branch` | `-b` | Branch to clone | default |

template - Template an existing directory

```sh
# Basic usage
yankrun template --dir ./my-project --input values.yaml --verbose

# Interactive mode
yankrun template --dir ./my-project --prompt

# With custom delimiters and size limit
yankrun template \
--dir ./my-project \
--input values.yaml \
--startDelim "{{" --endDelim "}}" \
--fileSizeLimit "10 mb" \
--verbose
```

**Flags:**

| Flag | Alias | Description | Default |
|------|-------|-------------|---------|
| `--dir` | `-d` | Directory to process | required |
| `--input` | `-i` | Values file (JSON/YAML) | - |
| `--startDelim` | | Start delimiter | `[[` |
| `--endDelim` | | End delimiter | `]]` |
| `--fileSizeLimit` | | Skip files larger than | `3 mb` |
| `--prompt` | `-p` | Interactive mode | `false` |
| `--processTemplates` | `--pt` | Process `.tpl` files | `false` |
| `--onlyTemplates` | `--ot` | Only process `.tpl` files | `false` |
| `--verbose` | `-v` | Verbose output | `false` |

generate - Interactive template selection

```sh
# Interactive - choose template from config
yankrun generate --prompt --verbose

# Non-interactive with template filter
yankrun generate --template "go-service" --input values.yaml --outputDir ./new-project

# Dry run uses cache to show placeholders without cloning
yankrun generate --template "go-service" --dryRun

# Force fresh data (skip cache)
yankrun generate --template "go-service" --noCache --outputDir ./new-project
```

Requires templates configured in `~/.yankrun/config.yaml` or GitHub discovery enabled.

The `generate` command caches GitHub-discovered repos and template variables in `~/.yankrun/cache.yaml`. Subsequent dry runs use cached data to avoid re-cloning. Use `--noCache` to bypass.

serve - Local web workbench

```sh
# Serve a local directory at http://127.0.0.1:17817
yankrun serve --dir ./my-project --input values.yaml

# Use a different bind address
yankrun serve --dir ./my-project --addr 127.0.0.1:19090

# Force preview-only mode
yankrun serve --dir ./my-project --input values.yaml --dryRun
```

The workbench supports:

- local scan, preview, and apply using the same replacement logic as `template`
- clone from SSH or HTTPS repositories using the existing cloner/auth behavior
- generate from configured templates and GitHub discovery
- file-level placeholder trees and evaluated transform previews
- local saved presets in IndexedDB, with JSON import/export

**Flags:**

| Flag | Alias | Description | Default |
|------|-------|-------------|---------|
| `--dir` | `-d` | Directory to scan/apply for local mode | - |
| `--input` | `-i` | Values file (JSON/YAML) | - |
| `--addr` | | Web listen address | `127.0.0.1:17817` |
| `--startDelim` | `--sd` | Start delimiter | `[[` |
| `--endDelim` | `--ed` | End delimiter | `]]` |
| `--fileSizeLimit` | `--fl` | Skip files larger than | `3 mb` |
| `--processTemplates` | `--pt` | Process `.tpl` files | `false` |
| `--onlyTemplates` | `--ot` | Only process `.tpl` files | `false` |
| `--dryRun` | `--dr` | Block writes and preview only | `false` |
| `--ignore` | | Glob patterns to skip | - |
| `--verbose` | `-v` | Verbose output | `false` |

tui - Safe terminal workflow

```sh
yankrun tui --dir ./my-project --input values.yaml
yankrun tui --dir ./my-project --dryRun
```

The TUI scans a local directory, prints the discovered placeholders, previews the replacement count, and only writes when not in `--dryRun` mode.

setup - Configure defaults

```sh
# Interactive setup
yankrun setup

# Show current config
yankrun setup --show

# Reset config
yankrun setup --reset
```

Creates/updates `~/.yankrun/config.yaml`.

---

## Values File Format

YAML (recommended)

```yaml
# Optional: directories to skip
ignore_patterns:
- node_modules
- dist
- .git
- vendor

# Required: key-value pairs
variables:
- key: APP_NAME
value: MyApp
- key: PROJECT_NAME
value: my-awesome-project
- key: AUTHOR_NAME
value: Jane Developer
- key: AUTHOR_EMAIL
value: jane@example.com
- key: VERSION
value: "1.0.0"
- key: YEAR
value: "2024"
```

JSON

```json
{
"ignore_patterns": ["node_modules", "dist", ".git"],
"variables": [
{ "key": "APP_NAME", "value": "MyApp" },
{ "key": "PROJECT_NAME", "value": "my-awesome-project" },
{ "key": "AUTHOR_NAME", "value": "Jane Developer" },
{ "key": "AUTHOR_EMAIL", "value": "jane@example.com" },
{ "key": "VERSION", "value": "1.0.0" }
]
}
```

---

## Transformation Functions

Apply transformations to placeholder values using the syntax `[[KEY:function]]`:

| Function | Syntax | Input | Output |
|----------|--------|-------|--------|
| Uppercase | `[[APP:toUpperCase]]` | `my-app` | `MY-APP` |
| Lowercase | `[[APP:toLowerCase]]` | `My-App` | `my-app` |
| Replace | `[[APP:gsub(-,_)]]` | `my-app` | `my_app` |
| Chain | `[[APP:gsub( ,-):toLowerCase]]` | `My App` | `my-app` |

More examples

```
# Template file content
Package: [[PACKAGE_NAME:toLowerCase]]
Constant: [[PACKAGE_NAME:toUpperCase]]
ClassName: [[PACKAGE_NAME:gsub(-,_)]]
URL-safe: [[PROJECT_NAME:gsub( ,-):toLowerCase]]

# With PACKAGE_NAME=My-Package and PROJECT_NAME=My Project
Package: my-package
Constant: MY-PACKAGE
ClassName: My_Package
URL-safe: my-project
```

See [doc/functions.md](doc/functions.md) for full documentation.

---

## Configuration

Full config example (~/.yankrun/config.yaml)

```yaml
# Default delimiters
start_delim: "[["
end_delim: "]]"

# Skip files larger than this
file_size_limit: "3 mb"

# Pre-configured templates for `generate` command
templates:
- name: "Go Microservice"
url: "git@github.com:your-org/go-template.git"
description: "Production-ready Go service template"
default_branch: "main"

- name: "React App"
url: "https://github.com/your-org/react-template.git"
description: "React + TypeScript starter"
default_branch: "main"

# GitHub auto-discovery for templates
github:
user: "your-username" # Your GitHub username
orgs: ["your-org", "another-org"] # Organizations to search
topic: "template" # Filter by topic
prefix: "template-" # Filter by name prefix
include_private: true # Include private repos
token: "ghp_xxxx" # Optional: for private repos
```

---

## Use Cases

Bootstrap a new project from a template

**Problem:** You maintain a template repo with CI, linting, and base code. You want to create a new project with your names filled in, without the template's git history.

**Solution:**

```sh
yankrun generate --prompt --verbose
```

Or non-interactively:

```sh
cat > values.yaml << 'EOF'
variables:
- key: PROJECT_NAME
value: my-new-service
- key: AUTHOR
value: Platform Team
EOF

yankrun clone \
--repo git@github.com:your-org/service-template.git \
--input values.yaml \
--outputDir ./my-new-service \
--verbose
```

**Result:** Fresh project with all placeholders replaced, no template git history.

Batch update config across many files

**Problem:** You need to update company name, version, or email across dozens of files.

**Solution:**

```sh
cat > updates.yaml << 'EOF'
variables:
- key: COMPANY_NAME
value: "New Company Inc"
- key: SUPPORT_EMAIL
value: "support@newcompany.com"
- key: VERSION
value: "2.0.0"
EOF

yankrun template --dir . --input updates.yaml --verbose
```

**Result:** Consistent updates across all files with a detailed report.

CI/CD pipeline templating

**Problem:** You need to stamp out projects in an automated pipeline with no user interaction.

**Solution:**

```sh
# In your CI script
yankrun clone \
--repo "$TEMPLATE_REPO" \
--input /config/values.json \
--outputDir ./output \
--startDelim "{{" --endDelim "}}" \
--processTemplates \
--verbose
```

**Result:** Fully templated project ready for deployment, no prompts.

Process .tpl template files

**Problem:** You have `Dockerfile.tpl`, `config.yaml.tpl` files that should be processed and renamed.

**Solution:**

```sh
yankrun template --dir ./project --input values.yaml --processTemplates --verbose
```

**Result:**
- `Dockerfile.tpl` → `Dockerfile` (with placeholders replaced)
- `config.yaml.tpl` → `config.yaml` (with placeholders replaced)
- Original `.tpl` files are removed

---

## Real-World: Templating Projects That Already Have Templates

Most template tools use `{{ }}` — which breaks if your project already has Helm charts, Go templates, or Jinja files. YankRun solves this with custom delimiters.

**Example:** You have a Helm chart with `{{ .Values.replicaCount }}` and you want to replace your own placeholders without touching Helm's syntax:

```yaml
# values.yaml (Helm file — has {{ }} everywhere)
replicaCount: {{ .Values.replicaCount }} # Helm — untouched
image:
repository: [[DOCKER_REGISTRY]]/[[APP_NAME]] # YankRun — replaced
tag: [[VERSION]] # YankRun — replaced
```

```sh
# Replace only [[ ]] placeholders, Helm {{ }} stays intact
yankrun template --dir ./my-helm-chart --input values.yaml --verbose
```

This works because YankRun defaults to `[[ ]]` delimiters. If your project already uses `[[ ]]`, just pick something else:

```sh
# Use <% %> delimiters instead
yankrun template --dir ./project --input values.yaml \
--startDelim "<%" --endDelim "%>"
```

**More examples of coexistence:**

| Your project uses | YankRun delimiter | Command flag |
|---|---|---|
| Helm / Go (`{{ }}`) | `[[ ]]` (default) | *(none needed)* |
| Jinja (`{% %}`, `{{ }}`) | `[[ ]]` (default) | *(none needed)* |
| Terraform (`${ }`) | `[[ ]]` (default) | *(none needed)* |
| Angular (`{{ }}`) | `[[ ]]` (default) | *(none needed)* |
| Something using `[[ ]]` | `<% %>` | `--startDelim "<%" --endDelim "%>"` |

---

## Exit Codes

| Code | Meaning |
|------|---------|
| `0` | Success |
| `1` | Error (invalid flags, clone failed, etc.) |

---

## License

MIT - see [LICENSE](LICENSE)