cmd

package
v0.0.0-...-03c0f2a Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 80 Imported by: 0

Documentation

Overview

Commands `gitmap add ignore` and `gitmap add attributes`.

Both share a near-identical pipeline:

  1. Validate we are inside a Git working tree.
  2. Resolve `common.<ext>` plus each language argument from the templates package (overlay > embed).
  3. Concatenate bodies with a single dedupe pass keyed on the trimmed line — comments included, blank lines preserved.
  4. Hand the merged body to templates.Merge under a marker block tagged "<kind>/<concatenated-langs>" so re-runs are byte-stable.

The two entry points (`runAddIgnore`, `runAddAttributes`) parameterize only the kind / extension / target file / marker tag prefix and reuse the shared `addTemplateOp` body. This keeps each entry point under the 15-line cap and avoids two diverging copies of the merge dance.

Command `gitmap add lfs-install`.

Two-step operation:

  1. Run `git lfs install --local` so the current repo has the LFS pre-push / clean / smudge hooks wired up. This is itself idempotent — Git LFS treats repeat invocations as no-ops.
  2. Resolve the `lfs/common` template (overlay > embed) and merge its body into ./.gitattributes via templates.Merge, which uses a gitmap-managed marker block so the second and later runs are byte-stable no-ops when the template hasn't changed.

Why a separate command from `gitmap lfs-common`? `lfs-common` shells out to `git lfs track` per-pattern and writes whatever line format `git lfs` decides on. `add lfs-install` is the template-driven path: the bytes written to .gitattributes come from the curated, versioned `lfs/common.gitattributes` asset (audit-trailed `# source:` header) and can be overridden by a user file at ~/.gitmap/templates/lfs/common.gitattributes.

Package cmd — amend.go handles flag parsing and orchestration for the amend command.

Package cmd — amendaudit.go handles audit JSON writing and DB persistence.

Package cmd — amendexec.go handles git operations for the amend command.

Package cmd — amendexecprint.go handles output and display for amend operations.

Package cmd — amendlist.go handles the amend-list command.

Package cmd: audit-legacy scans the workspace for forbidden legacy strings (default: gitmap-v16 / gitmap-v16 / gitmap-v16) and exits 1 on // gitmap-legacy-ref-allow any hit. Designed as a regression guard for remixes / rename commits.

Package cmd: unified-diff rendering for audit-legacy --diffs.

Pure-Go: reads the source file once, rewrites every regex match to DefaultAuditLegacyReplace, and emits one single-line hunk per changed line in standard `diff --unified=0` format.

Package cmd: per-file unified-diff writer for `gitmap audit-legacy`.

When --diffs is set alongside --report, every file with at least one match gets its own `<reportDir>/diffs/<sanitized-path>.diff` artifact containing a minimal unified diff that previews the legacy → v8 substitution. The Markdown report links each diff so a reviewer can click straight from the file-counts table to the proposed change.

Package cmd: emit + report helpers for `gitmap audit-legacy`.

Package cmd: flag parsing for `gitmap audit-legacy`.

Package cmd: Markdown report writer for `gitmap audit-legacy`.

Splits per-pattern + per-file counts and the full hit list into a human-readable Markdown file. Used so CI / contributors can attach a single artifact to a PR or share an audit summary without piping JSON through a formatter.

Package cmd — `gitmap branch <subcommand>` dispatcher.

Package cmd implements the CLI commands for gitmap.

Package cmd — clonefixrepo.go: entry points for `gitmap clone-fix-repo` (alias `cfr`) and `gitmap clone-fix-repo-pub` (alias `cfrp`).

These are convenience pipelines that chain three existing commands in one shot:

cfr  : clone <url>  →  cd <folder>  →  fix-repo --all
cfrp : clone <url>  →  cd <folder>  →  fix-repo --all  →  make-public --yes

Implementation strategy: the chained commands (runFixRepo, runMakePublic) all call os.Exit at the end, which would terminate our parent process before the next step runs. To stay decoupled and side-effect-clean, we shell out to our own binary (resolved via os.Executable) for the fix-repo and make-public steps after invoking executeDirectClone in-process. This also keeps each step's exit code, stdout, and stderr semantics intact.

Package cmd — clonenextcrossdir.go implements the cross-dir `gitmap cn <repo> <version>` form: chdir into the named repo, run the existing clone-next pipeline, then chdir back.

Backward compatibility: `gitmap cn vX.Y.Z` (single positional) keeps operating on the current directory's repo as before.

Package cmd — clonenextfolderdispatch.go implements the v3.117.0 folder-arg forms of `gitmap cn`:

gitmap cn vX <folder>     — explicit version, explicit folder
gitmap cn v+1 <folder>    — version-bump shortcut
gitmap cn <folder>        — folder only (defaults to v++)

