corral

command module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2026 License: GPL-3.0 Imports: 1 Imported by: 0

README

Corral logo

Corral

Automatically clone and organise GitHub repositories by visibility and language.

Build Version License


Install

git clone https://github.com/sebastienrousseau/corral.git
cd corral
gh auth login
./corral <owner>

Then verify the output:

ls ~/Code/

Requires gh, git, and Go 1.25+. Works on macOS, Ubuntu/Debian, Fedora/RHEL, Arch, and WSL2.

Platform-specific prerequisites

macOS:

brew install go git gh

Ubuntu / Debian / WSL2:

sudo apt install golang git

Install gh separately — see the GitHub CLI install guide for your distribution.

Fedora / RHEL:

sudo dnf install golang git gh

WSL2 users: Run all commands inside your Linux distribution, not from PowerShell or CMD. The script works identically to native Linux.

Automation and cron

The tool is idempotent and non-interactive. Safe to run on a schedule:

# crontab -e
0 2 * * * /path/to/corral my-username

Existing repositories are skipped. Only new ones are cloned.


Overview

Most cloning tools dump every repository into a single flat directory. Finding anything means scrolling through hundreds of folders with no structure. Corral creates a clean, navigable local mirror — sorted by visibility and language — in one command. No config files.

~/Code/
├── Public/
│   ├── rust/
│   │   └── my-crate/
│   ├── typescript/
│   │   └── my-app/
│   └── other/
│       └── dotfiles/
└── Private/
    └── python/
        └── internal-tool/
  • One command to clone and organise every repository from a user or organisation
  • Safe to re-run at any time — new repos are cloned, and existing ones are pulled to their latest changes (unless --no-sync is passed)
  • Automatic migration from flat ~/Code/<Language>/ layouts to the new visibility-based structure
  • Tested on macOS and Ubuntu with automated tests, 100% coverage, and signed commits.

Architecture

Run once or a hundred times, the directory tree converges on the same state.

graph TD
    A[User Shell] --> B{Corral}
    B --> C[Pre-flight: Git / GitHub API]
    C -- Missing --> Z1[Exit: dependency error]
    C -- OK --> D[GitHub API → Fetch Repos]
    D -- Fails --> Z2[Exit: API error]
    D -- OK --> E[Loop: each repo]
    E --> F{Already cloned?}
    F -- "Yes (default)" --> G1[git pull --rebase --autostash]
    F -- "Yes + --no-sync" --> G2[Skip]
    F -- No --> H{Legacy directory?}
    H -- Yes --> I[Migrate to new layout]
    H -- No --> J[git clone]
    G1 & G2 & I & J --> E
    E -- Done --> K[Remove empty legacy directories]
    K --> L[Print summary]

Features

Structured The only tool that sorts repositories into Public/ and Private/ trees, grouped by primary language
Idempotent Safe to re-run at any time — already-cloned repositories are skipped, only new ones are fetched
Migratory Flat ~/Code/<Language>/ layouts from earlier runs move into the new structure automatically
Platforms First-class support for macOS, Ubuntu/Debian, Fedora/RHEL, Arch, and Windows via WSL2
Zero-config No YAML, no .env, no config files — pass the owner name and run
Fail-safe Pre-flight checks for git and API connectivity with clear error messages on failure
Production-grade 100% test coverage, CI on Ubuntu and macOS, signed commits
Security All commits cryptographically signed (ED25519), CI actions pinned to immutable SHAs, Gitleaks secret scanning

Usage

Parameter Required Default Description
owner Yes GitHub username or organisation
base_dir No $HOME/Code Root directory for the cloned tree
limit No 1000 Maximum repositories to fetch
Option Short Default Description
--dry-run -n off Preview actions without making changes
--help -h Show help message
--protocol -p https Clone protocol — ssh or https
--no-sync off Skip pulling latest changes for already-cloned repos

Clone a personal account:

./corral my-username

Clone an organisation into a custom directory:

./corral my-org ~/Projects 500

Clone via SSH (key-based auth):

./corral --protocol ssh my-username

Skip pulling updates for existing clones:

./corral --no-sync my-username

Preview what would happen without making changes:

./corral --dry-run my-org

Private repositories require a gh token with appropriate access. Public repositories from any account are always available.


What's Included

