Class: Space::Src::SCM::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/space_src/scm/client.rb

Overview

Abstract SCM interface. The git CLI is the only implementation for now (per AGENTS.md / PRD §1), but the sync engine + tests must code to this interface so a future SCM is a drop-in.

Every method returns a Dry::Monads::Result. Programmer error (e.g. nil path) is a raise; expected failures (no .git, non-fast- forward, network down) are Failure.

Direct Known Subclasses

Git

Instance Method Summary collapse

Instance Method Details

#clone(url, path) ⇒ Object

git clone <url> <path>.

Raises:

  • (NotImplementedError)


58
59
60
# File 'lib/space_src/scm/client.rb', line 58

def clone(url, path)
  raise NotImplementedError
end

#current_branch(path) ⇒ Object

Returns the current branch name, or nil if HEAD is detached.

Raises:

  • (NotImplementedError)


25
26
27
# File 'lib/space_src/scm/client.rb', line 25

def current_branch(path)
  raise NotImplementedError
end

#default_branch(path) ⇒ Object

Returns the bare remote's HEAD (e.g. "main" or "trunk"). Must work even when the default branch is not "main". May do a one-shot network call (git remote set-head origin -a) to refresh a stale origin/HEAD.

Raises:

  • (NotImplementedError)


33
34
35
# File 'lib/space_src/scm/client.rb', line 33

def default_branch(path)
  raise NotImplementedError
end

#fast_forward(path, default_branch) ⇒ Object

git merge --ff-only origin/<default>. Returns Failure if the local branch has diverged (left count > 0) — never resets. On Success: returns Integer commit count pulled. 0 → already up to date (no merge performed) N → fast-forwarded N commits

Raises:

  • (NotImplementedError)


53
54
55
# File 'lib/space_src/scm/client.rb', line 53

def fast_forward(path, default_branch)
  raise NotImplementedError
end

#fetch(path) ⇒ Object

git fetch --prune --no-tags origin.

Raises:

  • (NotImplementedError)


44
45
46
# File 'lib/space_src/scm/client.rb', line 44

def fetch(path)
  raise NotImplementedError
end

#last_fetch_at(path) ⇒ Object

Returns the mtime of .git/FETCH_HEAD, or nil if absent. Treated as a freshness hint (PRD §3.3 step 4 + gate G5).

Raises:

  • (NotImplementedError)


39
40
41
# File 'lib/space_src/scm/client.rb', line 39

def last_fetch_at(path)
  raise NotImplementedError
end

#status(path) ⇒ Object

Parse the working-tree status of a repo on disk. Implementation must read porcelain v2 (per AGENTS.md gotcha) and report a SCM::Status value object.

Raises:

  • (NotImplementedError)


20
21
22
# File 'lib/space_src/scm/client.rb', line 20

def status(path)
  raise NotImplementedError
end

#switch(path, branch) ⇒ Object

git switch <branch>. Switches the local repo to the given branch. By default git switch refuses to clobber a dirty working tree (the operation is aborted on local-change loss per man git-switch); the engine treats that as a Failure. The engine is responsible for the upstream dirty-tree guard (per Slice 2 gate G5 / PHASE-0 ruling): the plan returns :report_wrong_branch / :report_detached for a dirty tree, so this method is only called on clean trees.

Raises:

  • (NotImplementedError)


70
71
72
# File 'lib/space_src/scm/client.rb', line 70

def switch(path, branch)
  raise NotImplementedError
end

#sync_empty(path) ⇒ Object

Sync an unborn (empty) local clone. Called when the repo has no commits (status.unborn? == true) and the working tree is clean. Returns Success(:empty) when the remote has no branches (valid empty clone; no mutation). Returns Success(:fast_forwarded) when the remote has gained commits and the local clone was advanced to them. Returns Failure on a real network/probe error (the empty-vs-error distinction is made via git ls-remote --heads origin: exit 0 = definitive answer; non-zero = real error).

Raises:

  • (NotImplementedError)


82
83
84
# File 'lib/space_src/scm/client.rb', line 82

def sync_empty(path)
  raise NotImplementedError
end