All three chdir into the resolved folder, run the existing in-place `runCloneNext` pipeline, then chdir back via the shared `performCrossDirCloneNext` helper in clonenextcrossdir.go.

Disambiguation rules and the full test matrix are documented in spec/01-app/111-cn-folder-arg.md. The two interceptor functions here run BEFORE tryCrossDirCloneNext in runCloneNext so the path-shaped tokens win over the release-alias fallback (the alias resolver matches bare names like "gitmap" which would otherwise shadow a same-named local folder).

Package cmd — clonepmsync.go: shared helper that pushes freshly cloned repos into the alefragnani.project-manager projects.json file. Wired into every clone variant (clone, clone-next, clone-from, clone-now, clone-pick, clone-multi, cfr/cfrp) so that any command that lands a new repo on disk also makes it visible in the VS Code Project Manager sidebar without a separate `gitmap code` step.

Soft-fail policy: when the user-data root or extension dir is missing (CI / headless / no VS Code installed) the helper logs a one-line note via reportVSCodePMSoftError and returns without error. A failed sync NEVER turns a successful clone into a failed exit code.

Spec: spec/01-vscode-project-manager-sync/02-clone-sync.md Memory: mem://features/clone-vscode-pm-sync

Package cmd implements the CLI commands for gitmap.

Package cmd — `gitmap downloader-config [path]` (shorthand: `dc`).

Slice 1 of the downloader feature. Reads / validates / persists the downloader Seedable-Config. Two modes:

  1. Path supplied → load JSON from disk, validate, save to Setting DB.
  2. No path → interactive prompt, pre-populated from current DB values (or downloaderconfig.Defaults() if none).

All actual download / install logic ships in Slice 2 (aria2c installer + engine) and Slice 3 (download / download-unzip commands). This command exists so users can pre-tune the config before those slices land.

Package cmd — haschange.go implements `gitmap has-change (hc) <repo>`.

Prints "true" or "false" depending on whether the named repo has uncommitted changes (default), is ahead of origin, or is behind origin. Use --mode to switch dimensions; --all prints structured output covering all three.

Examples:

gitmap hc gitmap                  -> true | false   (dirty working tree)
gitmap hc gitmap --mode=ahead     -> true | false   (local commits not pushed)
gitmap hc gitmap --mode=behind    -> true | false   (remote commits not pulled)
gitmap hc gitmap --all            -> dirty=true ahead=false behind=true

Package cmd — inject.go implements `gitmap inject` (`inj`).

Purpose: take an existing on-disk folder and "inject" it into the user's tooling — register with GitHub Desktop, open in VS Code, and (when a `git remote get-url origin` succeeds) upsert into the gitmap SQLite database so it shows up in `cd`, `list`, etc.

Forms:

gitmap inject              # operate on cwd
gitmap inject <folder>     # operate on the given folder
gitmap inj   ...           # short alias

`<folder>` accepts absolute, relative, or `~`-prefixed paths. Reuses `resolveCloneNextFolder` from clonenextfolderdispatch.go for path resolution + dir validation, so error messages stay consistent with `cn <folder>`.

Per the user's spec answer: any folder is accepted (no `.git/` required) — Desktop will silently skip non-repos and VS Code is happy to open anything. The DB upsert is conditional: if the folder has no `origin` remote, we skip the database write but still do Desktop + VS Code, so local-only sandboxes can still be injected into the editor without polluting the repo index.

Package cmd — installlist.go renders `gitmap install --list` grouped by category with a per-tool installed-status indicator.

Package cmd — latest-branch command handler.

Package cmd — latest-branch CSV formatter.

Split out from latestbranchoutput.go to keep that file under the 200-line code-style budget. CRLF line endings are forced on every row (header + data) so output is byte-identical across platforms (RFC 4180); pinned by gitmap/cmd/csvcrlf_contract_test.go.

Package cmd — latest-branch output formatters.

Package cmd — latest-branch resolve helpers.

Package cmd — `gitmap lb --switch` checkout post-step.

Package cmd — llmdocs.go generates a consolidated LLM.md reference file.

Package cmd — llmdocscommands.go writes the command reference tables.

Package cmd — llmdocsgroups.go defines command groups for LLM doc generation.

Package cmd — llmdocsheader.go writes the header and architecture sections.

Package cmd — llmdocssections.go writes the remaining LLM.md sections.

Package cmd — migrate.go handles automatic migration of legacy directories.

Package cmd — `gitmap pending clear` removes orphaned or illegal pending tasks so the next clone run is not blocked by a leftover entry from an earlier crash.

Modes (see helptext/pending-clear.md for the full contract):

orphans  — TargetPath is missing on disk
illegal  — TargetPath looks like a URL or contains illegal Windows
           path characters (`:` after drive letter, `?`, `*`, etc.)
all      — every pending task
<id>     — a single task by numeric ID

