Class: InlineFormsSchemaEdit::BatchImport
- Inherits:
-
Object
- Object
- InlineFormsSchemaEdit::BatchImport
- Defined in:
- lib/inline_forms_schema_edit/batch_import.rb
Overview
The import/replay half of the pipeline (phase 2): takes an exported batch payload and materializes it into the CURRENT checkout — validates every intent against this checkout's models, then replays them in order through InlineForms::SchemaApply#generate! (+ SchemaLabel for labels).
Deliberately does NOT migrate and does NOT commit: it only writes model edits + migration files and reports what it did, so the same class serves a developer replaying by hand and CI replaying automatically (CI's job then runs the test gate, commits, builds).
Defined Under Namespace
Classes: ImportError, Result
Instance Attribute Summary collapse
-
#payload ⇒ Object
readonly
Returns the value of attribute payload.
Class Method Summary collapse
Instance Method Summary collapse
-
#apply!(destination_root: Rails.root) ⇒ Object
Replay all intents into destination_root.
-
#initialize(payload, executor: nil, label_writer: nil) ⇒ BatchImport
constructor
Injectable for tests: executor replaces the addto generator run, label_writer replaces SchemaLabel.write.
-
#verify! ⇒ Object
Verify structure + digest + per-intent validity against this checkout.
Constructor Details
#initialize(payload, executor: nil, label_writer: nil) ⇒ BatchImport
Injectable for tests: executor replaces the addto generator run, label_writer replaces SchemaLabel.write.
25 26 27 28 29 30 31 |
# File 'lib/inline_forms_schema_edit/batch_import.rb', line 25 def initialize(payload, executor: nil, label_writer: nil) @payload = payload.is_a?(String) ? JSON.parse(payload) : payload @executor = executor @label_writer = label_writer || InlineForms::SchemaLabel.method(:write) rescue JSON::ParserError => e raise ImportError, "not valid JSON: #{e.}" end |
Instance Attribute Details
#payload ⇒ Object (readonly)
Returns the value of attribute payload.
21 22 23 |
# File 'lib/inline_forms_schema_edit/batch_import.rb', line 21 def payload @payload end |
Class Method Details
.from_file(path, **kwargs) ⇒ Object
33 34 35 |
# File 'lib/inline_forms_schema_edit/batch_import.rb', line 33 def self.from_file(path, **kwargs) new(File.read(path), **kwargs) end |
Instance Method Details
#apply!(destination_root: Rails.root) ⇒ Object
Replay all intents into destination_root. Stops at the first failure (raises), leaving earlier generated files in place for inspection — the caller (CI) works on a clean tree it can reset.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/inline_forms_schema_edit/batch_import.rb', line 62 def apply!(destination_root: Rails.root) intents = verify! migrations = [] labels = [] plan = [] intents.each do |intent_hash| intent = build_intent(intent_hash) apply = InlineForms::SchemaApply.new(intent) plan.concat(apply.preview_plan) migration = apply.generate!( destination_root: destination_root, executor: @executor || InlineForms::SchemaApply::DEFAULT_GENERATE_EXECUTOR ) migrations << migration if migration if intent_hash["label"].present? labels << @label_writer.call( destination_root: destination_root, model_class: intent.model_class, attribute: intent.attribute, label: intent_hash["label"], locale: intent_hash["locale"].presence || I18n.default_locale.to_s ) end end Result.new(applied: intents.size, migrations: migrations, labels: labels, plan: plan) end |
#verify! ⇒ Object
Verify structure + digest + per-intent validity against this checkout. Returns the intents array (raises ImportError on any problem).
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/inline_forms_schema_edit/batch_import.rb', line 39 def verify! raise ImportError, "unsupported format #{payload['format'].inspect}" unless payload["format"] == BatchExport::FORMAT intents = payload["intents"] raise ImportError, "batch has no intents" if intents.blank? canonical = JSON.generate(intents) digest = "sha256:#{Digest::SHA256.hexdigest(canonical)}" unless digest == payload["digest"] raise ImportError, "digest mismatch: payload says #{payload['digest'].inspect}, content is #{digest.inspect} — batch changed after submit?" end intents.each_with_index do |intent, i| error = IntentValidator.error_for(intent) raise ImportError, "intent ##{i + 1} (#{intent['model_name']}##{intent['attribute']}): #{error}" if error end intents end |