Files
herolib/lib/develop/gittools/architecture.md
2025-08-15 06:30:12 +02:00

7.4 KiB
Raw Blame History

GitTools Module Architecture

1. Purpose

GitTools is a lightweight Gitoriented service layer written in VLang. It sits between higherlevel application code (CLI tools, DevOps scripts, GUIs) and the Git executable, offering:

  • Repository discovery & lifecycle under a single coderoot directory
  • Highlevel operations (clone, commit, push, pull, delete, …) that can be executed in batch across many repos
  • Status inspection & caching through Redis, so expensive git calls are avoided between runs
  • Utility helpers (path mapping, VS Code / SourceTree launchers, SSHkey setup) to smooth local development workflows.

2. HighLevel 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 inmemory map of &GitRepo and persists metadata in Redis (git:<coderoothash> keys).
  • GitRepo wraps a single workingtree and exposes both mutating commands (commit, push, pull, …) and informational queries (need_commit, get_changes_*).
  • GitLocation is a purevalue helper that parses/creates Git URLs or paths without touching the filesystem.

Key flows:

  1. gittools.new() (→ factory.v) constructs or fetches a GitStructure for a coderoot.
  2. Repository acquisition via get_repo() | get_repos() | path() these consult the inmemory map and Redis; cloning is performed ondemand.
  3. Expensive remote state (git fetch, branch/tag lists) is refreshed by GitRepo.load() and memoised until remote_check_period expires.
  4. Batch operations are orchestrated by GitStructure.do() (→ gittools_do.v) which parses CLIlike arguments and delegates to each selected repo.

3. FilebyFile 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, SSHkey handling.
repository_load.v Pulls reality into memory (git fetch, branch/tag maps) and maintains the last_load timestamp.
repository_info.v Highlevel 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 & GitStatus

The state of a repository is captured in a single, unified GitStatus struct. This struct represents the current state of the repository after a status_update() operation and does not contain any "desired" or "wanted" state. State changes are performed through imperative function calls (e.g., repo.branch_switch('main')).

pub struct GitRepo {
	provider     string
	account      string
	name         string
	config       GitRepoConfig
	status       GitStatus  // Unified CURRENT status object
}

pub struct GitStatus {
pub mut:
	// Combined local & remote state from `git fetch`
	branches map[string]string // branch name -> commit hash
	tags     map[string]string // tag name -> commit hash

	// Current local state
	branch   string // current checked-out branch
	tag      string // current checked-out tag (if any)
	ahead    int    // commits ahead of remote
	behind   int    // commits behind remote

	// Overall status
	has_changes bool   // true if uncommitted changes exist
	error       string // holds error messages from status updates
}

5. Execution & Behavioural Notes

  1. Shallow clones configurable via GitStructureConfig.light; uses --depth 1 to accelerate onboarding.
  2. SSH vs HTTPS selection GitRepo.get_repo_url_for_clone() interrogates ssh-agent presence; falls back to HTTPS when no agent.
  3. Global instance cache __global ( gsinstances map[string]&GitStructure ) guarantees a single object per process. Caveat: not threadsafe.
  4. Command execution all Git interaction flows through GitRepo.exec(), a thin os.execute wrapper that embeds cd into the command.
  5. Offline mode an OFFLINE envvar shortcircuits remote fetches, to make sure we are not stuck e.g. in plane