Default mode is `orphans` because it's the safest auto-cleanup. Confirmation is required unless --yes is passed; --dry-run previews without touching the DB.

Package cmd — projectrepos.go handles project type query commands.

Package cmd — projectreposoutput.go formats project query output.

Package cmd implements the CLI commands for gitmap.

Package cmd implements the CLI commands for gitmap.

Package cmd implements the CLI commands for gitmap.

Package cmd — releaserebase.go implements the cross-dir `gitmap r <repo> <version>` form: pull --rebase the named repo, then run the standard release pipeline, then chdir back to the original directory.

Backward compatibility: `gitmap r vX.Y.Z` (single positional arg) keeps running an in-place release of the current repo. The new behavior only triggers when TWO positional args are given AND the first does NOT look like a version string (e.g. v3.31.0, 3.31.0).

Package cmd implements the CLI commands for gitmap.

Package cmd — scanbenchmark.go captures per-phase scan timings and writes them to a benchmark log so users can diagnose slow scans without us having to ask. Each scan invocation appends a fresh, timestamped block to .gitmap/output/scan-benchmark.log alongside the binary version.

Why a file (not just stdout): users routinely report "scan is slow" with no reproducible numbers. The log gives them — and us — a record of exactly which phase ate the wall clock, across every run.

Package cmd — scanprojectoutput.go writes project-specific JSON files.

Package cmd — scanprojects.go handles project detection during scan.

Package cmd — scanprojectsmeta.go handles Go and C# metadata persistence.

Package cmd — seowrite.go handles flag parsing and orchestration for seo-write.

Package cmd — seowritecreate.go scaffolds a sample seo-templates.json.

Package cmd — seowritecsv.go handles CSV parsing for seo-write.

Package cmd — seowriteloop.go handles the commit loop, rotation, and timing.

Package cmd — seowritetemplate.go handles template loading and placeholder substitution.

Package cmd — sshexisting.go handles the case where an SSH key already exists on disk when `gitmap ssh` is invoked. Instead of forwarding the stdin "Overwrite (y/n)?" prompt to `ssh-keygen` (which fails non-interactively and confuses users), we detect the existing key UP FRONT, print the public key + fingerprint, and exit cleanly. Pass `--force` to regenerate.

Command `gitmap templates init <lang> [<lang>...] [--lfs] [--dry-run] [--force]`.

Scaffolds .gitignore and .gitattributes for one or more languages by resolving the corresponding embedded (or user-overlay) templates and merging them into the target files via templates.Merge — the same idempotent marker-block primitive that powers `add lfs-install`.

Behavior summary:

  • For each <lang>, ignore/<lang>.gitignore is REQUIRED. Missing → hard error (exit 1) with a one-liner pointing at `templates list`.
  • attributes/<lang>.gitattributes is OPTIONAL. Missing → soft skip with a dim "no attributes template for <lang>" notice. This matches the embed corpus (every lang has ignore, only some have attributes).
  • --lfs additionally merges lfs/common.gitattributes into .gitattributes. Reuses templates.Merge with tag "lfs/common" so the block is interchangeable with `gitmap add lfs-install`.
  • --dry-run prints every block that WOULD be written and exits without touching disk. Outcome verbs reflect what would happen (created / would update / would insert).
  • --force replaces any pre-existing target file outright with a fresh gitmap-managed block, discarding hand edits OUTSIDE the markers. Without --force, Merge preserves non-marker content and either updates the existing block in place or appends one — see merge.go.

Operates from CWD. Does NOT require being inside a git repo (scaffolding before `git init` is a legitimate workflow). The --lfs path also does NOT shell out to `git lfs install` — that's `add lfs-install`'s job. `templates init --lfs` is purely a template-merge operation.

Package cmd implements CLI command handlers for gitmap.

Package cmd implements CLI command handlers for gitmap.

Package cmd — `gitmap unzip-compact` (alias `uzc`).

Resolves an input source (local archive, HTTP(S) URL, or auto-detect a single archive in the current folder) and runs the compact-extract algorithm into either the user-supplied destination folder or the current working directory.

Listing mode (--list / -l) skips extraction and prints the archive's entry table to stderr.

Package cmd — extra cleanup passes for update-cleanup.

These complement the pattern-based pass in updatecleanup_remove.go by targeting two artifact classes that don't fit the simple-glob model:

  1. The obsolete v2.90.0 drive-root forwarding shim (e.g. E:\gitmap.exe sitting at the literal drive root, NOT inside a gitmap\ subfolder).
  2. *.gitmap-tmp-* swap directories left by interrupted clones.

Both passes follow the spec/04-generic-cli/22-data-folder-deploy-and-cleanup.md contract (DFD-6, DFD-7).

Package cmd — `--debug-windows` diagnostics for the self-update Phase 3 cleanup handoff.

