batch-tool

command module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

Batch Tool

Batch Tool is a command-line utility for running the same workflow across many repositories at once. Make, git, pull request, and shell operations are supported.

It is built for people who routinely work across a repo fleet and want one consistent way to:

  • select repositories by name, SCM label, or locally-configured alias
  • fan out git operations safely
  • open, edit, and merge pull requests across supported providers
  • run make targets or custom commands across a coordinated set of repositories

Why Use It

  • One command surface for multi-repository work
  • Fast repository selection with aliases, labels, and exclusions
  • Interactive TUI output by default, with plain line-by-line output for scripts and CI
  • Shared configuration for repository groups, unwanted labels, and reviewers
  • Support for GitHub and Bitbucket pull request workflows

Install

Choose the lowest-friction option that fits your environment.

Pre-built Binary

Download the archive for your platform from the latest release, unpack it, and place batch-tool somewhere on your PATH.

Go Install

If you already use Go locally, install the latest tagged release with:

go install github.com/ryclarke/batch-tool@latest

This installs the binary into your Go bin directory, typically $GOPATH/bin or ~/go/bin. Make sure that directory is on your PATH.

For local builds, release packaging, and contributor setup, see CONTRIBUTING.md.

Agent Skill

This repository ships an Agent Skill that teaches AI coding agents to install, update, configure, and run Batch Tool. It works with any tool that supports the Agent Skills format, including Claude Code, Cursor, Codex, and Gemini CLI. Install it with the skills CLI:

npx skills add ryclarke/batch-tool

Or copy skills/batch-tool/ into your agent's skills directory.

The skill teaches the agent to treat each Batch Tool command as the git, pull request, make, or shell operation it runs, repeated across the selected repositories. An agent you already let open pull requests or push feature branches recognizes pr new and git push as the same operations. exec and make are judged by the command or recipe they actually run. The repository set is authorized separately: the agent shows you the resolved list, and asks first if it chose the selector itself. Destructive operations such as discards, force pushes, and merges always wait for your approval when they span several repositories. The agent also hands credential setup back to you, and never asks for or stores tokens itself.

Quick Start

1. Create a Config File

Batch Tool looks for batch-tool.yaml in:

  • your user config directory
  • $XDG_CONFIG_HOME when set
  • the directory containing the executable

To use any other file, such as one kept alongside a project, pass it with --config.

Start with this minimal example:

git:
  provider: github
  project: your-org-or-username

repos:
  unwanted-labels:
    - deprecated
    - poc
  aliases:
    app:
      - web-app
      - mobile-app
    platform:
      - api
      - worker
  reviewers:
    api:
      - backend-team

The only field you must set to get started is git.project.

2. Configure Authentication

Repository discovery and pull request operations require a credential. Credentials are resolved per project, so each organization can authenticate with a different account.

The quickest way to get started is to export a token:

export AUTH_TOKEN=your-token

If you use GitHub and already have the GitHub CLI installed and authenticated, that works with no configuration at all. gh is never required, and is only consulted when git.provider is github.

Credential Backends

Set auth.provider to choose how credentials are read. No configuration field ever holds a credential itself: each one names an environment variable, a command, or a gh account to read it from.

Backend Reads the credential from
auto (default) AUTH_TOKEN, then GH_TOKEN/GITHUB_TOKEN, then the gh CLI
env the environment variable named by auth.env
gh gh auth token, optionally for the account named by auth.account
command the standard output of the command in auth.command
none nothing - requests are made unauthenticated
Multiple Organizations

Add an auth.owners entry to give a project its own credential. Each entry overrides only the fields it sets, falling back to the top-level auth settings for the rest.

git:
  provider: github
  project: your-username
  projects:
    - your-work-org

auth:
  provider: auto

  owners:
    your-username:
      provider: gh
      account: your-personal-github-login
    your-work-org:
      provider: gh
      account: your-work-github-login
    partner-org:
      provider: env
      env: PARTNER_ORG_TOKEN
    some-public-org:
      provider: none

To use two GitHub accounts this way, log into both and let auth.account select between them. Batch Tool never changes which account is active.

gh auth login   # repeat for each account
gh auth status  # lists the account names to use for auth.account

The command backend reads a credential from any external tool, such as a password manager. The command is given as a list and is executed directly, never through a shell:

auth:
  provider: command
  command: ["op", "read", "op://Private/GitHub/token"]
Continuous Integration

Inside GitHub Actions the default auto backend picks up the standard GITHUB_TOKEN with no configuration:

- run: batch-tool pr get '~all'
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Environment variables are always preferred over the gh CLI, so CI runs stay deterministic and never spawn a subprocess.

Verifying Your Setup

batch-tool auth status reports which credential each project resolves to. It makes no API requests and never prints a credential. Add -v to include a truncated one-way digest, which is enough to confirm that two projects resolved to different credentials:

$ batch-tool auth status -v
PROJECT        BACKEND   SOURCE                     STATUS          DIGEST
partner-org    env       $PARTNER_ORG_TOKEN         ok              sha256:1b77ca52
public-org     none      unauthenticated            none required   -
your-username  gh        gh (user: personal-login)  ok              sha256:4f2a1c9b
your-work-org  gh        gh (user: work-login)      ok              sha256:8e0d33a1

