hecks 2.8.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/hecks +50 -7
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +32 -100
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +10 -32
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +149 -136
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +48 -38
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +76 -62
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +32 -142
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bench/cli.rb +62 -0
- data/lib/hecks/bench/environment.rb +71 -0
- data/lib/hecks/bench/postgres_probe.rb +30 -0
- data/lib/hecks/bench/report.rb +76 -0
- data/lib/hecks/bench/ruby_runner.rb +93 -0
- data/lib/hecks/bench/run.rb +55 -0
- data/lib/hecks/bench/rust_runner.rb +101 -0
- data/lib/hecks/bench/stats.rb +46 -0
- data/lib/hecks/bench/suite.rb +98 -0
- data/lib/hecks/bench/workload.rb +89 -0
- data/lib/hecks/bench.rb +17 -0
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +56 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +39 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +11 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +16 -50
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +49 -67
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +96 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +42 -89
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +148 -197
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +38 -43
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +46 -111
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +39 -661
- data/lib/hecks/bluebook/hexagon.rb +18 -33
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +87 -352
- data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
- data/lib/hecks/bluebook/model_check.rb +122 -596
- data/lib/hecks/bluebook/pattern_subset.rb +49 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +27 -51
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +9 -99
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +4 -23
- data/lib/hecks/canonical_json.rb +30 -0
- data/lib/hecks/chapters.rb +102 -0
- data/lib/hecks/cli/behaviors.rb +61 -0
- data/lib/hecks/cli/canonicalise.rb +25 -0
- data/lib/hecks/cli/check_engine_agreement.rb +32 -0
- data/lib/hecks/cli/check_era.rb +88 -0
- data/lib/hecks/cli/console.rb +66 -0
- data/lib/hecks/cli/deploy_template_diff.rb +40 -0
- data/lib/hecks/cli/doc_coverage.rb +32 -0
- data/lib/hecks/cli/document.rb +5 -23
- data/lib/hecks/cli/expression_projection.rb +41 -0
- data/lib/hecks/cli/follow.rb +88 -0
- data/lib/hecks/cli/history.rb +44 -0
- data/lib/hecks/cli/ir.rb +4 -6
- data/lib/hecks/cli/mcp.rb +5 -6
- data/lib/hecks/cli/model_check.rb +24 -88
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +223 -64
- data/lib/hecks/cli/project_diagrams.rb +4 -10
- data/lib/hecks/cli/project_glossary.rb +44 -0
- data/lib/hecks/cli/reference.rb +46 -0
- data/lib/hecks/cli/refresh_projections.rb +44 -0
- data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
- data/lib/hecks/cli/release.rb +70 -0
- data/lib/hecks/cli/release_gem.rb +59 -0
- data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
- data/lib/hecks/cli/rspec_shard_files.rb +66 -0
- data/lib/hecks/cli/run.rb +15 -61
- data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
- data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
- data/lib/hecks/cli/shape.rb +70 -0
- data/lib/hecks/cli/smoke_http.rb +230 -0
- data/lib/hecks/cli/smoke_test.rb +7 -19
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -6
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +216 -73
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
- data/lib/hecks/deploy/oidc.json +82 -2
- data/lib/hecks/doc/reference.rb +351 -0
- data/lib/hecks/doors/cli_door.rb +196 -0
- data/lib/hecks/doors/cli_runner.rb +297 -0
- data/lib/hecks/{facade → doors}/command_request.rb +14 -34
- data/lib/hecks/doors/handle.rb +206 -0
- data/lib/hecks/doors/json_door.rb +132 -0
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
- data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
- data/lib/hecks/doors/ruby_door.rb +77 -0
- data/lib/hecks/doors.rb +61 -0
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +5 -72
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +23 -51
- data/lib/hecks/forms/app.rb +21 -76
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +31 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
- data/lib/hecks/fuzzing/combination_miner.rb +86 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
- data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
- data/lib/hecks/fuzzing/differential.rb +156 -0
- data/lib/hecks/fuzzing/domain_generator.rb +615 -0
- data/lib/hecks/fuzzing/era_boundary.rb +71 -0
- data/lib/hecks/fuzzing/form_census.rb +136 -0
- data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
- data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
- data/lib/hecks/fuzzing/outside_world.rb +45 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
- data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
- data/lib/hecks/fuzzing/properties/guards.rb +190 -0
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
- data/lib/hecks/fuzzing/properties/querying.rb +175 -0
- data/lib/hecks/fuzzing/properties.rb +162 -0
- data/lib/hecks/fuzzing/qa_settings.rb +123 -0
- data/lib/hecks/fuzzing/replay.rb +505 -0
- data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
- data/lib/hecks/fuzzing/self_consistency.rb +339 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
- data/lib/hecks/fuzzing/shrinker.rb +166 -0
- data/lib/hecks/fuzzing/structural_skips.rb +33 -0
- data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
- data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
- data/lib/hecks/fuzzing/value_generator.rb +216 -0
- data/lib/hecks/fuzzing.rb +23 -0
- data/lib/hecks/grammar/evolve.rb +336 -0
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
- data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
- data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
- data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
- data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
- data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
- data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
- data/lib/hecks/hecks/adapters/git.adapter +7 -0
- data/lib/hecks/hecks/adapters/git.rb +102 -0
- data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
- data/lib/hecks/hecks/adapters/host_http.rb +65 -0
- data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
- data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
- data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
- data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
- data/lib/hecks/hecks/adapters/local_files.rb +46 -0
- data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
- data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
- data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
- data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
- data/lib/hecks/hecks/adapters/shell.adapter +7 -0
- data/lib/hecks/hecks/adapters/shell.rb +49 -0
- data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
- data/lib/hecks/hecks/adapters/terminal.rb +74 -0
- data/lib/hecks/hecks/codebase.behaviors +172 -0
- data/lib/hecks/hecks/codebase.bluebook +2453 -0
- data/lib/hecks/hecks/context_map.hecksagon +13 -0
- data/lib/hecks/hecks/custodian.behaviors +179 -0
- data/lib/hecks/hecks/custodian.bluebook +1847 -0
- data/lib/hecks/hecks/deploy.behaviors +74 -0
- data/lib/hecks/hecks/deploy.world +12 -0
- data/lib/hecks/hecks/environments/memory.world +10 -0
- data/lib/hecks/hecks/governance.world +7 -0
- data/lib/hecks/hecks/hecks.behaviors +62 -0
- data/lib/hecks/hecks/hecks.bluebook +124 -0
- data/lib/hecks/hecks/hecks.hecksagon +390 -0
- data/lib/hecks/hecks/hecks.world +42 -0
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/kernel_capabilities.rb +194 -0
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +26 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +19 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +83 -198
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +61 -64
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +44 -144
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +19 -76
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +43 -127
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +50 -47
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +47 -108
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +12 -44
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +40 -207
- data/lib/hecks/projections/deploy/lambda.rb +191 -708
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +3 -59
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +48 -147
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +22 -584
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +16 -43
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +13 -32
- data/lib/hecks/projections/reference.rb +4 -18
- data/lib/hecks/projections/rust_vocabulary.rb +13 -251
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +154 -400
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +42 -134
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
- data/lib/hecks/quality_control/adapters/agent.rb +58 -0
- data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
- data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
- data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
- data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
- data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
- data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
- data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
- data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
- data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
- data/lib/hecks/quality_control/cli/child.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
- data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
- data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
- data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
- data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
- data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
- data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
- data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
- data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
- data/lib/hecks/query_ir.rb +346 -0
- data/lib/hecks/query_ir_mcp.rb +198 -0
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +5 -8
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +15 -9
- data/lib/hecks/release/runner/npm_publisher.rb +9 -53
- data/lib/hecks/release/runner/preflight.rb +29 -20
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +31 -23
- data/lib/hecks/release/runner.rb +60 -38
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +15 -39
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +27 -160
- data/lib/hecks/runtime/command_interpreter.rb +124 -306
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +50 -104
- data/lib/hecks/runtime/dispatcher.rb +134 -243
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +64 -219
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +14 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +109 -194
- data/lib/hecks/runtime/outbox.rb +39 -262
- data/lib/hecks/runtime/policy_interpreter.rb +43 -202
- data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
- data/lib/hecks/runtime/query_interpreter.rb +122 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +28 -87
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +213 -227
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +156 -247
- data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +162 -760
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +15 -84
- data/lib/hecks/runtime.rb +35 -69
- data/lib/hecks/rust_build/conformance.rb +158 -0
- data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
- data/lib/hecks/rust_build/coverage.rb +218 -0
- data/lib/hecks/rust_build/native_build.rb +124 -0
- data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
- data/lib/hecks/rust_build/project_rust.rb +332 -0
- data/lib/hecks/rust_build/wasm.rb +105 -0
- data/lib/hecks/rust_build/wasm_browser.rb +113 -0
- data/lib/hecks/rust_build.rb +144 -0
- data/lib/hecks/storehouse.rb +155 -582
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/three_zero/forms.yml +127 -0
- data/lib/hecks/three_zero.rb +12 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
- data/lib/hecks/tools/comment_style.rb +1070 -0
- data/lib/hecks/tools/corpus_report.rb +87 -0
- data/lib/hecks/tools/deploy_recipe.rb +255 -0
- data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
- data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
- data/lib/hecks/tools/era_projection_backfill.rb +94 -0
- data/lib/hecks/tools/era_reattest.rb +146 -0
- data/lib/hecks/tools/evolve_run.rb +189 -0
- data/lib/hecks/tools/fuzz_sweep.rb +373 -0
- data/lib/hecks/tools/heki_compaction.rb +100 -0
- data/lib/hecks/tools/hoist_local_givens.rb +246 -0
- data/lib/hecks/tools/journal_compaction.rb +89 -0
- data/lib/hecks/tools/oidc_manifests.rb +70 -0
- data/lib/hecks/tools/query_ir_run.rb +81 -0
- data/lib/hecks/tools/regeneration_run.rb +166 -0
- data/lib/hecks/tools/rust_comment_style.rb +642 -0
- data/lib/hecks/tools/sequence_script.rb +62 -0
- data/lib/hecks/tools/tail_merge.rb +117 -0
- data/lib/hecks/tools/tenant_provisioning.rb +142 -0
- data/lib/hecks/tools/translation_audit.rb +208 -0
- data/lib/hecks/tools/translation_scaffold.rb +131 -0
- data/lib/hecks/tools.rb +86 -0
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks.rb +52 -90
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- data/qa/settings.yml +66 -0
- data/rust/.cargo/config.toml +6 -0
- data/rust/.gitignore +2 -0
- data/rust/Cargo.lock +54 -0
- data/rust/Cargo.toml +61 -0
- data/rust/build/.cargo/config.toml +3 -0
- data/rust/build/.gitignore +1 -0
- data/rust/build/Cargo.lock +7 -0
- data/rust/build/Cargo.toml +19 -0
- data/rust/build/src/build_artifact.rs +47 -0
- data/rust/build/src/cargo_sync.rs +248 -0
- data/rust/build/src/json.rs +421 -0
- data/rust/build/src/lineage_pass.rs +285 -0
- data/rust/build/src/main.rs +51 -0
- data/rust/build/src/optional_pass.rs +150 -0
- data/rust/build/src/pipeline.rs +264 -0
- data/rust/build/src/reserved_names.rs +76 -0
- data/rust/build/src/resolve.rs +124 -0
- data/rust/build/src/root.rs +25 -0
- data/rust/build/src/sidecars.rs +73 -0
- data/rust/build/src/subprocess.rs +51 -0
- data/rust/build/src/tmp.rs +31 -0
- data/rust/codegen/.cargo/config.toml +3 -0
- data/rust/codegen/.gitignore +1 -0
- data/rust/codegen/Cargo.lock +7 -0
- data/rust/codegen/Cargo.toml +20 -0
- data/rust/codegen/src/attr.rs +32 -0
- data/rust/codegen/src/bridging.rs +481 -0
- data/rust/codegen/src/commands.rs +1226 -0
- data/rust/codegen/src/constraints.rs +109 -0
- data/rust/codegen/src/dependency_planning.rs +209 -0
- data/rust/codegen/src/domain_generator.rs +1288 -0
- data/rust/codegen/src/exemplar.rs +230 -0
- data/rust/codegen/src/expr_emitter.rs +87 -0
- data/rust/codegen/src/fielded.rs +192 -0
- data/rust/codegen/src/hecks_naming.rs +33 -0
- data/rust/codegen/src/json.rs +335 -0
- data/rust/codegen/src/json_codec.rs +697 -0
- data/rust/codegen/src/literal.rs +207 -0
- data/rust/codegen/src/main.rs +290 -0
- data/rust/codegen/src/manifest.rs +227 -0
- data/rust/codegen/src/mutations.rs +784 -0
- data/rust/codegen/src/naming.rs +286 -0
- data/rust/codegen/src/ports.rs +208 -0
- data/rust/codegen/src/prelude.rs +116 -0
- data/rust/codegen/src/queries.rs +786 -0
- data/rust/codegen/src/reactions.rs +532 -0
- data/rust/codegen/src/read_models.rs +697 -0
- data/rust/codegen/src/reference_specs.rs +40 -0
- data/rust/codegen/src/registry.rs +966 -0
- data/rust/codegen/src/reserved_names.rs +76 -0
- data/rust/codegen/src/shared.rs +93 -0
- data/rust/codegen/src/skip_reason.rs +25 -0
- data/rust/codegen/src/types.rs +362 -0
- data/rust/host/.cargo/config.toml +3 -0
- data/rust/host/.gitignore +1 -0
- data/rust/host/Cargo.lock +4297 -0
- data/rust/host/Cargo.toml +61 -0
- data/rust/host/HECKS_RELEASE +1 -0
- data/rust/host/rds-ca-bundle.pem +2736 -0
- data/rust/host/src/api.rs +1596 -0
- data/rust/host/src/approval.rs +652 -0
- data/rust/host/src/auth.rs +1287 -0
- data/rust/host/src/bin/expr_harness.rs +46 -0
- data/rust/host/src/bin/lineage_harness.rs +119 -0
- data/rust/host/src/bin/mint_harness.rs +135 -0
- data/rust/host/src/checkout.rs +265 -0
- data/rust/host/src/dispatch.rs +1443 -0
- data/rust/host/src/expr_json.rs +1117 -0
- data/rust/host/src/field_hints.rs +52 -0
- data/rust/host/src/ir.rs +733 -0
- data/rust/host/src/journal.rs +874 -0
- data/rust/host/src/lambda_client.rs +378 -0
- data/rust/host/src/log.rs +147 -0
- data/rust/host/src/main.rs +474 -0
- data/rust/host/src/mint.rs +1865 -0
- data/rust/host/src/payments/keystore.rs +330 -0
- data/rust/host/src/payments/tests.rs +1400 -0
- data/rust/host/src/payments.rs +767 -0
- data/rust/host/src/presentation.rs +698 -0
- data/rust/host/src/presentation_write.rs +1431 -0
- data/rust/host/src/query_step.rs +149 -0
- data/rust/host/src/rate_limit.rs +904 -0
- data/rust/host/src/reference_transform.rs +241 -0
- data/rust/host/src/reference_validate.rs +338 -0
- data/rust/host/src/resend.rs +296 -0
- data/rust/host/src/secrets.rs +106 -0
- data/rust/host/src/server.rs +663 -0
- data/rust/host/src/storage_shape.rs +175 -0
- data/rust/host/src/test_pg.rs +40 -0
- data/rust/host/src/ui_schema.rs +1351 -0
- data/rust/host/src/wasm_runner.rs +191 -0
- data/rust/host/src/web/newsletter/cooldown.rs +126 -0
- data/rust/host/src/web/newsletter/tests.rs +104 -0
- data/rust/host/src/web/newsletter.rs +310 -0
- data/rust/host/src/web/newsletter_send.rs +357 -0
- data/rust/host/src/web/registrations.rs +1505 -0
- data/rust/host/src/web.rs +2937 -0
- data/rust/lsp/.gitignore +1 -0
- data/rust/lsp/Cargo.lock +7 -0
- data/rust/lsp/Cargo.toml +16 -0
- data/rust/lsp/README.md +133 -0
- data/rust/lsp/src/diagnostics.rs +165 -0
- data/rust/lsp/src/json.rs +385 -0
- data/rust/lsp/src/main.rs +399 -0
- data/rust/lsp/src/outline.rs +177 -0
- data/rust/lsp/src/rpc.rs +67 -0
- data/rust/parser/.cargo/config.toml +5 -0
- data/rust/parser/.gitignore +1 -0
- data/rust/parser/Cargo.lock +7 -0
- data/rust/parser/Cargo.toml +21 -0
- data/rust/parser/src/build/closed_sets.rs +27 -0
- data/rust/parser/src/build/identity.rs +276 -0
- data/rust/parser/src/build/mod.rs +12 -0
- data/rust/parser/src/build/naming.rs +141 -0
- data/rust/parser/src/build/pattern_subset.rs +161 -0
- data/rust/parser/src/build/query_derive.rs +72 -0
- data/rust/parser/src/build/query_inference.rs +269 -0
- data/rust/parser/src/build/query_options.rs +100 -0
- data/rust/parser/src/build/read_model.rs +94 -0
- data/rust/parser/src/build/references.rs +32 -0
- data/rust/parser/src/canonical.rs +114 -0
- data/rust/parser/src/diag.rs +55 -0
- data/rust/parser/src/emit.rs +953 -0
- data/rust/parser/src/expr/ast_json.rs +147 -0
- data/rust/parser/src/expr/evaluator.rs +81 -0
- data/rust/parser/src/expr/mod.rs +84 -0
- data/rust/parser/src/expr/resolver.rs +497 -0
- data/rust/parser/src/ir.rs +387 -0
- data/rust/parser/src/keywords.rs +585 -0
- data/rust/parser/src/lex.rs +662 -0
- data/rust/parser/src/main.rs +252 -0
- data/rust/parser/src/parse/aggregate.rs +612 -0
- data/rust/parser/src/parse/chapter.rs +517 -0
- data/rust/parser/src/parse/command.rs +637 -0
- data/rust/parser/src/parse/domain_port.rs +127 -0
- data/rust/parser/src/parse/entity.rs +527 -0
- data/rust/parser/src/parse/file.rs +67 -0
- data/rust/parser/src/parse/hecksagon.rs +231 -0
- data/rust/parser/src/parse/lifecycle.rs +162 -0
- data/rust/parser/src/parse/mod.rs +1262 -0
- data/rust/parser/src/parse/policy.rs +87 -0
- data/rust/parser/src/parse/process_manager.rs +305 -0
- data/rust/parser/src/parse/query.rs +100 -0
- data/rust/parser/src/parse/read_model.rs +214 -0
- data/rust/parser/src/parse/value_object.rs +250 -0
- data/rust/parser/src/ruby_value.rs +422 -0
- data/rust/project/bridging.rb +257 -0
- data/rust/project/commands.rb +877 -0
- data/rust/project/constraints.rb +86 -0
- data/rust/project/dependency_planning.rb +178 -0
- data/rust/project/domain_generator.rb +980 -0
- data/rust/project/exemplar.rb +148 -0
- data/rust/project/expr_emitter.rb +72 -0
- data/rust/project/fielded.rb +141 -0
- data/rust/project/json_codec.rb +641 -0
- data/rust/project/mutations.rb +721 -0
- data/rust/project/naming.rb +205 -0
- data/rust/project/ports.rb +65 -0
- data/rust/project/queries.rb +493 -0
- data/rust/project/reactions.rb +317 -0
- data/rust/project/read_models.rb +690 -0
- data/rust/project/reference_specs.rb +27 -0
- data/rust/project/registry.rb +396 -0
- data/rust/project/skip_reason.rb +29 -0
- data/rust/project/types.rb +225 -0
- data/rust/project/write_if_changed.rb +83 -0
- data/rust/project.rb +30 -0
- data/rust/project_rust_pipeline.rb +383 -0
- data/rust/src/exemplar/commands.rs +279 -0
- data/rust/src/exemplar/constraints.rs +18 -0
- data/rust/src/exemplar/fielded.rs +280 -0
- data/rust/src/exemplar/json.rs +277 -0
- data/rust/src/exemplar/mod.rs +17 -0
- data/rust/src/exemplar/mutations.rs +80 -0
- data/rust/src/exemplar/queries.rs +33 -0
- data/rust/src/exemplar/reactions.rs +88 -0
- data/rust/src/exemplar/read_models.rs +48 -0
- data/rust/src/exemplar/registry.rs +166 -0
- data/rust/src/exemplar/types.rs +44 -0
- data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
- data/rust/src/kernel/attribute_shapes/list.rs +18 -0
- data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
- data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
- data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
- data/rust/src/kernel/cli.rs +585 -0
- data/rust/src/kernel/dispatch.rs +1090 -0
- data/rust/src/kernel/expr.rs +458 -0
- data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
- data/rust/src/kernel/expression_operators/comparison.rs +48 -0
- data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
- data/rust/src/kernel/expression_operators/logical.rs +13 -0
- data/rust/src/kernel/expression_operators/membership.rs +18 -0
- data/rust/src/kernel/expression_operators/mod.rs +68 -0
- data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
- data/rust/src/kernel/expression_operators/positional.rs +126 -0
- data/rust/src/kernel/expression_operators/presence.rs +101 -0
- data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
- data/rust/src/kernel/expression_operators/sized.rs +35 -0
- data/rust/src/kernel/expression_operators/text.rs +79 -0
- data/rust/src/kernel/expression_operators/to_string.rs +18 -0
- data/rust/src/kernel/json.rs +779 -0
- data/rust/src/kernel/mod.rs +133 -0
- data/rust/src/kernel/named_query.rs +219 -0
- data/rust/src/kernel/orchestrate.rs +1810 -0
- data/rust/src/kernel/pattern.rs +307 -0
- data/rust/src/kernel/query_comparators.rs +206 -0
- data/rust/src/kernel/query_ordering.rs +103 -0
- data/rust/src/kernel/read_model.rs +914 -0
- data/rust/src/kernel/reference_lookup.rs +149 -0
- data/rust/src/kernel/repository.rs +468 -0
- data/rust/src/kernel/routing.rs +612 -0
- data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
- data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
- data/rust/src/kernel/vocab/field_hint.rs +70 -0
- data/rust/src/kernel/vocab/mod.rs +20 -0
- data/rust/src/kernel/vocab/query_comparator.rs +65 -0
- data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
- data/rust/src/lib.rs +8 -0
- data/rust/src/main.rs +16 -0
- data/rust/web/.gitignore +1 -0
- data/rust/web/Cargo.lock +119 -0
- data/rust/web/Cargo.toml +18 -0
- data/rust/web/src/lib.rs +8 -0
- metadata +478 -12
- data/lib/hecks/facade/cli_door.rb +0 -178
- data/lib/hecks/facade/cli_runner.rb +0 -271
- data/lib/hecks/facade/handle.rb +0 -293
- data/lib/hecks/facade/json_door.rb +0 -247
- data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
- data/lib/hecks/facade/surface/chapter.rb +0 -116
- data/lib/hecks/facade/surface.rb +0 -61
- data/lib/hecks/mcp_door_scope.rb +0 -176
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hecks/corpus"
|
|
4
|
+
require "hecks/query_ir"
|
|
5
|
+
require "hecks/query_ir_mcp"
|
|
6
|
+
require_relative "tree"
|
|
7
|
+
require "hecks/rust_build"
|
|
8
|
+
require_relative "../console_capture"
|
|
9
|
+
|
|
10
|
+
module Hecks
|
|
11
|
+
module Adapters
|
|
12
|
+
module Codebase
|
|
13
|
+
# What Codebase's `CorpusRun` asks of the working tree: which committed domains have a Rust
|
|
14
|
+
# feature, what the language's IR holds, and the two doors that serve it.
|
|
15
|
+
#
|
|
16
|
+
# The questions are pure reads and run in this process, with the code `hecks rust_domains` and
|
|
17
|
+
# `hecks ir_constructs` run (`Hecks::Corpus`, `Hecks::QueryIR`); the coverage question runs
|
|
18
|
+
# `Hecks::RustBuild`'s coverage tool over each generated module, also in this process. The
|
|
19
|
+
# two doors run until they are closed: the query MCP server on stdio, and the forms app on a
|
|
20
|
+
# local port.
|
|
21
|
+
module CorpusTasks
|
|
22
|
+
# Every operation this family carries out.
|
|
23
|
+
OPERATIONS = %w[serve_query_ir_mcp present].freeze
|
|
24
|
+
|
|
25
|
+
# The port `present` listens on when none is named.
|
|
26
|
+
DEFAULT_PORT = 4567
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
# @return [#call, nil] serves the MCP door; `Hecks::QueryIrMcp.start` when nil. A spec
|
|
30
|
+
# replaces it so no stdio has to be held.
|
|
31
|
+
attr_accessor :mcp_server
|
|
32
|
+
|
|
33
|
+
# @return [#call, nil] takes `app:` and `port:` and serves until stopped; a WEBrick
|
|
34
|
+
# server through Rack when nil.
|
|
35
|
+
attr_accessor :web_server
|
|
36
|
+
|
|
37
|
+
# @return [#capture, nil] runs each coverage check, as `capture(tool, argv, env:)`
|
|
38
|
+
# answering an object with `out`, `err` and `ok?`; `Hecks::RustBuild` when nil.
|
|
39
|
+
attr_accessor :coverage_runner
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module_function
|
|
43
|
+
|
|
44
|
+
# Opens one of the doors.
|
|
45
|
+
#
|
|
46
|
+
# @param operation [String] `serve_query_ir_mcp` or `present`
|
|
47
|
+
# @param held [Hash] the `CorpusRun` record's fields: `port`
|
|
48
|
+
# @param tree [Tree] the working tree, already known to be a hecks checkout
|
|
49
|
+
# @param shell [#capture, nil] unused
|
|
50
|
+
# @return [String] a note that the door closed
|
|
51
|
+
# @raise [ConsoleCapture::Failure] when the MCP door refuses the process's setup
|
|
52
|
+
def call(operation, held, tree, shell: nil)
|
|
53
|
+
_ = shell
|
|
54
|
+
return serve_mcp if operation == "serve_query_ir_mcp"
|
|
55
|
+
|
|
56
|
+
present(plain(held)[:port] || DEFAULT_PORT, tree)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# A pure read.
|
|
60
|
+
#
|
|
61
|
+
# @param operation [String] a query's name in snake case
|
|
62
|
+
# @param args [Hash] the query's plain arguments
|
|
63
|
+
# @param tree [Tree] the checkout
|
|
64
|
+
# @param shell [#capture, nil] unused; the coverage checks run in this process
|
|
65
|
+
# @return [String] the answer, one line for each row
|
|
66
|
+
# @raise [ConsoleCapture::Failure] when a coverage check fails, or a query is refused
|
|
67
|
+
def report(operation, args, tree, shell: nil)
|
|
68
|
+
_ = shell
|
|
69
|
+
case operation
|
|
70
|
+
when "rust_domains" then rust_domains(tree)
|
|
71
|
+
when "regen_order" then regen_order(tree)
|
|
72
|
+
when "corpus_rust_coverage" then coverage(tree)
|
|
73
|
+
else ir_query(operation, args)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @param held [Hash] fields, each perhaps a value object's `{ value: x }`
|
|
78
|
+
# @return [Hash] the same fields as plain values
|
|
79
|
+
def plain(held) = held.transform_values { |value| value.is_a?(Hash) ? value[:value] : value }
|
|
80
|
+
|
|
81
|
+
# @return [String] a note that the MCP door closed
|
|
82
|
+
# @raise [ConsoleCapture::Failure] when the door refuses to start
|
|
83
|
+
def serve_mcp
|
|
84
|
+
server = CorpusTasks.mcp_server || ->(**options) { QueryIrMcp.start(**options) }
|
|
85
|
+
server.call(argv: [])
|
|
86
|
+
"query ir mcp door closed"
|
|
87
|
+
rescue SystemExit => e
|
|
88
|
+
raise ConsoleCapture::Failure, "the query ir mcp door refused to start (status #{e.status}); see stderr"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @param port [Integer] the port to listen on
|
|
92
|
+
# @param tree [Tree] the checkout
|
|
93
|
+
# @return [String] a note that the server stopped
|
|
94
|
+
def present(port, tree)
|
|
95
|
+
require "hecks/forms/banking_presentation"
|
|
96
|
+
app = Forms::BankingPresentation.app(root: tree.root)
|
|
97
|
+
warn "banking forms, in memory, on http://localhost:#{port}/ - no authentication, no CSRF " \
|
|
98
|
+
"protection, no caller identity; do not expose beyond localhost"
|
|
99
|
+
(CorpusTasks.web_server || method(:rack_serve)).call(app: app, port: port)
|
|
100
|
+
"presented on port #{port}, now stopped"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @param app [#call] the Rack app
|
|
104
|
+
# @param port [Integer] the port
|
|
105
|
+
# @return [void]
|
|
106
|
+
def rack_serve(app:, port:)
|
|
107
|
+
require "rackup"
|
|
108
|
+
Rackup::Server.start(app: app, Port: port, server: "webrick")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @param tree [Tree] the checkout
|
|
112
|
+
# @return [String] each domain with a Rust feature: its feature, a tab, and its directory
|
|
113
|
+
def rust_domains(tree)
|
|
114
|
+
Corpus.rust_domains(root: tree.root).map { |domain| "#{domain.feature}\t#{tree.relative(domain.dir)}" }
|
|
115
|
+
.join("\n")
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @param tree [Tree] the checkout
|
|
119
|
+
# @return [String] the directories regeneration walks, in order, one for each line
|
|
120
|
+
def regen_order(tree)
|
|
121
|
+
Corpus.rust_regen_order(root: tree.root).map { |domain| tree.relative(domain.dir) }.join("\n")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Runs the coverage tool over every generated module. A module named in
|
|
125
|
+
# `Corpus::RUST_COVERAGE_PENDING` must still fail; every other one must pass.
|
|
126
|
+
#
|
|
127
|
+
# @param tree [Tree] the checkout
|
|
128
|
+
# @return [String] one line for each module, and how many were checked
|
|
129
|
+
# @raise [ConsoleCapture::Failure] with every module that failed, or that passes now while
|
|
130
|
+
# still listed as pending
|
|
131
|
+
def coverage(tree)
|
|
132
|
+
modules = Corpus.generated_modules(root: tree.root)
|
|
133
|
+
pending = Corpus::RUST_COVERAGE_PENDING
|
|
134
|
+
unknown = pending.keys - modules
|
|
135
|
+
raise ConsoleCapture::Failure, "pending names #{unknown.join(', ')}, with no generated module" if unknown.any?
|
|
136
|
+
|
|
137
|
+
lines, problems = judge(modules, pending, coverage_results(modules, tree))
|
|
138
|
+
raise ConsoleCapture::Failure, [*lines, "", *problems].join("\n") if problems.any?
|
|
139
|
+
|
|
140
|
+
[*lines, "#{modules.size} generated modules checked"].join("\n")
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @param modules [Array<String>] the generated modules
|
|
144
|
+
# @param pending [Hash{String => String}] the modules known to fail, and why
|
|
145
|
+
# @param results [Hash{String => Array}] each module's `[passed, output]`
|
|
146
|
+
# @return [Array(Array<String>, Array<String>)] the report lines and the problems
|
|
147
|
+
def judge(modules, pending, results)
|
|
148
|
+
problems = []
|
|
149
|
+
lines = modules.map do |name|
|
|
150
|
+
passed, output = results.fetch(name)
|
|
151
|
+
if pending.key?(name)
|
|
152
|
+
problems << "#{name} passes now - delete it from Hecks::Corpus::RUST_COVERAGE_PENDING" if passed
|
|
153
|
+
"#{name}: pending (#{passed ? 'NOW PASSES' : 'still fails'}) - #{pending[name]}"
|
|
154
|
+
else
|
|
155
|
+
problems << "#{name} failed:\n#{output}" unless passed
|
|
156
|
+
"#{name}: #{passed ? 'ok' : 'FAILED'}"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
[lines, problems]
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# @param modules [Array<String>] the generated modules
|
|
163
|
+
# @param tree [Tree] the checkout
|
|
164
|
+
# @return [Hash{String => Array}] each module's `[passed, output]`
|
|
165
|
+
def coverage_results(modules, tree)
|
|
166
|
+
runner = CorpusTasks.coverage_runner || RustBuild
|
|
167
|
+
env = { "HECKS_RUST_DIR" => tree.path("rust") }
|
|
168
|
+
modules.to_h do |name|
|
|
169
|
+
result = runner.capture("rust_coverage", [name], env: env)
|
|
170
|
+
[name, [result.ok?, [result.out, result.err].join]]
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# @param operation [String] `ir_constructs`, `ir_duplicates` or `ir_impact`
|
|
175
|
+
# @param args [Hash] the query's plain arguments
|
|
176
|
+
# @return [String] the formatted answer
|
|
177
|
+
# @raise [ConsoleCapture::Failure] when the query refuses its arguments
|
|
178
|
+
def ir_query(operation, args)
|
|
179
|
+
case operation
|
|
180
|
+
when "ir_constructs" then QueryIR.format_constructs(QueryIR.constructs(words(args[:names])))
|
|
181
|
+
when "ir_duplicates" then duplicates(args)
|
|
182
|
+
else QueryIR.format_impact_preview(QueryIR.impact_preview(args[:name], args[:field]))
|
|
183
|
+
end
|
|
184
|
+
rescue ArgumentError => e
|
|
185
|
+
raise ConsoleCapture::Failure, e.message
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# @param args [Hash] `domains` and `meta`
|
|
189
|
+
# @return [String] the duplicated rules; the meta-domain is included when asked for, or
|
|
190
|
+
# when no domain is named
|
|
191
|
+
def duplicates(args)
|
|
192
|
+
domains = args[:domains] ? words(args[:domains]) : nil
|
|
193
|
+
QueryIR.format_duplicates(QueryIR.duplicates(domains: domains, include_meta: args[:meta] == true || domains.nil?))
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @param list [String, nil] a comma-separated list
|
|
197
|
+
# @return [Array<String>] its items
|
|
198
|
+
def words(list) = list.to_s.split(",").map(&:strip).reject(&:empty?)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "json"
|
|
5
|
+
require "hecks/release/runner/commands"
|
|
6
|
+
require_relative "secret_vault"
|
|
7
|
+
|
|
8
|
+
module Hecks
|
|
9
|
+
module Adapters
|
|
10
|
+
module Codebase
|
|
11
|
+
# The `GemRegistry` adapter: what a release does with rubygems.org and the `gem` program.
|
|
12
|
+
#
|
|
13
|
+
# It asks the registry which versions are out (over `curl`, no credentials), builds the gem
|
|
14
|
+
# from the checkout's gemspec, and pushes it with the key the SecretVault holds. A built gem
|
|
15
|
+
# file is always deleted again, whether the push worked or not.
|
|
16
|
+
class GemRegistry
|
|
17
|
+
# Where RubyGems lists the published versions of the gem.
|
|
18
|
+
VERSIONS_URL = "https://rubygems.org/api/v1/versions/hecks.json"
|
|
19
|
+
|
|
20
|
+
# The env file `op run` reads the push key from, relative to the checkout.
|
|
21
|
+
ENV_FILE = "release/gem_push.env"
|
|
22
|
+
|
|
23
|
+
# @param root [String] the checkout's root
|
|
24
|
+
# @param commands [#capture, #run!] starts each process
|
|
25
|
+
# @param vault [SecretVault, nil] holds the push key; one over `commands` when nil
|
|
26
|
+
def initialize(root:, commands:, vault: nil)
|
|
27
|
+
@root = root
|
|
28
|
+
@commands = commands
|
|
29
|
+
@vault = vault || SecretVault.new(commands: commands)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Says whether RubyGems lists the gem at a version.
|
|
33
|
+
#
|
|
34
|
+
# @param version [String] the version to look for
|
|
35
|
+
# @return [Boolean] true when it is published
|
|
36
|
+
# @raise [Hecks::Release::Runner::Refusal] when RubyGems cannot be reached or answers with
|
|
37
|
+
# something that is not a version list
|
|
38
|
+
def published?(version)
|
|
39
|
+
result = @commands.capture("curl", "-fsS", VERSIONS_URL, chdir: @root)
|
|
40
|
+
unless result.success?
|
|
41
|
+
raise Release::Runner::Refusal, "could not list published hecks versions (#{result.stderr.strip}); " \
|
|
42
|
+
"check the network and re-run"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
JSON.parse(result.stdout).any? { |entry| entry["number"] == version }
|
|
46
|
+
rescue JSON::ParserError
|
|
47
|
+
raise Release::Runner::Refusal, "RubyGems answered with something other than a version list; " \
|
|
48
|
+
"re-run in a minute"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Builds the gem, to prove it builds, and deletes it again.
|
|
52
|
+
#
|
|
53
|
+
# @param version [String] the version being released
|
|
54
|
+
# @return [void]
|
|
55
|
+
# @raise [Hecks::Release::Runner::CommandFailed] when the build fails
|
|
56
|
+
def build_only!(version)
|
|
57
|
+
@commands.run!("gem", "build", "hecks.gemspec", chdir: @root)
|
|
58
|
+
ensure
|
|
59
|
+
discard(version)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Builds the gem and pushes it to rubygems.org, then deletes the file.
|
|
63
|
+
#
|
|
64
|
+
# @param version [String] the version being released
|
|
65
|
+
# @return [void]
|
|
66
|
+
# @raise [Hecks::Release::Runner::CommandFailed] when the build or the push fails
|
|
67
|
+
def push!(version)
|
|
68
|
+
@commands.run!("gem", "build", "hecks.gemspec", chdir: @root)
|
|
69
|
+
@vault.run!(ENV_FILE, "gem", "push", "hecks-#{version}.gem", chdir: @root)
|
|
70
|
+
ensure
|
|
71
|
+
discard(version)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def discard(version) = FileUtils.rm_f(File.join(@root, "hecks-#{version}.gem"))
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "tree"
|
|
4
|
+
require "hecks/kernel_capabilities"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
module Adapters
|
|
8
|
+
module Codebase
|
|
9
|
+
# What Codebase's `KernelRun` asks of the working tree: projecting the capability enums the
|
|
10
|
+
# hand-written Rust kernel is matched against, and checking that each capability the grammar
|
|
11
|
+
# admits has its hand-written file.
|
|
12
|
+
#
|
|
13
|
+
# The projection is built in memory by `KernelCapabilities`, the code
|
|
14
|
+
# `hecks project_kernel_capabilities` runs, and compared with the tree; it writes only when
|
|
15
|
+
# confirmed. The coverage check reads the tree and writes nothing.
|
|
16
|
+
module KernelTables
|
|
17
|
+
# Every operation this family carries out.
|
|
18
|
+
OPERATIONS = %w[project_kernel_capabilities measure_kernel_coverage].freeze
|
|
19
|
+
|
|
20
|
+
module_function
|
|
21
|
+
|
|
22
|
+
# Carries out one operation.
|
|
23
|
+
#
|
|
24
|
+
# @param operation [String] one of `OPERATIONS`
|
|
25
|
+
# @param held [Hash] the `KernelRun` record's fields
|
|
26
|
+
# @param tree [Tree] the working tree, already known to be a hecks checkout
|
|
27
|
+
# @param shell [#capture] unused; the family starts no child process
|
|
28
|
+
# @return [String] the drift report, or the coverage report
|
|
29
|
+
# @raise [ConsoleCapture::Failure] when a capability has no kernel file
|
|
30
|
+
def call(operation, held, tree, shell: nil)
|
|
31
|
+
_ = shell
|
|
32
|
+
confirm = (held[:confirm].is_a?(Hash) ? held[:confirm][:value] : held[:confirm]) == true
|
|
33
|
+
return coverage(tree) if operation == "measure_kernel_coverage"
|
|
34
|
+
|
|
35
|
+
result = KernelCapabilities.build(root: tree.root)
|
|
36
|
+
tree.apply(result.content, stale: result.stale, confirm: confirm)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Lists every capability the live grammar admits with whether its file is there.
|
|
40
|
+
#
|
|
41
|
+
# @param tree [Tree] the checkout
|
|
42
|
+
# @return [String] one line for each capability, and a verdict
|
|
43
|
+
# @raise [ConsoleCapture::Failure] when any capability has no file
|
|
44
|
+
def coverage(tree)
|
|
45
|
+
lines, verdict, complete = KernelCapabilities.coverage_report(root: tree.root)
|
|
46
|
+
report = [lines, "", verdict].join("\n")
|
|
47
|
+
return report if complete
|
|
48
|
+
|
|
49
|
+
raise ConsoleCapture::Failure, report
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "tree"
|
|
5
|
+
require_relative "../shell"
|
|
6
|
+
require "hecks/projection_files"
|
|
7
|
+
require "hecks/grammar/evolve"
|
|
8
|
+
|
|
9
|
+
module Hecks
|
|
10
|
+
module Adapters
|
|
11
|
+
module Codebase
|
|
12
|
+
# What Codebase's `LanguageRun` asks of the working tree: projecting the language's tables
|
|
13
|
+
# and walking a word through its lifecycle.
|
|
14
|
+
#
|
|
15
|
+
# A projection is built in memory by {ProjectionFiles} (the same code the `hecks project_*`
|
|
16
|
+
# scripts run) and compared with the tree; it writes only when confirmed. An evolution edits
|
|
17
|
+
# the syntax tables through {Grammar::Evolve}: unconfirmed it is rehearsed against an
|
|
18
|
+
# in-memory copy and reports the edit it would make; confirmed it regenerates the golden IR
|
|
19
|
+
# and holds the gates in a child process, and puts every file back if a gate refuses.
|
|
20
|
+
module Language
|
|
21
|
+
# The projection each operation runs.
|
|
22
|
+
PROJECTIONS = {
|
|
23
|
+
"project_model" => :model,
|
|
24
|
+
"project_vocabulary" => :vocabulary,
|
|
25
|
+
"project_rust_vocabulary" => :rust_vocabulary,
|
|
26
|
+
"project_reserved_names" => :reserved_names,
|
|
27
|
+
"project_parser_table" => :parser_table,
|
|
28
|
+
"project_bootstrap_table" => :bootstrap_table,
|
|
29
|
+
"project_field_hints" => :field_hints,
|
|
30
|
+
"project_expression_tables" => :expression_tables,
|
|
31
|
+
"project_reference" => :reference
|
|
32
|
+
}.freeze
|
|
33
|
+
|
|
34
|
+
# The status each word or argument operation moves a row to.
|
|
35
|
+
STATUSES = { "admit" => "admitted", "deprecate" => "deprecated", "retire" => "retired",
|
|
36
|
+
"admit_argument" => "admitted", "deprecate_argument" => "deprecated",
|
|
37
|
+
"retire_argument" => "retired" }.freeze
|
|
38
|
+
|
|
39
|
+
# Every operation this family carries out.
|
|
40
|
+
OPERATIONS = (PROJECTIONS.keys + %w[propose rename propose_argument] + STATUSES.keys).freeze
|
|
41
|
+
|
|
42
|
+
# The specs that hold a grammar edit: the syntax rows agree with the builder, the lifecycle
|
|
43
|
+
# holds, and the golden IR is the one the language produces.
|
|
44
|
+
GATES = %w[spec/syntax_conformance_spec.rb spec/syntax_lifecycle_spec.rb spec/ir_golden_spec.rb].freeze
|
|
45
|
+
|
|
46
|
+
# The golden IR a grammar edit regenerates.
|
|
47
|
+
GOLDEN = "spec/golden/ir/Bluebook.json"
|
|
48
|
+
|
|
49
|
+
# What the tool says after a proposal or a rename, which still needs hand work.
|
|
50
|
+
FOLLOW_UP = {
|
|
51
|
+
"propose" => "Proposed. It reaches no projection until admitted. Before `hecks admit`:\n " \
|
|
52
|
+
"1. teach the %<context>s builder the word (and its spec/dsl_spec example)",
|
|
53
|
+
"rename" => "Renamed. The old spelling keeps parsing — that is the point. Before this holds:\n " \
|
|
54
|
+
"1. alias the new word to the old in the %<context>s builder " \
|
|
55
|
+
"(alias_method :%<new_name>s, :%<word>s)\n " \
|
|
56
|
+
"2. add the identical-IR example to spec/dsl_spec.rb",
|
|
57
|
+
"propose_argument" => "Proposed. It reaches no projection until admitted. Before " \
|
|
58
|
+
"`hecks admit_argument`:\n " \
|
|
59
|
+
"1. teach the %<context>s builder's %<word>s method the argument"
|
|
60
|
+
}.freeze
|
|
61
|
+
|
|
62
|
+
module_function
|
|
63
|
+
|
|
64
|
+
# Carries out one operation.
|
|
65
|
+
#
|
|
66
|
+
# @param operation [String] one of `OPERATIONS`
|
|
67
|
+
# @param held [Hash] the `LanguageRun` record's fields
|
|
68
|
+
# @param tree [Tree] the working tree, already known to be a hecks checkout
|
|
69
|
+
# @param shell [#capture] starts the gates' child process
|
|
70
|
+
# @return [String] what was found, or done
|
|
71
|
+
# @raise [ConsoleCapture::Failure] when the language refuses the edit, or a gate does
|
|
72
|
+
def call(operation, held, tree, shell: Shell.new)
|
|
73
|
+
args = held.transform_values { |value| value.is_a?(Hash) ? value[:value] : value }
|
|
74
|
+
return project(operation, args, tree) if PROJECTIONS.key?(operation)
|
|
75
|
+
|
|
76
|
+
evolve(operation, args, tree, shell)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Where every word stands: the rows not simply admitted, and the renamed ones.
|
|
80
|
+
#
|
|
81
|
+
# @return [String] a count, then a line for each row that is moving or renamed
|
|
82
|
+
def word_status
|
|
83
|
+
rows = Grammar::Evolve.keyword_rows
|
|
84
|
+
moving = rows.reject { |row| row[:status] == "admitted" }
|
|
85
|
+
renamed = rows.reject { |row| row[:was].to_s.empty? }
|
|
86
|
+
lines = ["#{rows.size} keyword rows; #{moving.size} not simply admitted; #{renamed.size} renamed"]
|
|
87
|
+
lines += moving.map { |row| " #{row[:status].ljust(10)} #{row[:context]}.#{row[:word]}" }
|
|
88
|
+
lines += renamed.map { |row| " renamed #{row[:context]}.#{row[:word]} (was #{row[:was]})" }
|
|
89
|
+
lines.join("\n")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @param operation [String] a projection's operation
|
|
93
|
+
# @param args [Hash] the record's plain fields
|
|
94
|
+
# @param tree [Tree] the checkout
|
|
95
|
+
# @return [String] the projected text for `stdout`, or the drift report
|
|
96
|
+
# @raise [ConsoleCapture::Failure] when the language cannot be projected
|
|
97
|
+
def project(operation, args, tree)
|
|
98
|
+
result = ProjectionFiles.build(PROJECTIONS.fetch(operation), root: tree.root)
|
|
99
|
+
return result.content.values.first if args[:stdout]
|
|
100
|
+
|
|
101
|
+
tree.apply(result.content, stale: result.stale, confirm: args[:confirm] == true)
|
|
102
|
+
rescue ProjectionFiles::Refused => e
|
|
103
|
+
raise ConsoleCapture::Failure, e.message
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# @param operation [String] a word or argument operation
|
|
107
|
+
# @param args [Hash] the record's plain fields
|
|
108
|
+
# @param tree [Tree] the checkout
|
|
109
|
+
# @param shell [#capture] starts the gates
|
|
110
|
+
# @return [String] the rehearsed edit, or the confirmed edit's outcome
|
|
111
|
+
# @raise [ConsoleCapture::Failure] when the language or a gate refuses
|
|
112
|
+
def evolve(operation, args, tree, shell)
|
|
113
|
+
change = -> { edit(operation, args) }
|
|
114
|
+
return rehearse(change, tree) unless args[:confirm] == true
|
|
115
|
+
|
|
116
|
+
guarded(operation, args, tree, shell, change)
|
|
117
|
+
rescue Grammar::Evolve::Refusal => e
|
|
118
|
+
raise ConsoleCapture::Failure, e.message
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# @param edit [#call] the edit to make
|
|
122
|
+
# @param tree [Tree] the checkout
|
|
123
|
+
# @return [String] each file the edit would change, with its lines added and removed
|
|
124
|
+
def rehearse(edit, tree)
|
|
125
|
+
changed = Grammar::Evolve.rehearse(&edit)
|
|
126
|
+
lines = changed.map do |path, text|
|
|
127
|
+
before = File.read(path).lines
|
|
128
|
+
after = text.lines
|
|
129
|
+
" changed #{tree.relative(path)} (+#{(after - before).size} -#{(before - after).size} lines)"
|
|
130
|
+
end
|
|
131
|
+
["dry run, #{changed.size} file changes (add --confirm to make them, regenerate the golden and hold the gates):",
|
|
132
|
+
*lines].join("\n")
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Makes the edit, regenerates the golden and holds the gates; puts every file back if the
|
|
136
|
+
# edit or a gate refuses.
|
|
137
|
+
#
|
|
138
|
+
# @param operation [String] the operation, for the follow-up it prints
|
|
139
|
+
# @param args [Hash] the record's plain fields
|
|
140
|
+
# @param tree [Tree] the checkout
|
|
141
|
+
# @param shell [#capture] starts the child processes
|
|
142
|
+
# @param edit [#call] the edit to make
|
|
143
|
+
# @return [String] what the gates held, and what is left to do by hand
|
|
144
|
+
# @raise [ConsoleCapture::Failure] when the edit or a gate refuses; nothing was changed
|
|
145
|
+
def guarded(operation, args, tree, shell, edit)
|
|
146
|
+
paths = Grammar::Evolve.syntax_paths + [tree.path(GOLDEN)]
|
|
147
|
+
snapshots = paths.to_h { |path| [path, File.read(path)] }
|
|
148
|
+
Grammar::Evolve.restore_on_raise(paths, &edit)
|
|
149
|
+
regenerate(tree, shell)
|
|
150
|
+
gates = shell.capture("bundle", "exec", "rspec", *GATES, chdir: tree.root)
|
|
151
|
+
unless gates.ok?
|
|
152
|
+
snapshots.each { |path, text| File.write(path, text) }
|
|
153
|
+
raise ConsoleCapture::Failure,
|
|
154
|
+
"RESTORED — the gates refused, and the failures are the checklist. Nothing was " \
|
|
155
|
+
"changed.\n#{[gates.out, gates.err].join.strip}"
|
|
156
|
+
end
|
|
157
|
+
["#{args[:context]}.#{args[:word]} — the gates hold. Regenerated projections and the golden " \
|
|
158
|
+
"are in the tree.", follow_up(operation, args)].compact.join("\n")
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @param tree [Tree] the checkout
|
|
162
|
+
# @param shell [#capture] starts the child process
|
|
163
|
+
# @return [void]
|
|
164
|
+
def regenerate(tree, shell)
|
|
165
|
+
shell.capture("bundle", "exec", "rspec", "spec/ir_golden_spec.rb", env: { "GOLDEN" => "rewrite" },
|
|
166
|
+
chdir: tree.root)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @param operation [String] the operation
|
|
170
|
+
# @param args [Hash] the record's plain fields
|
|
171
|
+
# @return [String, nil] what still needs hand work, if anything
|
|
172
|
+
def follow_up(operation, args)
|
|
173
|
+
text = FOLLOW_UP[operation] or return nil
|
|
174
|
+
|
|
175
|
+
format(text, context: args[:context], new_name: args[:new_name], word: args[:word])
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Makes one edit to the syntax tables.
|
|
179
|
+
#
|
|
180
|
+
# @param operation [String] a word or argument operation
|
|
181
|
+
# @param args [Hash] the record's plain fields
|
|
182
|
+
# @return [void]
|
|
183
|
+
# @raise [Grammar::Evolve::Refusal] when the tables refuse the edit
|
|
184
|
+
def edit(operation, args)
|
|
185
|
+
case operation
|
|
186
|
+
when "propose" then propose(args)
|
|
187
|
+
when "rename" then rename(args)
|
|
188
|
+
when "propose_argument" then propose_argument(args)
|
|
189
|
+
when "admit", "deprecate", "retire" then set_status(operation, args)
|
|
190
|
+
else set_argument_status(operation, args)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# @param args [Hash] the record's plain fields
|
|
195
|
+
# @return [void]
|
|
196
|
+
def propose(args)
|
|
197
|
+
Grammar::Evolve.propose(word: args[:word], context: args[:context], body: args[:body] || "none",
|
|
198
|
+
inner: args[:inner] || "", opens: args[:opens] || "", fills: args[:fills] || "")
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# @param args [Hash] the record's plain fields
|
|
202
|
+
# @return [void]
|
|
203
|
+
# @raise [Grammar::Evolve::Refusal] when no new name was given
|
|
204
|
+
def rename(args)
|
|
205
|
+
to = args[:new_name] or refuse("a rename goes somewhere: new_name=")
|
|
206
|
+
Grammar::Evolve.rename(word: args[:word], context: args[:context], to: to)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# @param args [Hash] the record's plain fields
|
|
210
|
+
# @return [void]
|
|
211
|
+
def propose_argument(args)
|
|
212
|
+
Grammar::Evolve.propose_argument(keyword: args[:word], context: args[:context], kind: args[:kind],
|
|
213
|
+
required: args[:required] || "false", at: args[:at] || "",
|
|
214
|
+
named: args[:named] || "", fills: args[:fills] || "",
|
|
215
|
+
pairs_shape: args[:pairs_shape])
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# @param operation [String] `admit`, `deprecate` or `retire`
|
|
219
|
+
# @param args [Hash] the record's plain fields
|
|
220
|
+
# @return [void]
|
|
221
|
+
def set_status(operation, args)
|
|
222
|
+
Grammar::Evolve.set_status(word: args[:word], context: args[:context], to: STATUSES.fetch(operation))
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# @param operation [String] the argument form of `admit`, `deprecate` or `retire`
|
|
226
|
+
# @param args [Hash] the record's plain fields
|
|
227
|
+
# @return [void]
|
|
228
|
+
def set_argument_status(operation, args)
|
|
229
|
+
Grammar::Evolve.set_argument_status(keyword: args[:word], context: args[:context],
|
|
230
|
+
to: STATUSES.fetch(operation), at: args[:at] || "",
|
|
231
|
+
named: args[:named] || "")
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# @param message [String] why the edit cannot be made
|
|
235
|
+
# @raise [Grammar::Evolve::Refusal] always
|
|
236
|
+
def refuse(message) = raise(Grammar::Evolve::Refusal, message)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "tempfile"
|
|
4
|
+
require "hecks/release/runner/commands"
|
|
5
|
+
require_relative "secret_vault"
|
|
6
|
+
|
|
7
|
+
module Hecks
|
|
8
|
+
module Adapters
|
|
9
|
+
module Codebase
|
|
10
|
+
# The `NpmRegistry` adapter: what a release does with npm and the `@hecks/client` package.
|
|
11
|
+
#
|
|
12
|
+
# It asks npm whether a version is out (no credentials), installs the package's
|
|
13
|
+
# dependencies, and publishes it, either as a dry run (a pack, no credentials) or with the
|
|
14
|
+
# token the SecretVault holds. The token bypasses 2FA, so the publish runs with
|
|
15
|
+
# `--auth-type=web` and its output is not captured: the approval link reaches the terminal.
|
|
16
|
+
class NpmRegistry
|
|
17
|
+
# The package, by name.
|
|
18
|
+
PACKAGE = "@hecks/client"
|
|
19
|
+
|
|
20
|
+
# Where the package stands, relative to the checkout.
|
|
21
|
+
PACKAGE_DIR = "packages/hecks-client"
|
|
22
|
+
|
|
23
|
+
# The env file `op run` reads the publish token from, relative to the checkout.
|
|
24
|
+
ENV_FILE = "release/npm_publish.env"
|
|
25
|
+
|
|
26
|
+
# The npmrc line that reads the token from the environment `op run` sets.
|
|
27
|
+
USERCONFIG_LINE = "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}"
|
|
28
|
+
|
|
29
|
+
# @param root [String] the checkout's root
|
|
30
|
+
# @param commands [#capture, #run!] starts each process
|
|
31
|
+
# @param vault [SecretVault, nil] holds the publish token; one over `commands` when nil
|
|
32
|
+
def initialize(root:, commands:, vault: nil)
|
|
33
|
+
@root = root
|
|
34
|
+
@commands = commands
|
|
35
|
+
@vault = vault || SecretVault.new(commands: commands)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Says whether npm lists the package at a version.
|
|
39
|
+
#
|
|
40
|
+
# @param version [String] the version to look for
|
|
41
|
+
# @return [Boolean] true when it is published
|
|
42
|
+
# @raise [Hecks::Release::Runner::Refusal] when npm fails for any reason other than the
|
|
43
|
+
# version not existing
|
|
44
|
+
def published?(version)
|
|
45
|
+
result = @commands.capture("npm", "view", "#{PACKAGE}@#{version}", "version", chdir: @root)
|
|
46
|
+
return result.stdout.strip == version if result.success?
|
|
47
|
+
return false if result.stderr.include?("E404")
|
|
48
|
+
|
|
49
|
+
raise Release::Runner::Refusal,
|
|
50
|
+
"could not check npm for #{PACKAGE}@#{version} (#{result.stderr.strip.lines.first}); " \
|
|
51
|
+
"check the network and re-run"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @return [Boolean] whether the package's dependencies are already installed
|
|
55
|
+
def installed?
|
|
56
|
+
Dir.exist?(File.join(package_dir, "node_modules"))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Installs the package's dependencies with `npm ci`.
|
|
60
|
+
#
|
|
61
|
+
# @return [void]
|
|
62
|
+
# @raise [Hecks::Release::Runner::CommandFailed] when it fails
|
|
63
|
+
def install!
|
|
64
|
+
@commands.run!("npm", "ci", chdir: package_dir)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Packs the package and publishes nothing.
|
|
68
|
+
#
|
|
69
|
+
# @return [void]
|
|
70
|
+
# @raise [Hecks::Release::Runner::CommandFailed] when the pack fails
|
|
71
|
+
def dry_publish!
|
|
72
|
+
@commands.run!("npm", "publish", "--dry-run", "--access", "public", chdir: package_dir)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Publishes the package with the token the vault holds.
|
|
76
|
+
#
|
|
77
|
+
# @return [void]
|
|
78
|
+
# @raise [Hecks::Release::Runner::CommandFailed] when the publish fails
|
|
79
|
+
def publish!
|
|
80
|
+
with_userconfig do |userconfig|
|
|
81
|
+
@vault.run!(File.join(@root, ENV_FILE), "npm", "publish", "--access", "public", "--auth-type=web",
|
|
82
|
+
"--userconfig", userconfig, chdir: package_dir)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def package_dir = File.join(@root, PACKAGE_DIR)
|
|
89
|
+
|
|
90
|
+
def with_userconfig
|
|
91
|
+
file = Tempfile.new(["hecks-npmrc", ".npmrc"])
|
|
92
|
+
file.chmod(0o600)
|
|
93
|
+
file.write("#{USERCONFIG_LINE}\n")
|
|
94
|
+
file.flush
|
|
95
|
+
yield file.path
|
|
96
|
+
ensure
|
|
97
|
+
file&.close!
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|