The flag is opt-in and prints a structured dump to os.Stderr on every relevant lifecycle event. It propagates across the handoff boundary via two channels:

  1. Argv — `--debug-windows` is forwarded into the handoff copy (Phase 2) and the detached cleanup child (Phase 3).
  2. Env — `GITMAP_DEBUG_WINDOWS=1` is set on the cleanup child so even processes spawned without an inherited argv (e.g. future re-execs) keep printing the dump.

Either signal alone activates the dump; users can flip the env var manually to enable the dump on a single run without rebuilding.

The dump is intentionally cross-platform (works on Unix too) so the same flag can debug Linux/macOS handoffs, even though the original motivation was the Windows update-cleanup loop tracked in Issue #10.

Package cmd — JSON sink for `--debug-windows` diagnostics.

In addition to the human-readable `[debug-windows]` lines printed to stderr, every dump helper also emits a structured NDJSON event to a timestamped file under the project's output directory:

output/gitmap-debug-windows-YYYY-MM-DD_HH-MM-SS.jsonl

One event per line — easy to `jq`/`grep`, easy to ship to a log aggregator, and (crucially) survives even when stdout/stderr are swallowed by a detached Windows launcher.

Activation:

  1. `--debug-windows-json` flag (boolean, defaults the path)
  2. `--debug-windows-json=<path>` to override the file path
  3. `GITMAP_DEBUG_WINDOWS_JSON=<path>` env var (also auto-forwarded to the Phase 3 cleanup child so its events append to the same file as the parent, giving one consolidated trace per handoff)

The sink is OFF by default — `--debug-windows` alone keeps the console-only behavior from v3.86. You opt-in to the file sink because writing under the project tree has user-visible side effects.

Failure policy: file open / write errors are swallowed and degrade to console-only. Diagnostics must NEVER block or fail the update.

Package cmd — extended `--debug-windows` output that prints the exact commands and filesystem operations the update-cleanup handoff will perform, so the user can audit and reproduce them.

Two functions are exported within the package:

dumpDebugWindowsCommandPlan — renders the Phase 3 spawn command
line as a copy-pastable shell invocation (proper quoting), and
prints an explicit note that no `git` subprocess is launched.

dumpDebugWindowsCleanupPlan — enumerates the filepath.Glob
patterns the deployed binary will scan and the actual file
matches that will be passed to os.Remove / os.RemoveAll. Called
from runUpdateCleanup BEFORE any deletion happens so the output
reflects intent, not outcome.

These complement the structured-event log written by updatehandofflog.go (which is post-hoc) with a pre-flight view.

Package cmd — Phase 3 of the self-update handoff chain.

Phase 1 (update.go): active gitmap.exe → handoff copy (gitmap-update-<pid>.exe) Phase 2 (update.go): handoff copy runs build/deploy via run.ps1 Phase 3 (this file): handoff copy spawns the freshly-deployed gitmap.exe

(a different file with no lock) detached, with a small delay, to
run `update-cleanup`. Only the deployed binary can safely remove
the still-locked handoff copy and the just-renamed *.exe.old.

See spec/08-generic-update/06-cleanup.md and spec/03-general/02f-self-update-orchestration.md for the full sequence.

Package cmd — durable on-disk handoff log for the self-update Phase 3 cleanup chain.

The verbose logger (verbose.Get) only writes when --verbose is on, and stdout/stderr from a detached Windows cleanup child can be swallowed by intermediate launchers (run.ps1 wrappers, hidden process attrs, etc.). To make these failures forensically recoverable, every Phase 3 lifecycle event also goes to a small, always-on log file under the same temp directory used for the handoff copy and update script:

<TMP>/gitmap-update-handoff-YYYYMMDD.log

The file is opened in append mode (O_APPEND|O_CREATE|O_WRONLY) with line-oriented entries:

2026-04-24T12:34:56Z pid=12345 ppid=12000 phase=phase-3 event=resolve source=config target=C:\bin\gitmap.exe

We never rotate — daily filename is enough to keep the file bounded for the typical update cadence. If the file cannot be opened (read-only volume, etc.) writes degrade silently; this logger must NEVER block or fail the update flow.

Package cmd — visibility.go: entry points for `gitmap make-public` and `gitmap make-private`.

These commands toggle the current repository's visibility on the remote provider (GitHub or GitLab). They wrap the host CLI (`gh` or `glab`) so we don't have to ship OAuth tokens — if the CLI is authenticated, so are we.

Spec parity: spec-authoring/23-visibility-change/01-spec.md.

Forms:

gitmap make-public  [--yes] [--dry-run] [--verbose]
gitmap make-private        [--dry-run] [--verbose]

`--yes` is a no-op for `make-private` (no confirmation is shown when going public → private; the asymmetry matches the PowerShell reference and is intentional — exposing a private repo is the risky direction, hiding a public one is reversible).

