Class: RailVerdict::RepositoryState

Inherits:
Object
  • Object
show all
Defined in:
lib/rail_verdict/repository_state.rb

Defined Under Namespace

Classes: UnavailableError

Constant Summary collapse

SCHEMA_VERSION =
"1"
MAX_INDEX_BYTES =
8 * 1024 * 1024
MAX_STATUS_BYTES =
4 * 1024 * 1024
MAX_DIRTY_PATHS =
500
MAX_FILE_BYTES =
2 * 1024 * 1024
UNBORN_HEAD =
"unborn"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(projection:, unavailable_reason: nil, dirty_paths_count: nil) ⇒ RepositoryState

Returns a new instance of RepositoryState.



280
281
282
283
284
285
# File 'lib/rail_verdict/repository_state.rb', line 280

def initialize(projection:, unavailable_reason: nil, dirty_paths_count: nil)
  @projection = projection&.freeze
  @unavailable_reason = unavailable_reason&.to_s&.freeze
  @dirty_paths_count = dirty_paths_count
  freeze
end

Instance Attribute Details

#dirty_paths_countObject (readonly)

Returns the value of attribute dirty_paths_count.



27
28
29
# File 'lib/rail_verdict/repository_state.rb', line 27

def dirty_paths_count
  @dirty_paths_count
end

#projectionObject (readonly)

Returns the value of attribute projection.



27
28
29
# File 'lib/rail_verdict/repository_state.rb', line 27

def projection
  @projection
end

#unavailable_reasonObject (readonly)

Returns the value of attribute unavailable_reason.



27
28
29
# File 'lib/rail_verdict/repository_state.rb', line 27

def unavailable_reason
  @unavailable_reason
end

Class Method Details

.capture(repository_root:, runner: ProcessRunner, configuration_paths: nil) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rail_verdict/repository_state.rb', line 29

def self.capture(repository_root:, runner: ProcessRunner, configuration_paths: nil)
  root = File.realpath(repository_root)
  paths = resolve_configuration_paths(root, configuration_paths)

  head = capture_head(root, runner: runner)
  index_digest = capture_index_digest(root, runner: runner)
  worktree = capture_worktree(root, runner: runner)
  configuration_digest = file_content_identity(paths.fetch(:config))
  baseline_digest = optional_file_digest(paths.fetch(:baseline))
  waivers_digest = optional_file_digest(paths.fetch(:waivers))

  components = {
    "head" => head,
    "index_digest" => index_digest,
    "worktree_digest" => worktree.fetch("digest"),
    "configuration_digest" => configuration_digest,
    "baseline_digest" => baseline_digest,
    "waivers_digest" => waivers_digest
  }
  digest = "sha256:#{Digest::SHA256.hexdigest(CanonicalJSON.generate(components))}"
  projection = {
    "schema_version" => SCHEMA_VERSION,
    "digest" => digest,
    "components" => components
  }
  new(projection: projection, dirty_paths_count: worktree.fetch("dirty_paths_count"))
rescue UnavailableError => error
  unavailable(error.reason)
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::EMFILE, Errno::ENAMETOOLONG
  unavailable(:repository_root_unavailable)
rescue StandardError
  unavailable(:capture_failed)
end

.unavailable(reason) ⇒ Object



276
277
278
# File 'lib/rail_verdict/repository_state.rb', line 276

def self.unavailable(reason)
  new(projection: nil, unavailable_reason: reason.to_s, dirty_paths_count: nil)
end

Instance Method Details

#available?Boolean

Returns:

  • (Boolean)


287
288
289
# File 'lib/rail_verdict/repository_state.rb', line 287

def available?
  !@projection.nil?
end

#componentsObject



295
296
297
# File 'lib/rail_verdict/repository_state.rb', line 295

def components
  available? ? @projection.fetch("components") : nil
end

#digestObject



291
292
293
# File 'lib/rail_verdict/repository_state.rb', line 291

def digest
  available? ? @projection.fetch("digest") : nil
end

#raise_unavailable!(context: "repository state") ⇒ Object

Raises:



299
300
301
302
303
# File 'lib/rail_verdict/repository_state.rb', line 299

def raise_unavailable!(context: "repository state")
  return self if available?

  raise UnavailableError.new(@unavailable_reason, detail: context)
end