The command exits non-zero if any project fails to resolve, so it also works as a CI preflight. Note that a resolved credential is known to exist but is not known to be valid or to carry the necessary access.

3. Try a Safe Read-Only Command
batch-tool auth status
batch-tool git status repo1 repo2
batch-tool labels '~app'
batch-tool catalog

Repository Selection

Most commands accept one or more repository selectors.

  • repo1 or project/repo1: select a repository directly
  • '~backend': select all repositories with the SCM label or configured alias
  • '!repo2' or '!~deprecated': exclude repositories from the working set
  • '+repo3' or '+~experimental': force inclusion even if the repo would normally be filtered out
  • .: run the command once against the current working directory only

ℹ️ ~all is always available and expands to every discovered repository in the configured project.

Examples:

batch-tool git status '~app' '!mobile-app'
batch-tool git status '+~experimental' '!~deprecated'
batch-tool pr get .

Quote selectors that contain !, +, or ~ so your shell does not expand them first.

Project Resolution

Repositories are tracked internally as project/name. When you supply an explicit project prefix it is used as given, without consulting the catalog. A bare name is resolved against the catalog, preferring git.project and then each entry of git.projects in the order you configured them. A name that is unknown to the catalog falls back to git.project.

Output trims the git.project prefix, so repositories in your default project display as bare names and everything else stays qualified.

Core Workflows

Git Operations
batch-tool git status '~app'
batch-tool git branch -b feature/new-checkout '~app' '~platform'
batch-tool git diff '~platform'
batch-tool git commit -m "Roll out config update" '~platform'
batch-tool git push '~platform'
batch-tool git update '~all'
Choosing What Gets Committed

By default git commit stages everything, including untracked files. Use -s/--stage to narrow that:

  • all (default): stage every change, including untracked files
  • tracked: stage modifications and deletions to tracked files only, like git commit -a
  • none: commit only what you already staged yourself
batch-tool git commit -s tracked -m "Tweak config" '~platform'

git commit does not push. Pass --push when you want it to, or set git.commit.push to make that the default.

Updating and Stashing

git update stashes local changes and restores them after updating, so it will not throw away work by default. Pass --discard to reset the worktree instead, or set git.update.discard to make that the default. --stash forces the stash behavior back on when the config opts into discarding. Use --pull-strategy to control how diverged history is reconciled (default, ff-only, rebase, or merge).

git branch updates the default branch the same way, then restores your local changes onto the new branch. To branch from a clean worktree, run git update --discard first.

git stash push captures untracked and ignored files by default. Use --scope untracked to leave ignored files such as build artifacts and .env in place, or --scope tracked to stash tracked files only.

Pull Request Operations
batch-tool pr new -t "Add checkout flow" -d "Summary of changes" '~app'
batch-tool pr edit -r alice -R my-org/platform-team '~platform'
batch-tool pr merge -m squash --check '~platform'

PR commands validate that you are not operating from the repository's base branch.

Make and Exec
batch-tool make -t test '~platform'
batch-tool exec -c "go test ./..." '~platform'
batch-tool exec -f ./scripts/deploy.sh -a staging '~app'

⚠️ exec is intentionally explicit and prompts for confirmation before running unless you pass -y. This feature is powerful but dangerous, so use it with caution, especially with destructive commands.

Output Modes

Batch Tool supports two output styles:

  • tui (default): interactive progress display with scrolling and per-repository output
  • native: plain streamed output with no TUI chrome. Each repository gets a ------ name ------ header on stdout, and its output streams under it as it arrives, in repository order. The command line, any ERROR: <repo>: <message> lines, and a closing summary go to stderr. The summary looks like 3 repositories (1 failed) | Elapsed: 4s, followed by Failed: <repos>. Color codes are stripped unless stdout is a terminal. Reliable in scripts, CI pipelines, agents, and any terminal.

When stdout is not a terminal, such as a pipe, a redirect, or CI, Batch Tool uses native automatically. Use --style native to get the same output in an interactive terminal.

The TUI can be cancelled at any time with q, Esc, or Ctrl+C. Cancellation propagates to in-flight subprocesses, not just the screen.

Useful global flags:

  • --config: use a specific config file
  • --style / -o: choose tui or native
  • --print / -p: print accumulated output after the run completes
  • --sync: run repositories one at a time
  • --max-concurrency: control parallelism directly
  • --env / -e: inject environment variables into executed commands

Configuration Notes

Repository Directory

Repositories are cloned beneath git.directory using the provider host, project, and repository name. If you do not set git.directory, Batch Tool defaults to $GOPATH/src when GOPATH is available and otherwise falls back to the current working directory.

Git Command Defaults

Each git subcommand reads its persistent defaults from a matching config group, so you can set the behavior you want once instead of repeating flags. The example below shows every key with its default value.