Package cmd — visibilityapply.go: read / write / verify visibility via the host provider's CLI (`gh repo view --json visibility` and `gh repo edit --visibility ...`; analogous `glab` commands).

We deliberately shell out instead of speaking the REST API directly — it lets users authenticate once via their normal `gh auth login` / `glab auth login` flow and keeps gitmap free of token storage.

Package cmd — visibilityresolve.go: provider/slug detection, CLI-availability checks, and the interactive confirm prompt.

Kept separate from visibility.go so each file stays well under the 200-line limit and helpers can be unit-tested in isolation without dragging in the flag-parsing surface.

Package cmd — vscodecustomtags.go: global CLI surface for tuning VS Code Project Manager tag detection.

Three repeatable flags (each accepting comma-lists) let users override the defaults that ship in constants.AutoTagMarkers / AutoTagOrder:

--vscode-tag <name>             always add to every entry
--vscode-tag-skip <name>        drop this auto-detected tag
--vscode-tag-marker <file>=<tag> register marker→tag rule

Like `--vscode-sync-disabled`, the flags are stripped from argv before any subcommand sees its flagset and persisted into GITMAP_VSCODE_TAG_{ADD,SKIP,MARKER} for the current process. The vscodepm.DetectTagsCustom helper consumes those env vars, so every caller that swapped DetectTags → DetectTagsCustom inherits the rules without per-call wiring.

Package cmd — vscodesyncdisabled.go: global kill switch for the VS Code Project Manager projects.json sync.

The per-command `--no-vscode-sync` flag opts out of a single invocation. This file adds a process-wide lever that disables the sync for the current gitmap run AND every subprocess it spawns (clone-fix-repo, reclone batches, etc.) by flipping GITMAP_VSCODE_SYNC_DISABLED=1.

Activation paths (any one is enough):

  1. Pass `--vscode-sync-disabled` (or `-vscode-sync-disabled`) anywhere on the command line. It is stripped from os.Args before subcommand dispatch so individual flag.FlagSets never see an unknown flag.
  2. Export GITMAP_VSCODE_SYNC_DISABLED=1 in the shell. Useful for CI / headless boxes that should never touch projects.json regardless of which gitmap command runs.

Honored centrally by syncClonedReposToVSCodePM in clonepmsync.go, so every present and future clone variant inherits the behavior without per-call wiring.

Package cmd — vscodeworkspace.go: implements `gitmap vscode-workspace` (alias `vsws`).

Emits a single multi-root `.code-workspace` file from the same Repo table that drives the Project Manager sync, so one click in VS Code (File → Open Workspace from File…) opens every cloned repo as a folder in one window — no manual "Add Folder to Workspace…" loop.

Distinct from the projects.json sync: the PM sync gives you a flat sidebar list of projects (each opens in its own VS Code window); the workspace file gives you ONE window with N folders, ideal for cross-repo search / refactor. Both surfaces stay in lockstep because both read the same DB.

Spec: spec/01-vscode-project-manager-sync/03-workspace-export.md

Package cmd — `gitmap zip` (alias `z`).

Resolves N heterogeneous sources (folders, archive URLs, git repos) into local paths, then runs CreateArchive into the user-supplied --out path. Compression mode is chosen via mutually exclusive flags (--best / --fast / --standard, with -s as a synonym for standard).

Each invocation writes one ArchiveHistory row (in-flight at start, finalized at end) so a partial failure still leaves a forensic trace.

Index

Constants

View Source
const (
	StartupActionCreated     = "created"
	StartupActionOverwritten = "overwritten"
	StartupActionExists      = "exists"
	StartupActionRefused     = "refused"
	StartupActionBadName     = "bad_name"
	StartupActionDeleted     = "deleted"
	StartupActionNoOp        = "noop"
)

Action labels. Mirror the AddStatus / RemoveStatus enums but with snake_case strings safe for shell pipelines (jq, awk on the `.action` value). Kept as constants so the translators can't disagree on spelling.

View Source
const (
	StartupOwnerGitmap     = "gitmap"
	StartupOwnerThirdParty = "third-party"
	StartupOwnerNone       = "none"
	StartupOwnerUnknown    = "unknown"
)

Owner labels. Tells the consumer who CURRENTLY holds the on-disk entry — independent of what we did to it. "none" appears only when there's no entry at all (NoOp / BadName).

Variables

This section is empty.

Functions

func AliasAsRecords

func AliasAsRecords() []store.AliasWithRepo

AliasAsRecords returns the alias as a single-element ScanRecord slice. Useful for commands that operate on a list of repos.

func CheckSequenceRange

func CheckSequenceRange(start, count, digits int) error

CheckSequenceRange validates sequence range without os.Exit.

func CountUnguardedTokenHits

func CountUnguardedTokenHits(body, token string) int

CountUnguardedTokenHits is a convenience wrapper that returns just the hit count. Equivalent to len(ScanUnguardedTokenHits(...)) but avoids the slice allocation on hot paths.