Organisation and Layout
  • Visibility sorting separates repositories into Public/ and Private/ trees based on GitHub metadata. GitHub Enterprise INTERNAL repositories are securely routed to the Private/ tree.
  • Language grouping places each repository under its primary language directory, normalised to lowercase
  • Special characters are handled cleanly — C# becomes csharp, C++ becomes cpp, spaces and slashes become underscores
  • Null languages default to other/ so every repository has a home
Legacy Migration
  • Flat layouts from earlier versions (~/Code/<Language>/<repo>) are detected and moved into the new <Visibility>/<Language>/<repo> structure
  • Empty directories left behind after migration are removed automatically
  • Existing clones are never overwritten or deleted — the script only adds, never subtracts
Troubleshooting
Message Cause Solution
ERROR: Bash 4+ is required macOS includes Bash 3.2 by default brew install bash
ERROR: Required command 'gh' not found GitHub CLI is not installed See Install above
ERROR: gh repo list failed Not authenticated, or the owner does not exist Run gh auth login and verify the owner name
FAILED: owner/repo Network issue or private repo without token access Check connectivity and verify gh auth status
Script reports 0 repos No repositories visible to the current token Run gh repo list <owner> --limit 5 to verify
\r: command not found (WSL2) Windows line endings in the script Run dos2unix corral.sh or re-clone with git config core.autocrlf input
Frequently Asked Questions
  • Can it back up private repositories? Yes. Any repository visible to the authenticated gh token is cloned. PRIVATE and GitHub Enterprise INTERNAL repositories land in the Private/ tree.
  • Does it work with organisations? Yes. Pass the organisation name as the first argument. Both user accounts and organisations are supported.
  • What happens if a repository is deleted on GitHub? The local clone remains untouched. The script never deletes existing directories.
  • What happens if I have uncommitted changes when it syncs? Your local uncommitted work is kept safe. Git automatically stashes your changes (--autostash), rebases the latest commits from the remote branch, and then reapplies your stash. If there is a direct conflict, the sync is cleanly aborted for that specific repository.
  • Does it work on Windows? Yes, through WSL2. Install a Linux distribution from the Microsoft Store, open its terminal, and run the script there. It behaves identically to native Linux.
  • Does it work on macOS with the default shell? macOS ships with Bash 3.2. Run brew install bash to get Bash 4+, then invoke the script with the Homebrew-installed Bash or add it to your $PATH.
  • Is it safe to run on a schedule? Yes. The script is idempotent — existing repos are skipped, only new ones are cloned. No interactive prompts.
How It Compares
Feature Corral ghorg ghcloneall Gist scripts
Organises by language Yes No No No
Organises by visibility Yes No No No
macOS, Linux, and WSL2 Yes (CI on both) Yes Linux only Varies
Zero install Yes (single bash file) Go binary or Docker Python + pip Copy-paste
Idempotent re-runs Yes Yes Yes No
Concurrent operations Yes Yes Yes No
Legacy layout migration Yes No No No
Test suite 39 tests, CI on 2 OS Yes Limited None
Config required None YAML + env vars CLI flags + rc file Manual edits

For security policy and vulnerability reporting, see SECURITY.md.


THE ARCHITECTSebastien Rousseau THE ENGINEEUXIS ᛫ Enterprise Unified Execution Intelligence System


License

Licensed under the GNU General Public License v3.0.

Back to Top

align="right">Back to Top

-

License

Licensed under the GNU General Public License v3.0.

Back to Top

align="right">Back to Top

Documentation

Overview

Package main is the entry point for the Corral CLI application.

Directories

Path Synopsis
Package cmd provides the command-line interface for the Corral application.
Package cmd provides the command-line interface for the Corral application.
internal
engine
Package engine provides the core concurrency and execution logic for Corral.
Package engine provides the core concurrency and execution logic for Corral.
git
Package git provides helper functions to execute common Git commands by wrapping the system's git binary using os/exec.
Package git provides helper functions to execute common Git commands by wrapping the system's git binary using os/exec.
github
Package github provides functionality to interact with the GitHub API.
Package github provides functionality to interact with the GitHub API.
tui
Package tui provides a Bubble Tea terminal user interface for Corral.
Package tui provides a Bubble Tea terminal user interface for Corral.

Jump to

Keyboard shortcuts

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