Module: SnapDiff::Vcs
- Defined in:
- lib/snap_diff/vcs.rb
Constant Summary collapse
- GIT_ENV =
-C <dir>sets the working directory, but GIT_DIR/GIT_WORK_TREE OVERRIDE it -- so a suite launched from a git hook (which exports both) reads the WRONG repository. Every baseline lookup then fails, and becausefail_if_newis false locally, screenshots are recorded as new and the tests PASS. Scrubbing them makes-Cmean what this code already assumes. {"GIT_DIR" => nil, "GIT_WORK_TREE" => nil, "GIT_INDEX_FILE" => nil}.freeze
Class Method Summary collapse
- .checkout_vcs(root, screenshot_path, checkout_path) ⇒ Object
-
.git_root_for(root_path) ⇒ Object
git rev-parse --show-toplevelcosts a process spawn (~6ms) and used to run once per screenshot -- 200 screenshots, 200 spawns, all answering the same question.
Class Method Details
.checkout_vcs(root, screenshot_path, checkout_path) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/snap_diff/vcs.rb', line 18 def self.checkout_vcs(root, screenshot_path, checkout_path) root_path = root.to_s git_root = git_root_for(root_path) return false unless git_root vcs_file_path = Pathname.new(screenshot_path)..relative_path_from(Pathname.new(git_root)).to_s if SnapDiff.config.use_lfs tmp_path = "#{checkout_path}.tmp" success = system(GIT_ENV, "git", "-C", root_path, "show", "HEAD:#{vcs_file_path}", out: tmp_path, err: File::NULL) if success system(GIT_ENV, "git", "-C", root_path, "lfs", "smudge", in: tmp_path, out: checkout_path.to_s, err: File::NULL) end File.delete(tmp_path) if File.exist?(tmp_path) else success = system(GIT_ENV, "git", "-C", root_path, "show", "HEAD:#{vcs_file_path}", out: checkout_path.to_s, err: File::NULL) end unless success checkout_path.delete if checkout_path.exist? return false end true end |
.git_root_for(root_path) ⇒ Object
git rev-parse --show-toplevel costs a process spawn (~6ms) and used to
run once per screenshot -- 200 screenshots, 200 spawns, all answering the
same question. The repository a directory belongs to does not change
while the suite runs, so remember it per directory. false (not a repo)
is remembered too: that is the every-assertion answer for anyone whose
screenshots live outside a git checkout.
Synchronized because the lookup itself is what must not be duplicated:
MRI releases the GVL for the whole of Open3.capture3, so eight threads
asking about one root all miss key? before any of them writes -- eight
spawns, the exact cost this cache exists to remove. Threads are the
default parallel mode on JRuby, which has no GVL to make the Hash write
safe either. Holding the lock across the spawn is deliberate: callers
almost always share one root, so the other threads wait once and then
read the cache, which is the outcome we want.
59 60 61 62 63 64 65 66 |
# File 'lib/snap_diff/vcs.rb', line 59 def self.git_root_for(root_path) @git_roots_lock.synchronize do next @git_roots[root_path] if @git_roots.key?(root_path) git_root, _, status = Open3.capture3(GIT_ENV, "git", "-C", root_path, "rev-parse", "--show-toplevel") @git_roots[root_path] = status.success? && git_root.chomp end end |