Module: SpecGuard::RSpec::GitCheckout
- Defined in:
- lib/specguard/rspec/configuration.rb
Overview
Where the checkout is sitting — which commit, and which branch — asked of git directly.
This is the last resort for both, consulted only when no environment variable named the answer.
The two questions carry different stakes and the same honesty
requirement. commit_sha is the one envelope field the platform refuses
a run without (Ingest::Payload#validate_commit_sha rejects a blank one
and the whole POST comes back 400, every example discarded), so a run
that cannot name its commit is a run whose telemetry is lost entirely —
not one with a gap in it. A nil branch, by contrast, is accepted: the
platform stores it, and renders it as "not reported". Which is precisely
why a guess is worse here than a gap — see BRANCH_COMMAND.
Three properties, all load-bearing, and both questions have all three:
* It never raises. `git` may not be installed at all, in which case
`IO.popen` raises `Errno::ENOENT` before a subprocess ever exists.
* It never prints. `git rev-parse HEAD` outside a repository writes
"fatal: not a git repository" to stderr, and a telemetry tool that
graffitis somebody's CI log with a git error has already failed.
* It answers once per process. Each result is memoized *separately*
because a subprocess is expensive relative to everything else here,
and neither answer can change mid-run.
Constant Summary collapse
- COMMIT_SHA_COMMAND =
%w[git rev-parse HEAD].freeze
- BRANCH_COMMAND =
symbolic-ref, deliberately, and notrev-parse --abbrev-ref HEAD.On a detached checkout
--abbrev-refsucceeds, exit 0, printing the literal string"HEAD".actions/checkoutdetaches by default, so that command would reportbranch: "HEAD"for a large share of CI runs — a value the platform stores, renders in its Branch column, and groups by, indistinguishable from a repository that genuinely has a branch calledHEAD. It is the wrong answer wearing the costume of a right one.git symbolic-ref --short -q HEADasks the question actually being asked: what branch is HEAD a symbolic reference to? Detached, there is no answer, and it says so the honest way — no output, exit 1, and-qkeeps it silent while doing it. resolve's existing$?.success?guard turns that straight intonil, which is what a detached checkout should report and what the platform already knows how to render. %w[git symbolic-ref --short -q HEAD].freeze
Class Method Summary collapse
-
.branch ⇒ String?
The branch the checkout is on, or nil for any reason at all — no git, no repository, and notably a detached HEAD, which is nil rather than the string "HEAD".
-
.commit_sha ⇒ String?
The checked-out commit, or nil for any reason at all — no git, no repository, an empty repository, a broken HEAD.
-
.reset! ⇒ void
Drop the memoized answers — both of them.
Class Method Details
.branch ⇒ String?
Returns the branch the checkout is on, or nil for any reason at all — no git, no repository, and notably a detached HEAD, which is nil rather than the string "HEAD". See BRANCH_COMMAND.
63 64 65 66 67 |
# File 'lib/specguard/rspec/configuration.rb', line 63 def branch return @branch if defined?(@branch) @branch = resolve(BRANCH_COMMAND) end |
.commit_sha ⇒ String?
Returns the checked-out commit, or nil for any reason at all — no git, no repository, an empty repository, a broken HEAD.
53 54 55 56 57 |
# File 'lib/specguard/rspec/configuration.rb', line 53 def commit_sha return @commit_sha if defined?(@commit_sha) @commit_sha = resolve(COMMIT_SHA_COMMAND) end |
.reset! ⇒ void
This method returns an undefined value.
Drop the memoized answers — both of them. For tests, and for the rare caller that changes directory into a different checkout mid-process, where the commit and the branch have equally gone stale.
74 75 76 77 78 |
# File 'lib/specguard/rspec/configuration.rb', line 74 def reset! remove_instance_variable(:@commit_sha) if defined?(@commit_sha) remove_instance_variable(:@branch) if defined?(@branch) nil end |