func FormatSeq

func FormatSeq(seq, digits int) string

FormatSeq is an exported wrapper for testing formatSeq.

func GetAliasPath

func GetAliasPath() string

GetAliasPath returns the resolved alias path if set, or empty string.

func GetAliasSlug

func GetAliasSlug() string

GetAliasSlug returns the resolved alias slug if set, or empty string.

func HasAlias

func HasAlias() bool

HasAlias returns true if a -A flag was resolved.

func ParsePrettyFlag

func ParsePrettyFlag(args []string) ([]string, render.PrettyMode)

ParsePrettyFlag pulls --pretty / --no-pretty out of args and returns the cleaned slice + the resolved render.PrettyMode. Accepted forms:

--pretty            → PrettyOn
--pretty=true       → PrettyOn
--pretty=on         → PrettyOn
--pretty=1          → PrettyOn
--pretty=false      → PrettyOff
--pretty=off        → PrettyOff
--pretty=0          → PrettyOff
--pretty=auto       → PrettyAuto (explicit reset)
--no-pretty         → PrettyOff

When the same flag is repeated, the **last** occurrence wins (matches stdlib flag.Parse semantics). When neither appears, the returned mode is PrettyAuto so callers can rely on Decide()'s default ladder.

Unrecognized values fall through to PrettyAuto and the token is left in place so the downstream parser can produce a meaningful error.

func ParseVersionPatternSafe

func ParseVersionPatternSafe(pattern string) (string, int)

ParseVersionPatternSafe parses a version pattern without os.Exit.

func PrintBinaryLocations

func PrintBinaryLocations()

PrintBinaryLocations prints the Active / Deployed / Config binary triplet to stdout. Called from bare `gitmap` (no args) and from the post-update readout. The output is suppressed when --no-banner is in os.Args or when the GITMAP_QUIET env var is set to "1".

Definitions (see spec/01-app/89-deploy-layout-and-binary-readout.md):

  • Active = os.Executable() after filepath.EvalSymlinks. The file the OS actually loaded for this process.
  • Deployed = <powershell.json.deployPath>/gitmap-cli/<binaryName> if it exists on disk; "(not found)" otherwise.
  • Config = literal path the config declares, whether or not the file exists. Represents config intent.

func PrintCmdFaithfulReport

func PrintCmdFaithfulReport(w io.Writer, r CmdFaithfulReport) error

PrintCmdFaithfulReport writes the report to w. No-op when the report has no mismatches so callers can invoke it unconditionally. Returns the first write error so a closed stderr surfaces (zero- swallow policy).

Format (v4.13.0+): every line is prefixed with the severity tag `[FAIL]` so a CI log scraped one line at a time is unambiguous, and the banner ends with a hint about which flag promotes the report into a hard exit. The intent is to stop users asking "is this actually broken?" — the banner answers it inline.

func PrintCmdFaithfulReportForTest

func PrintCmdFaithfulReportForTest(w io.Writer, r CmdFaithfulReport) error

PrintCmdFaithfulReportForTest wraps PrintCmdFaithfulReport in a "--- expected mismatch ---" banner so test runs that intentionally drive a divergent input don't bury real `[FAIL]` lines in identical- looking simulated ones. Production code MUST NOT call this — only tests that deliberately exercise the mismatch print path. The banner emits even when the report is empty so the section is always paired open/close in captured output, making golden diffs and human scans deterministic.

func ResolveTRBranchExported

func ResolveTRBranchExported(version string) string

ResolveTRBranchExported is an exported wrapper for testing resolveTRBranch.

func Run

func Run()

Run is the main entry point for the CLI.

func ScanUnguardedTokenHits

func ScanUnguardedTokenHits(body, token string) []int

ScanUnguardedTokenHits returns every byte offset in body where token appears AND the rewriter's negative-lookahead guard would allow a substitution. The returned slice is in ascending order.

func WriteShellHandoff

func WriteShellHandoff(targetPath string)

WriteShellHandoff records `targetPath` so the shell wrapper function can `cd` to it after the binary exits.

Mechanism: the wrapper function exports `GITMAP_HANDOFF_FILE=<tmp>` before invoking the binary. We write `targetPath` to that file. The wrapper then reads it and cds. If the env var is unset (binary called without the wrapper) this is a no-op — `cd` still prints the path to stdout for legacy capture.

Spec: spec/04-generic-cli/21-post-install-shell-activation/01-contract.md

Types

type CloneFlags

