Module: Ibex::CLIGenerationArtifacts

Included in:
CLI
Defined in:
lib/ibex/cli/generation_artifacts.rb,
sig/ibex/cli/generation_artifacts.rbs

Overview

Collects, verifies, and transactionally publishes CLI generation outputs.

Instance Method Summary collapse

Instance Method Details

#add_generation_manifestvoid

This method returns an undefined value.

RBS:

  • () -> void



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ibex/cli/generation_artifacts.rb', line 58

def add_generation_manifest
  require_relative "../generation_manifest"

  path = manifest_output_path
  source = GenerationManifest.render(
    generation_artifacts,
    source_records: @generation_inputs,
    options: generation_manifest_options
  )
  register_artifact(:manifest, path, source, status: true)
end

#append_ir_manifest_options(options) ⇒ void

This method returns an undefined value.

RBS:

  • (Hash[String, Object?] options) -> void

Parameters:

  • options (Hash[String, Object?])


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ibex/cli/generation_artifacts.rb', line 144

def append_ir_manifest_options(options)
  automaton = @generation_automaton
  return unless automaton

  grammar = automaton.grammar
  contract = grammar.parser_contract
  options["grammar_ir"] = {
    "schema_version" => grammar.schema_version,
    "digest" => automaton.grammar_digest,
    "parser_contract" => stringify_contract(contract)
  }
  options["automaton_ir"] = {
    "schema_version" => automaton.schema_version,
    "algorithm" => automaton.algorithm,
    "entry_construction" => automaton.entry_construction,
    "construction_authority" => construction_authority
  }
  options["effective_configuration"] = manifest_effective_configuration
end

#artifact_label(kind) ⇒ String

RBS:

  • (Symbol kind) -> String

Parameters:

  • kind (Symbol)

Returns:

  • (String)


80
81
82
83
84
85
86
87
# File 'lib/ibex/cli/generation_artifacts.rb', line 80

def artifact_label(kind)
  {
    parser: "parser",
    rbs: "RBS signature",
    action_source: "action source",
    manifest: "generation manifest"
  }.fetch(kind, kind.to_s.tr("_", " "))
end

#begin_artifact_generationvoid

This method returns an undefined value.

RBS:

  • () -> void



21
22
23
24
25
26
27
# File 'lib/ibex/cli/generation_artifacts.rb', line 21

def begin_artifact_generation
  @generation_artifacts = ArtifactSet.new
  @generation_statuses = [] #: Array[String]
  @generation_sources = [] #: Array[String]
  @generation_inputs = [] #: Array[GenerationInput]
  @generation_automaton = nil
end

#construction_authorityString

RBS:

  • () -> String

Returns:

  • (String)


165
166
167
# File 'lib/ibex/cli/generation_artifacts.rb', line 165

def construction_authority
  @options[:from] == "automaton-ir" ? "embedded_automaton" : "grammar_contract"
end

#effective_cst_triviaSymbol

RBS:

  • () -> Symbol

Returns:

  • (Symbol)


185
186
187
# File 'lib/ibex/cli/generation_artifacts.rb', line 185

def effective_cst_trivia
  configuration_value("cst.trivia") #: Symbol
end

#ensure_generation_inputs_stable!void

This method returns an undefined value.

RBS:

  • () -> void



100
101
102
103
104
# File 'lib/ibex/cli/generation_artifacts.rb', line 100

def ensure_generation_inputs_stable!
  return if generation_inputs_stable?

  raise GenerationTransaction::SourceChanged, "(generation):1:1: source changed while rendering outputs"
end

#finish_artifact_generation(_source_paths) ⇒ Integer

RBS:

  • (Array[String] source_paths) -> Integer

Parameters:

  • source_paths (Array[String])

Returns:

  • (Integer)


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ibex/cli/generation_artifacts.rb', line 37

def finish_artifact_generation(_source_paths)
  add_generation_manifest if @options[:manifest]
  return 0 if @defer_generation_publication

  ensure_generation_inputs_stable!
  if @options[:verify_output]
    verify_artifact_generation
    ensure_generation_inputs_stable!
  elsif !generation_artifacts.empty?
    GenerationTransaction.new(
      generation_artifacts,
      warning: ->(message) { @stderr.puts("ibex: warning: #{message}") },
      stability_check: -> { generation_inputs_stable? },
      source_records: @generation_inputs
    ).commit
    @generation_statuses.each { |message| report_status(message) }
  end
  0
end

#generation_artifactsArtifactSet

RBS:

  • () -> ArtifactSet

Returns:



90
91
92
# File 'lib/ibex/cli/generation_artifacts.rb', line 90

def generation_artifacts
  @generation_artifacts || raise(Ibex::Error, "(generation):1:1: artifact collection is not active")
end

#generation_inputs_stable?Boolean

RBS:

  • () -> bool

Returns:

  • (Boolean)


95
96
97
# File 'lib/ibex/cli/generation_artifacts.rb', line 95

def generation_inputs_stable?
  @generation_inputs.all?(&:current?)
end

#generation_manifest_optionsHash[String, Object?]

RBS:

  • () -> Hash[String, Object?]

Returns:

  • (Hash[String, Object?])


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/ibex/cli/generation_artifacts.rb', line 127

def generation_manifest_options
  keys = %i[
    action_source algorithm counterexample_max_configurations counterexample_max_tokens debug
    embedded emit entry_isolation executable frozen line_convert line_convert_all messages mode omit_actions rbs
    superclass table
  ]
  options = {} #: Hash[String, Object?]
  keys.each do |key|
    value = @options[key]
    options[key.to_s] = value unless value.nil?
  end
  options["cst_trivia"] = effective_cst_trivia.to_s
  append_ir_manifest_options(options)
  options
end

#manifest_effective_configurationArray[Hash[String, Object?]]

RBS:

  • () -> Array[Hash[String, Object?]]

Returns:

  • (Array[Hash[String, Object?]])


170
171
172
173
174
175
# File 'lib/ibex/cli/generation_artifacts.rb', line 170

def manifest_effective_configuration
  values = effective_configuration.to_h.fetch("configuration")
  return values unless @options[:from] == "automaton-ir"

  values.reject { |entry| %w[parser.algorithm parser.entries].include?(entry.fetch("key")) }
end

#manifest_output_pathString

RBS:

  • () -> String

Returns:

  • (String)


116
117
118
119
120
121
122
123
124
# File 'lib/ibex/cli/generation_artifacts.rb', line 116

def manifest_output_path
  configured = @options[:manifest]
  return configured if configured.is_a?(String) && !configured.empty?

  parser = generation_artifacts.find { |artifact| artifact.kind == :parser }
  raise Ibex::Error, "(generation):1:1: generation manifest requires a parser artifact" unless parser

  default_output_path(parser.path, ".ibex.json")
end

#record_generation_input(path, source) ⇒ GenerationInput

RBS:

  • (String path, String source) -> GenerationInput

Parameters:

  • path (String)
  • source (String)

Returns:



107
108
109
110
111
112
113
# File 'lib/ibex/cli/generation_artifacts.rb', line 107

def record_generation_input(path, source)
  input = GenerationInput.new(path, source)
  @generation_inputs.reject! { |entry| entry.path == input.path }
  @generation_inputs << input
  @generation_sources = @generation_inputs.map(&:path)
  input
end

#register_artifact(kind, path, content, mode: nil, status: false) ⇒ Artifact

RBS:

  • (Symbol kind, String path, String content, ?mode: Integer?, ?status: bool) -> Artifact

Parameters:

  • kind (Symbol)
  • path (String)
  • content (String)
  • mode: (Integer, nil) (defaults to: nil)
  • status: (Boolean) (defaults to: false)

Returns:



30
31
32
33
34
# File 'lib/ibex/cli/generation_artifacts.rb', line 30

def register_artifact(kind, path, content, mode: nil, status: false)
  artifact = generation_artifacts.add(kind: kind, path: path, content: content, mode: mode)
  @generation_statuses << "wrote #{path}" if status
  artifact
end

#stringify_contract(contract) ⇒ Hash[String, Object?]

RBS:

  • (IR::ParserContract contract) -> Hash[String, Object?]

Parameters:

Returns:

  • (Hash[String, Object?])


178
179
180
181
182
# File 'lib/ibex/cli/generation_artifacts.rb', line 178

def stringify_contract(contract)
  contract.to_h.to_h do |name, entry|
    [name.to_s, entry.to_h { |key, value| [key.to_s, value] }]
  end
end

#verify_artifact_generationvoid

This method returns an undefined value.

RBS:

  • () -> void



71
72
73
74
75
76
77
# File 'lib/ibex/cli/generation_artifacts.rb', line 71

def verify_artifact_generation
  generation_artifacts.each do |artifact|
    verify_file(artifact.path, artifact.content, artifact_label(artifact.kind))
  end
  parser = generation_artifacts.find { |artifact| artifact.kind == :parser }
  report_status("verified #{parser.path}") if parser
end