A Go project scaffolding tool with template cloning and automatic module rewriting.
  • Go 99.1%
  • Just 0.9%
Find a file
Oliver Andrich 5658518677
test: improve test coverage from 85.8% to 90.0%
Add tests for error paths and edge cases across all packages:
- internal/rewrite: updatePathWithRenames branches, Module/ReadModulePath
  error paths (missing/malformed go.mod, malformed .go), .git skipping
- internal/source: Parse os.Stat branch (relative dir without ./ prefix),
  LocalSource.Fetch with nonexistent path
- cmd/gohatch: run source parse error, getGitAuthor fallback, initGitRepo
  invalid path, fetchTemplate/executeScaffold error forwarding, no-gomod
  with/without force, variables with path renaming
2026-02-28 21:43:55 +01:00
.beans feat: detect and handle unset template variables 2026-02-05 14:32:23 +01:00
.claude chore: add beans and claude code configuration 2025-12-31 17:17:36 +01:00
cmd/gohatch test: improve test coverage from 85.8% to 90.0% 2026-02-28 21:43:55 +01:00
internal test: improve test coverage from 85.8% to 90.0% 2026-02-28 21:43:55 +01:00
.beans.yml chore: add beans and claude code configuration 2025-12-31 17:17:36 +01:00
.gitignore chore: add beans to .gitignore 2026-02-28 21:00:14 +01:00
.golangci.yml chore: update build tooling and remove CI/CD pipeline 2026-01-04 15:52:48 +01:00
.goreleaser.yaml refactor: simplify release workflow 2026-02-01 09:58:20 +01:00
.pre-commit-config.yaml chore: update build tooling and remove CI/CD pipeline 2026-01-04 15:52:48 +01:00
go.mod chore: bump minimum Go version to 1.26 2026-02-28 21:14:41 +01:00
go.sum chore: update all dependencies 2026-02-28 20:51:35 +01:00
justfile feat: use tparse for nicer test output 2026-02-01 10:14:51 +01:00
LICENSE feat: initial implementation of gohatch 2025-12-31 11:19:17 +01:00
README.md docs: add shields.io badges to README 2026-02-01 10:39:26 +01:00

gohatch

Go Version License Codeberg

A project scaffolding tool for Go, inspired by gonew with additional features.

Features

  • Clone templates from GitHub, Codeberg, or any Git host
  • Use local directories as templates
  • Automatic module path rewriting in go.mod and all .go files
  • Template variable substitution (__VarName__Value)
  • Initialize git repository with initial commit (optional)
  • Support for specific tags (@v1.0.0), branches (@main), or commits (@abc1234)
  • Optional string replacement in additional file types

Requirements

  • Go 1.24 or later (for building from source or go install)
  • Git (for cloning remote templates)

Installation

Homebrew (macOS/Linux)

brew tap oliverandrich/tap https://codeberg.org/oliverandrich/homebrew-tap.git
brew install gohatch

Go Install

go install codeberg.org/oliverandrich/gohatch@latest

Binary Downloads

Pre-built binaries for Linux, macOS, and Windows are available on the Releases page.

Build from Source

git clone https://codeberg.org/oliverandrich/gohatch.git
cd gohatch
go build -o gohatch ./cmd/gohatch

To install into your $GOPATH/bin:

go install ./cmd/gohatch

Usage

gohatch [options] <source> <module> [directory]

Arguments

Argument Description
source Template source (see formats below)
module New Go module path
directory Output directory (optional, defaults to last element of module)

Options

Flag Description
-e, --extension Additional file extensions or filenames for module replacement
-v, --var Set template variable (e.g., --var Author="Name")
-f, --force Proceed even if template has no go.mod
--no-git-init Skip git repository initialization
--keep-config Keep .gohatch.toml config file in output
--dry-run Show what would be done without making any changes
--verbose Show detailed progress output

Source Formats

Format Example
GitHub shorthand user/repo
Full URL github.com/user/repo
Other Git hosts codeberg.org/user/repo
Specific tag user/[email protected]
Specific branch user/repo@main
Specific commit user/repo@abc1234
Local directory ./my-template

Note: gohatch automatically detects whether the version is a tag, branch, or commit hash by querying the remote repository.

Examples

Create a new project from a GitHub template:

gohatch user/go-template github.com/me/myapp

Use a specific tag:

gohatch user/[email protected] github.com/me/myapp

Use a specific branch:

gohatch user/go-template@main github.com/me/myapp

Specify output directory:

gohatch user/go-template github.com/me/myapp ./projects/myapp

Also replace module path in config files:

gohatch -e toml -e yaml user/go-template github.com/me/myapp

Replace in specific files (by exact name):

gohatch -e yml -e justfile -e Makefile user/go-template github.com/me/myapp

Use a local template:

gohatch ./my-template github.com/me/myapp

Preview what would be done (dry-run):

gohatch --dry-run user/go-template github.com/me/myapp

Use a non-Go template (skip go.mod validation):

gohatch --force user/non-go-template github.com/me/myapp

Template Variables

Templates can include placeholders that get replaced during scaffolding. Placeholders use dunder-style syntax: __VarName__.

Default Variables

Variable Default Value
ProjectName Output directory name
GitUser Second path element of module (e.g., github.com/user/...user)

Setting Variables

Use the -v or --var flag to set variables:

gohatch --var Author="Oliver Andrich" user/go-template github.com/me/myapp

Multiple variables:

gohatch -v ProjectName=MyApp -v Author="Oliver Andrich" user/go-template github.com/me/myapp

Template Example

In your template files:

package main

const AppName = "__ProjectName__"
const Author = "__Author__"

After scaffolding with --var Author="Oliver":

package main

const AppName = "myapp"
const Author = "Oliver"

Variables are replaced in .go files and any additional extensions or filenames specified with -e.

Each -e pattern is treated as both a potential filename and extension:

  • yml matches files named yml AND files with .yml extension
  • justfile matches files named justfile AND files with .justfile extension

Path Renaming

Variables can also be used in directory and file names:

Template structure:              After scaffolding:
cmd/__ProjectName__/main.go  →   cmd/myapp/main.go
__ProjectName___test.go      →   myapp_test.go

This allows you to create templates where the directory structure adapts to the project name.

Template Configuration

Templates can include a .gohatch.toml configuration file to specify default settings. This eliminates the need to pass -e flags manually when using the template.

Configuration File

Create a .gohatch.toml file in your template root:

# Optional: schema version (defaults to 1)
version = 1

# File extensions/names for module path and variable replacement
extensions = ["toml", "yaml", "justfile", "Makefile"]

Behavior

  • The config file is automatically read after fetching the template
  • Extensions from the config are merged with any -e flags passed on the command line
  • The .gohatch.toml file is automatically removed from the output (use --keep-config to retain it)

Example

Template with .gohatch.toml:

extensions = ["toml", "yaml", "justfile"]

Now users can simply run:

gohatch user/template github.com/me/myapp

Instead of:

gohatch -e toml -e yaml -e justfile user/template github.com/me/myapp

Development

just build        # Build binary to build/gohatch
just test         # Run tests (requires tparse)
just cover        # Run tests with coverage (requires tparse)
just cover-report # Open coverage report in browser
just fmt          # Format code
just lint         # Run linter
just check        # Run fmt, lint, and test
just clean        # Remove build artifacts
just install      # Install to $GOPATH/bin
just release      # Create and publish release (requires git tag)

Install tparse for nicer test output:

go install github.com/mfridman/tparse@latest

License

This project is licensed under the European Union Public License 1.2 (EUPL-1.2).