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
- Host: GitHub
- URL: https://github.com/axeforging/yankrun
- Owner: AxeForging
- License: mit
- Created: 2026-01-28T19:21:21.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-05-26T11:44:22.000Z (about 1 month ago)
- Last Synced: 2026-05-26T12:34:34.951Z (about 1 month ago)
- Language: Go
- Size: 5.41 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# YankRun
**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)