Class: Bundler::Codegraph::ErrorLog

Inherits:
Object
  • Object
show all
Defined in:
lib/bundler/codegraph/error_log.rb

Overview

codegraph's error output for one gem, kept in the runtime directory for as long as the last run on that gem failed.

The log starts with the directory it is about, is written under a temporary name while codegraph runs, and only takes its own name once the run failed: a log naming a directory means codegraph failed on it and nothing retried it since — never that a run is still going. A new version of the gem is a new directory.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(gem_path) ⇒ ErrorLog

Returns a new instance of ErrorLog.

Parameters:

  • gem_path (String) —

    directory codegraph runs on



34
35
36
37
38
39
# File 'lib/bundler/codegraph/error_log.rb', line 34

def initialize(gem_path)
  @path     = self.class.path(gem_path)
  @gem_path = gem_path
  @kept     = false
  @logged   = false
end

Instance Attribute Details

#gem_path ⇒ Object (readonly)

Returns the value of attribute gem_path.



31
32
33
# File 'lib/bundler/codegraph/error_log.rb', line 31

def gem_path
  @gem_path
end

#path ⇒ Object (readonly)

Returns the value of attribute path.



31
32
33
# File 'lib/bundler/codegraph/error_log.rb', line 31

def path
  @path
end

Class Method Details

.path(gem_path) ⇒ String?

Named after the gem directory and a digest of its full path (rack-3.2.6-<digest>.log): two directories of the same name — the same version in two projects' .bundle/, two path: sources called admin — keep a log each, instead of erasing each other's on every run.

Parameters:

  • gem_path (String) —

    directory codegraph runs on

Returns:

  • (String, nil) —

    nil when the runtime directory cannot be trusted



26
27
28
29
# File 'lib/bundler/codegraph/error_log.rb', line 26

def self.path(gem_path)
  dir = RuntimeDir.path
  dir && File.join(dir, "#{File.basename(gem_path)}-#{::Digest::SHA256.hexdigest(gem_path)[0, 12]}.log")
end

Instance Method Details

#capture ⇒ Object

Yields the stream codegraph's stderr should go to, and keeps the log only when the block returns a failure. An exception — Interrupt included — drops it too: codegraph did not fail, it was stopped, and a kept log would stop the hook from ever retrying the gem.

Only an explicit false is a codegraph failure: nil means it could not even be started. A log that cannot be opened (full disk) must not cost the index either, so codegraph then runs without one.

Returns:

  • the block's value



76
77
78
79
80
81
82
83
84
85
# File 'lib/bundler/codegraph/error_log.rb', line 76

def capture(&)
  @kept = false
  return yield(File::NULL) unless path

  succeeded = write(&)
  @kept = succeeded == false && @logged && publish
  succeeded
ensure
  FileUtils.rm_f(partial_path) if path
end

#discard ⇒ Object



62
63
64
# File 'lib/bundler/codegraph/error_log.rb', line 62

def discard
  FileUtils.rm_f(path) if path
end

#failed_before? ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
# File 'lib/bundler/codegraph/error_log.rb', line 56

def failed_before?
  return false unless path && File.exist?(path)

  File.foreach(path).first&.chomp == gem_path
end

#hint ⇒ String

Where to find codegraph's error output, as a suffix for a failure message; empty unless this attempt kept a log.

Returns:

  • (String)


52
53
54
# File 'lib/bundler/codegraph/error_log.rb', line 52

def hint
  kept? ? ", see #{path}" : ''
end

#kept? ⇒ Boolean

Whether the last capture kept a log — the only log a failure message may point at: one found on disk could predate this attempt, or belong to another process working on another version of the gem.

Returns:

  • (Boolean)


44
45
46
# File 'lib/bundler/codegraph/error_log.rb', line 44

def kept?
  @kept
end