git:
  remote: origin # remote used by 'git push' and 'git commit --push'

  commit:
    stage: all # "all", "tracked", or "none"
    push: false # push automatically after committing

  update:
    discard: false # discard local changes instead of stashing and restoring them
    pull-strategy: default # "default", "ff-only", "rebase", or "merge"
    clean-ignored: false # also delete ignored files when discarding changes
    submodules: true # re-initialize submodules after discarding changes

  stash:
    scope: all # "all", "untracked", or "tracked"; also used by 'git update' and 'git branch'

  branch:
    reset: true # reset branches that already exist instead of failing
Aliases and Unwanted Labels

Use repos.aliases to define local groupings that behave like labels. Alias members may be given as bare or project/name values, in any mix; each is resolved through the catalog when the alias is loaded. Use repos.unwanted-labels together with repos.skip-unwanted to keep deprecated or experimental repositories out of broad operations unless you explicitly force them in.

Default Reviewers

Use repos.reviewers or repos.team_reviewers to preconfigure the reviewers you usually request for a given repository or label. Repository keys may be either bare or project/name, and label keys use the ~label form.

Troubleshooting

  • Authentication errors: run batch-tool auth status to see which credential each project resolves to
  • Repository not found: confirm the repository name, default project, and cached catalog data
  • Unexpected matches: run batch-tool labels <selectors...> to inspect how your filters resolve
  • Interactive hangs in automation: use --style native, or --print to keep the TUI and print its output when it exits
  • Long-running commands: reduce concurrency with --sync or --max-concurrency limits

For command-specific help, run:

batch-tool [command] --help

If you are contributing to the project itself, see CONTRIBUTING.md.

🤖 AI Use Disclosure

This project uses AI assistance in a supervised, human-in-the-loop workflow.

AI assistance has been used most heavily for:

  • documentation drafting and style iteration
  • early TUI output scaffolding and presentation experiments
  • expanding unit test cases and coverage scenarios

AI is not the source of truth for behavior, correctness, or project structure. The maintainer is responsible for final design choices, code review, and acceptance.

This is not a prompt-driven "vibe-coded" project. Changes are expected to pass normal engineering controls and quality expectations, and any prompt-based contributions are carefully vetted.

Users should expect intentionally reviewed software, not unattended AI output.

Documentation

Overview

Package main is the entry point for the batch-tool application.

It simply executes the root command defined in the cmd package, which handles all command-line parsing and execution logic.

Directories

Path Synopsis
Package auth resolves SCM credentials per repository owner through pluggable backends, allowing separate accounts for each configured project.
Package auth resolves SCM credentials per repository owner through pluggable backends, allowing separate accounts for each configured project.
Package call provides batching primitives for executing repository-scoped work concurrently with shared cancellation and output semantics.
Package call provides batching primitives for executing repository-scoped work concurrently with shared cancellation and output semantics.
Package catalog provides repository discovery, selector expansion, and cache-backed metadata for batch-tool command workflows.
Package catalog provides repository discovery, selector expansion, and cache-backed metadata for batch-tool command workflows.
cmd
Package cmd provides the top-level Cobra command tree, global flags, and command execution entry points for batch-tool.
Package cmd provides the top-level Cobra command tree, global flags, and command execution entry points for batch-tool.
exec
Package exec provides the command implementation for running shell commands or executable files across selected repositories.
Package exec provides the command implementation for running shell commands or executable files across selected repositories.
git
Package git provides git-focused subcommands for branch, status, commit, push, diff, stash, and update operations across repository batches.
Package git provides git-focused subcommands for branch, status, commit, push, diff, stash, and update operations across repository batches.
make
Package make provides command handlers for executing one or more make targets across a selected set of repositories.
Package make provides command handlers for executing one or more make targets across a selected set of repositories.
pr
Package pr provides pull-request lifecycle commands such as create, edit, get, and merge across repository batches.
Package pr provides pull-request lifecycle commands such as create, edit, get, and merge across repository batches.
Package config provides configuration defaults, key constants, context-scoped viper configuration access, and environment-specific setup for the CLI.
Package config provides configuration defaults, key constants, context-scoped viper configuration access, and environment-specific setup for the CLI.
Package output provides rendering and channel abstractions used to stream batched execution results to either interactive TUI or native console output.
Package output provides rendering and channel abstractions used to stream batched execution results to either interactive TUI or native console output.
scm
Package scm provides provider-neutral contracts, model types, and validation helpers for repository and pull-request operations.
Package scm provides provider-neutral contracts, model types, and validation helpers for repository and pull-request operations.
bitbucket
Package bitbucket implements the scm.Provider contract against Bitbucket APIs.
Package bitbucket implements the scm.Provider contract against Bitbucket APIs.
fake
Package fake provides an in-memory scm.Provider implementation for tests and local examples.
Package fake provides an in-memory scm.Provider implementation for tests and local examples.
github
Package github implements the scm.Provider contract for GitHub repositories and pull-request workflows.
Package github implements the scm.Provider contract for GitHub repositories and pull-request workflows.
Package utils provides shared helper functions used across packages for command construction, selector normalization, and small cross-cutting operations.
Package utils provides shared helper functions used across packages for command construction, selector normalization, and small cross-cutting operations.
testing
Package testing provides shared test utilities used by multiple package test suites in this repository.
Package testing provides shared test utilities used by multiple package test suites in this repository.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL