6.8 KiB
6.8 KiB
GitTools Module Architecture
1. Purpose
GitTools is a lightweight Git‑oriented service layer written in V Lang. It sits between higher‑level application code (CLI tools, DevOps scripts, GUIs) and the Git executable, offering:
- Repository discovery & life‑cycle under a single code‑root directory
- High‑level operations (clone, commit, push, pull, delete, …) that can be executed in batch across many repos
- Status inspection & caching through Redis, so expensive
gitcalls are avoided between runs - Utility helpers (path mapping, VS Code / SourceTree launchers, SSH‑key setup) to smooth local development workflows.
2. High‑Level Design
┌────────────────────┐ 1️⃣ factory.new()
│ GitStructure │<─────────────┐
│ (singleton/cache) │ │
└────────────────────┘ │
▲ owns many │
│ │
│ 2️⃣ get_repo()/path() │
│ ▼
┌────────────────────┐ exec() / status_update()
│ GitRepo │──────────────────────────────┐
│ (one repository) │ │
└────────────────────┘◄──────────────────────────────┘
│
▼ uses
┌────────────────────┐
│ GitLocation │ (URL ↔ path ↔ metadata conversions)
└────────────────────┘
- GitStructure (singleton per coderoot) is the entry point; it maintains an in‑memory map of
&GitRepoand persists metadata in Redis (git:<coderoot‑hash>keys). - GitRepo wraps a single working‑tree and exposes both mutating commands (
commit,push,pull, …) and informational queries (need_commit,get_changes_*). - GitLocation is a pure‑value helper that parses/creates Git URLs or paths without touching the filesystem.
Key flows:
gittools.new()(→factory.v) constructs or fetches aGitStructurefor a coderoot.- Repository acquisition via
get_repo()|get_repos()|path()– these consult the in‑memory map and Redis; cloning is performed on‑demand. - Expensive remote state (
git fetch, branch/tag lists) is refreshed byGitRepo.load()and memoised untilremote_check_periodexpires. - Batch operations are orchestrated by
GitStructure.do()(→gittools_do.v) which parses CLI‑like arguments and delegates to each selected repo.
3. File‑by‑File Breakdown
| File | Core Responsibility |
|---|---|
| factory.v | Public API. Creates/gets GitStructure, initialises Redis config, and exposes gittools.path() helper. |
| gitstructure.v | Implements the GitStructure aggregate: caching, recursive discovery, config persistence. |
| gitlocation.v | Pure parsing utilities to derive a GitLocation from URLs or FS paths. |
| repository.v | Primary GitRepo implementation: mutations (commit/push/etc.), checkout logic, SSH‑key handling. |
| repository_load.v | Pulls reality into memory (git fetch, branch/tag maps) and maintains the last_load timestamp. |
| repository_info.v | High‑level queries (need_pull, need_push,…) and diff helpers. |
| repository_utils.v | Convenience UX helpers (VS Code, SourceTree, human paths, URL builders). |
| repository_cache.v | Thin Redis (de)serialisation for GitRepo. |
| gittools_do.v | Batch command dispatcher used by topline scripts/CLI. |
| repos_get.v / repos_print.v | Collection filtering, status table printer. |
| tests | Pure V unit tests for URL parsing & path logic. |
4. Data Structures & Storage
4.1 GitStructure
pub struct GitStructure {
key string // md5(coderoot)
coderoot pathlib.Path // ~/code by default
repos map[string]&GitRepo // key = provider:account:name
config_ ?GitStructureConfig // persisted in Redis
}
Redis schema
site:key → config JSON
site:key:repos:<provider:acct:name> → GitRepo JSON
4.2 GitRepo (excerpt)
pub struct GitRepo {
provider string // e.g. github
account string // org/user
name string // repo name
status_remote GitRepoStatusRemote
status_local GitRepoStatusLocal
status_wanted GitRepoStatusWanted
last_load int // epoch
has_changes bool
}
Status structs separate remote, local and desired state, enabling need_* predicates to remain trivial.
5. Execution & Behavioural Notes
- Shallow clones – configurable via
GitStructureConfig.light; uses--depth 1to accelerate onboarding. - SSH vs HTTPS selection –
GitRepo.get_repo_url_for_clone()interrogatesssh-agentpresence; falls back to HTTPS when no agent. - Global instance cache –
__global ( gsinstances map[string]&GitStructure )guarantees a single object per process. Caveat: not thread‑safe. - Command execution – all Git interaction flows through
GitRepo.exec(), a thinos.executewrapper that embedscdinto the command. - Offline mode – an
OFFLINEenv‑var short‑circuits remote fetches, to make sure we are not stuck e.g. in plane