type CloneFlags struct {
	Source     string
	FolderName string
	TargetDir  string
	SSHKeyName string
	// DefaultBranch mirrors `gitmap scan --default-branch`: when a
	// manifest row has an unknown / empty Branch (or a non-trustworthy
	// BranchSource like "detached" or "unknown"), the cloner rebuilds
	// the clone instruction as `git clone -b <DefaultBranch> ...`
	// instead of letting the remote's default HEAD decide. Empty keeps
	// the legacy behavior. Same constant powers both flags so the help
	// wording stays byte-identical across surfaces.
	DefaultBranch  string
	Positional     []string
	SafePull       bool
	GHDesktop      bool
	NoReplace      bool
	Verbose        bool
	Audit          bool
	MaxConcurrency int
	// Output selects the per-repo summary format. Empty (default)
	// keeps the legacy terse messages; "terminal" emits the
	// standardized RepoTermBlock right before each clone runs so
	// the shape matches scan/clone-next/clone-from/probe.
	Output string
	// VerifyCmdFaithful enables the dry-run argv-vs-displayed
	// checker. See clonetermverify.go for behavior.
	VerifyCmdFaithful bool
	// VerifyCmdFaithfulExitOnMismatch upgrades the verifier into a
	// hard failure: any divergence sets a sticky bit and the run tail
	// exits with constants.CloneVerifyCmdFaithfulExitCode. Implies
	// VerifyCmdFaithful.
	VerifyCmdFaithfulExitOnMismatch bool
	// PrintCloneArgv dumps the executor's literal argv tokens to
	// stderr. See cloneprintargv.go for behavior.
	PrintCloneArgv bool
	// NoVSCodeSync suppresses the post-clone update of the
	// alefragnani.project-manager projects.json file. Mirrors the
	// flag of the same name on `gitmap scan`. Default false →
	// every successful clone is reflected in the VS Code Project
	// Manager sidebar without an extra command. See
	// spec/01-vscode-project-manager-sync/02-clone-sync.md.
	NoVSCodeSync bool
}

CloneFlags holds all parsed clone-command flags and positional args. Exposing the full positional slice (Positional) lets runClone detect the multi-URL invocation form documented in spec/01-app/104-clone-multi.md.

type CloneNextFlags

type CloneNextFlags struct {
	VersionArg   string
	Delete       bool
	Keep         bool
	NoDesktop    bool
	CreateRemote bool
	SSHKeyName   string
	Verbose      bool
	CSVPath      string
	All          bool
	// Force forces a flat clone even when the user's cwd IS the target
	// folder. Triggers a chdir-to-parent before the existence check (to
	// release Windows file locks) and DISABLES the versioned-folder
	// fallback so the user gets either a flat layout or a clear error.
	// See spec/01-app/87-clone-next-flatten.md.
	Force bool
	// MaxConcurrency is the worker-pool size for batch mode (--all / --csv).
	// 1 (the default) preserves the historical sequential behavior so
	// stdout ordering of per-repo lines is deterministic. Values >1 fan
	// repos out across a bounded pool that mirrors the main cloner's
	// pattern (see gitmap/cloner/concurrent.go). Ignored in single-repo
	// mode where there is only one unit of work.
	MaxConcurrency int
	// NoProgress suppresses the live per-repo progress line printed
	// by the batch collector as workers finish. The final summary
	// (ok/failed/skipped totals) always prints regardless. Default
	// false so users get progress feedback out-of-the-box.
	NoProgress bool
	// ReportErrors enables a JSON failure report at command exit
	// when any per-repo clone fails. Off by default; mirrors the
	// `gitmap scan --errors-report` flag for consistent UX.
	ReportErrors bool
	// DryRun, when true, prints the would-be `git clone` commands
	// (single-repo + batch) and skips ALL side effects — no actual
	// clone, no folder removal, no DB write, no GH Desktop / VS Code
	// launch, no shell handoff. See FlagCloneNextDryRun.
	DryRun bool
	// Output selects the per-repo summary format. Empty keeps the
	// legacy terse stage messages; "terminal" additionally emits
	// the standardized RepoTermBlock right before the clone, so the
	// shape matches scan/clone-from/probe.
	Output string
	// VerifyCmdFaithful enables the dry-run argv-vs-displayed checker.
	VerifyCmdFaithful bool
	// VerifyCmdFaithfulExitOnMismatch upgrades the verifier into a
	// hard failure: any divergence sets a sticky bit and the run tail
	// exits with constants.CloneVerifyCmdFaithfulExitCode. Implies
	// VerifyCmdFaithful.
	VerifyCmdFaithfulExitOnMismatch bool
	// PrintCloneArgv dumps the executor argv to stderr.
	PrintCloneArgv bool
	// NoVSCodeSync suppresses the post-clone update of the
	// alefragnani.project-manager projects.json file. Mirrors
	// `gitmap scan --no-vscode-sync`. Default false. See
	// spec/01-vscode-project-manager-sync/02-clone-sync.md.
	NoVSCodeSync bool
}

CloneNextFlags bundles every parsed flag from the clone-next command so the dispatcher in runCloneNext can branch on batch vs single mode without a 9-arg return list.

type CloneTermBlockInput

type CloneTermBlockInput struct {
	Index        int
	Name         string
	Branch       string
	BranchSource string
	OriginalURL  string
	TargetURL    string
	Dest         string
	// CmdBranch overrides which branch (if any) is rendered as `-b`
	// in the printed cmd. Empty = no `-b` flag, regardless of what
	// Branch (the display field) holds. Defaults to Branch when the
	// caller leaves both CmdBranch AND CmdExtraArgs* unset (legacy
	// fallback for clone-now / clone-pick rows).
	CmdBranch string
	// CmdExtraArgsPre are tokens between `git clone` and `-b`.
	CmdExtraArgsPre []string
	// CmdExtraArgsPost are tokens between `-b <branch>` and the
	// positional URL/dest pair.
	CmdExtraArgsPost []string
}

CloneTermBlockInput carries the per-repo data every clone command already has on hand. Branch/BranchSource may be empty — the renderer falls back to "(unknown)" so the block shape is stable.

Faithfulness contract (audited): the printed `cmd:` line MUST be byte-identical to the argv the executor passes to exec.Command. Each caller controls three override fields to achieve that:

  • CmdBranch: branch passed to `-b` in the printed cmd. Empty means "no `-b` flag".
  • CmdExtraArgsPre: literal tokens inserted between `git clone` and the `-b` slot. Used by clone-pick for `--filter=blob:none --no-checkout` and the long-form `--branch X` / `--depth N`.
  • CmdExtraArgsPost: literal tokens inserted between the `-b` slot and the positional `<url> <dest>` pair. Used by clone-from for `--depth=N` (its executor places --depth AFTER -b).

type CmdFaithfulMismatch

type CmdFaithfulMismatch struct {
	Index     int
	Displayed string
	Executed  string
	Reason    string // short tag: "differs", "missing-in-displayed", "missing-in-executed"
}

CmdFaithfulMismatch describes one position-level divergence between the displayed cmd: tokens and the executor's argv. Index is 0-based over the joined slice (git, clone, …). Either Displayed or Executed may be empty when one slice is shorter than the other.

type CmdFaithfulReport

type CmdFaithfulReport struct {
	Repo       string
	Displayed  string // exact `cmd:` string the user would see
	Executed   string // space-joined executor argv (incl. "git")
	Mismatches []CmdFaithfulMismatch
}

CmdFaithfulReport bundles the per-row verification result. Empty Mismatches means the two forms are byte-identical when joined by single spaces — which is the contract --output terminal advertises.

func VerifyCmdFaithful

func VerifyCmdFaithful(in CloneTermBlockInput, executorArgv []string) CmdFaithfulReport

VerifyCmdFaithful computes the displayed cmd: line via buildCloneCommand and compares it token-by-token to executorArgv (which the caller obtains from clonenow.BuildGitArgs / clonefrom.BuildGitArgs / clonepick.BuildGitArgs). The "git" prefix is prepended to executorArgv internally so the two forms align — the executors return argv WITHOUT the binary, matching exec.Command's convention.

Pure function: no I/O, deterministic. Caller decides where (if anywhere) to print the resulting report — see PrintCmdFaithfulReport.

func (CmdFaithfulReport) HasMismatch

func (r CmdFaithfulReport) HasMismatch() bool

HasMismatch is a convenience predicate so callers can branch without poking at the slice length directly.

type ScanProbeOptions

type ScanProbeOptions struct {
	// Disable suppresses the background probe entirely. Set via --no-probe.
	Disable bool
	// NoWait makes scan return immediately after dispatching jobs;
	// the runner keeps draining in the background until process exit.
	NoWait bool
	// Concurrency overrides the worker count. 0 = use the documented
	// default; negative values disable the runner the same as --no-probe.
	Concurrency int
	// ConcurrencySet records whether the user explicitly passed
	// --probe-workers (or the deprecated --probe-concurrency alias).
	// Used to bypass the auto-trigger ceiling for power users who
	// clearly opted in.
	ConcurrencySet bool
	// Depth is the `--depth N` value forwarded to the shallow-clone
	// fallback inside the background runner. Defaults to
	// constants.ProbeDefaultDepth (1) when no flag was passed.
	Depth int
}

ScanProbeOptions bundles the flags that govern the optional background version-probe pass scan kicks off after upserting repos. Bundling them keeps parseScanFlags's return list manageable and makes the runner-wiring call site read as a single cohesive object.

Source Files

Directories

Path Synopsis
Package commitin contains the typed enums and shared types for the `gitmap commit-in` (cin) command.
Package commitin contains the typed enums and shared types for the `gitmap commit-in` (cin) command.
orchestrator
Package orchestrator wires the commit-in sub-packages together.
Package orchestrator wires the commit-in sub-packages together.

Jump to

Keyboard shortcuts

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