hecks 2.9.0 → 3.0.1
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 +51 -6
- data/lib/hecks/adapters/driven/heki/journal.rb +1 -1
- data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
- data/lib/hecks/adapters/driven/lambda.rb +1 -1
- data/lib/hecks/adapters/driven/memory.rb +16 -3
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +6 -2
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +13 -4
- data/lib/hecks/adapters/driven/prism.rb +41 -8
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +73 -16
- data/lib/hecks/behaviors/expectations.rb +1 -1
- data/lib/hecks/behaviors.rb +1 -1
- 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/assembly/contracts.rb +2 -0
- data/lib/hecks/bluebook/attribute.rb +1 -1
- data/lib/hecks/bluebook/behaviour/aggregate.rb +30 -1
- data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -0
- data/lib/hecks/bluebook/chapter.rb +6 -2
- data/lib/hecks/bluebook/domain_port.rb +36 -5
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +10 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +8 -0
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -1
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +31 -3
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +122 -3
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +1 -1
- data/lib/hecks/bluebook/dsl/query_builder.rb +27 -1
- data/lib/hecks/bluebook/dsl/rule_reference.rb +1 -1
- data/lib/hecks/bluebook/dsl/world_builder.rb +29 -2
- data/lib/hecks/bluebook/expression/canonical_form.rb +1 -1
- data/lib/hecks/bluebook/expression/resolver.rb +3 -2
- data/lib/hecks/bluebook/hexagon.rb +13 -5
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +1 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +4 -1
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator.rb +9 -4
- data/lib/hecks/bluebook/model_check.rb +23 -0
- data/lib/hecks/bluebook/pattern_subset.rb +38 -0
- data/lib/hecks/bluebook/query.rb +20 -5
- data/lib/hecks/bluebook/smoke_test.rb +1 -1
- 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 +2 -2
- 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 +1 -1
- data/lib/hecks/cli/mcp.rb +3 -3
- data/lib/hecks/cli/model_check.rb +15 -8
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +224 -32
- data/lib/hecks/cli/project_diagrams.rb +4 -3
- 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 +3 -3
- 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 +5 -3
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -5
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +201 -52
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +591 -23
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -4
- 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 +1 -1
- data/lib/hecks/{facade → doors}/handle.rb +2 -2
- data/lib/hecks/{facade → doors}/json_door.rb +4 -4
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +7 -7
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/{facade/surface → doors/ruby_door}/aggregate_door.rb +8 -3
- data/lib/hecks/{facade/surface → doors/ruby_door}/chapter.rb +3 -3
- data/lib/hecks/{facade/surface.rb → doors/ruby_door.rb} +36 -5
- data/lib/hecks/doors.rb +61 -0
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +1 -1
- data/lib/hecks/embryonaut_bluebook.rb +1 -1
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +24 -37
- data/lib/hecks/forms/app.rb +6 -6
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- data/lib/hecks/forms/field_shape.rb +2 -1
- data/lib/hecks/forms/port_argument.rb +1 -1
- 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/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/kernel_capabilities.rb +194 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +11 -0
- data/lib/hecks/language/bluebook/query.bluebook +7 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +4 -4
- data/lib/hecks/language/hecksagon/domain_port.bluebook +10 -0
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +20 -0
- data/lib/hecks/mcp_stdio_guard.rb +2 -2
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +8 -5
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +4 -1
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +15 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +32 -15
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +15 -5
- 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 +1 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +43 -24
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
- data/lib/hecks/ports/persistence/state_codec.rb +24 -5
- data/lib/hecks/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +1 -1
- data/lib/hecks/projections/deploy/fargate.rb +5 -5
- data/lib/hecks/projections/deploy/lambda.rb +43 -32
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/preview/template.rb +1 -1
- 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/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/shared.rb +1 -1
- data/lib/hecks/projections/diagrams.rb +3 -3
- data/lib/hecks/projections/model/deviations.rb +1 -1
- data/lib/hecks/projections/parser_table.rb +4 -4
- data/lib/hecks/projections/reference.rb +2 -3
- data/lib/hecks/projections/rust_vocabulary.rb +1 -1
- data/lib/hecks/projector/cli_projector.rb +106 -37
- data/lib/hecks/projector.rb +1 -1
- 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/release/runner/ci_publisher.rb +2 -2
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +14 -7
- data/lib/hecks/release/runner/npm_publisher.rb +6 -36
- data/lib/hecks/release/runner/preflight.rb +26 -2
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +30 -15
- data/lib/hecks/release/runner.rb +57 -6
- data/lib/hecks/router/namespace_installer.rb +3 -3
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +4 -0
- data/lib/hecks/runtime/dependency_planning.rb +20 -2
- data/lib/hecks/runtime/dispatcher.rb +53 -3
- data/lib/hecks/runtime/interpreting.rb +3 -0
- data/lib/hecks/runtime/loader.rb +65 -12
- data/lib/hecks/runtime/outbox.rb +1 -1
- data/lib/hecks/runtime/policy_interpreter.rb +5 -2
- data/lib/hecks/runtime/port_operation_interpreter.rb +2 -10
- data/lib/hecks/runtime/query_interpreter.rb +77 -0
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- data/lib/hecks/runtime/refusal_wording.rb +23 -1
- data/lib/hecks/runtime/registry/verification.rb +163 -4
- data/lib/hecks/runtime/registry.rb +57 -3
- data/lib/hecks/runtime/remote_dispatcher.rb +31 -2
- data/lib/hecks/runtime/value/coercion.rb +23 -135
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +4 -1
- data/lib/hecks/runtime.rb +20 -6
- 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 +16 -16
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +2 -2
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +1 -1
- 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/version.rb +1 -1
- data/lib/hecks.rb +32 -15
- 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 +477 -12
- data/lib/hecks/facade/cli_door.rb +0 -96
- data/lib/hecks/facade/cli_runner.rb +0 -127
- data/lib/hecks/mcp_door_scope.rb +0 -95
|
@@ -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
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "stringio"
|
|
4
|
+
require "hecks/release/runner"
|
|
5
|
+
require_relative "tree"
|
|
6
|
+
require_relative "gem_registry"
|
|
7
|
+
require_relative "secret_vault"
|
|
8
|
+
require_relative "release_facts"
|
|
9
|
+
require_relative "../console_capture"
|
|
10
|
+
|
|
11
|
+
module Hecks
|
|
12
|
+
module Adapters
|
|
13
|
+
module Codebase
|
|
14
|
+
# What Codebase's `PublishingRun` asks of the working tree once the release is cleared:
|
|
15
|
+
# cutting the release, or pushing the gem alone.
|
|
16
|
+
#
|
|
17
|
+
# A release is `Hecks::Release::Runner`: it tags the release commit, publishes the gem and
|
|
18
|
+
# gets the client package published, skipping what a registry already lists. Its rules were
|
|
19
|
+
# judged before it starts (the givens of `Clear`), so it is handed the facts they cleared and
|
|
20
|
+
# checks only that its tools are installed. Unconfirmed it is the dry run: every check and
|
|
21
|
+
# build, and nothing tagged, pushed or published. The answer says which steps were really
|
|
22
|
+
# carried out, so the journal can advance the root `Release`: tagged, published, verified.
|
|
23
|
+
module Publishing
|
|
24
|
+
# Every operation this family carries out.
|
|
25
|
+
OPERATIONS = %w[publish publish_gem].freeze
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
# @return [#capture, #run!, nil] starts every process a release runs; the real ones
|
|
29
|
+
# (`Hecks::Release::Runner::Commands`) when nil. A spec replaces it, so nothing is
|
|
30
|
+
# tagged, pushed, published or fetched.
|
|
31
|
+
attr_accessor :commands
|
|
32
|
+
|
|
33
|
+
# @return [Hash] extra arguments for the release, such as `pause:` and `now:`, so a spec
|
|
34
|
+
# can wait for the registry without sleeping
|
|
35
|
+
attr_accessor :release_options
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
module_function
|
|
39
|
+
|
|
40
|
+
# The facts of a tree that is not a checkout: placeholders that satisfy the value objects,
|
|
41
|
+
# so the checkout rule is the one that refuses.
|
|
42
|
+
#
|
|
43
|
+
# @param operation [String] `publish` or `publish_gem`
|
|
44
|
+
# @return [Hash] every fact a release is judged by, none of them true
|
|
45
|
+
def no_facts(operation)
|
|
46
|
+
none = { value: "none" }
|
|
47
|
+
{ operation: { value: operation }, version: { value: "0.0.0" }, client_version: { value: "0.0.0" },
|
|
48
|
+
ir_version: { value: "0.0.0" }, ships_from: { path: "none" }, branch: none, head: none,
|
|
49
|
+
tag_state: none, on_origin: { value: false }, clean: { value: false }, changelog: { value: false } }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Carries out an accepted request.
|
|
53
|
+
#
|
|
54
|
+
# @param operation [String] `publish` or `publish_gem`
|
|
55
|
+
# @param held [Hash] the `PublishingRun` record's fields
|
|
56
|
+
# @param tree [Tree] the working tree, already known to be a hecks checkout
|
|
57
|
+
# @param shell [#capture, nil] unused; the release starts its own processes
|
|
58
|
+
# @return [Hash] `report`, `tagged`, `published` and `verified`, and `version` for the
|
|
59
|
+
# `Release` record
|
|
60
|
+
# @raise [ConsoleCapture::Failure] when the release refuses or a step fails, with its words
|
|
61
|
+
def call(operation, held, tree, shell: nil)
|
|
62
|
+
_ = shell
|
|
63
|
+
args = held.transform_values { |value| value.is_a?(Hash) && value.key?(:value) ? value[:value] : value }
|
|
64
|
+
commands = Publishing.commands || Release::Runner::Commands.new
|
|
65
|
+
if operation == "publish_gem"
|
|
66
|
+
publish_gem(args, tree, commands)
|
|
67
|
+
else
|
|
68
|
+
publish(args, tree, commands)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# @param args [Hash] the record's plain fields
|
|
73
|
+
# @param tree [Tree] the checkout
|
|
74
|
+
# @param commands [#capture, #run!] starts each process
|
|
75
|
+
# @return [Hash] what the release did
|
|
76
|
+
# @raise [ConsoleCapture::Failure] when the release stops before any real step; one that
|
|
77
|
+
# stops after a real step answers, with `succeeded` false, so the steps are recorded
|
|
78
|
+
def publish(args, tree, commands)
|
|
79
|
+
out = StringIO.new
|
|
80
|
+
err = StringIO.new
|
|
81
|
+
runner = release(args, tree, commands, out, err)
|
|
82
|
+
status = runner.call
|
|
83
|
+
text = [out.string, err.string].map(&:strip).reject(&:empty?).join("\n")
|
|
84
|
+
raise ConsoleCapture::Failure, text if !status.zero? && runner.steps.empty?
|
|
85
|
+
|
|
86
|
+
outcome(text, args, tagged: runner.steps.include?(:tagged), published: runner.steps.include?(:gem),
|
|
87
|
+
verified: runner.verified, succeeded: status.zero?)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# @return [Hecks::Release::Runner] the release, over the facts the run was cleared by
|
|
91
|
+
def release(args, tree, commands, out, err)
|
|
92
|
+
flag = ->(name) { args[name] == true }
|
|
93
|
+
options = Release::Runner::Options.new(dry_run: args[:confirm] != true, gem_only: flag.call(:gem_only),
|
|
94
|
+
npm_only: flag.call(:npm_only), npm_local: flag.call(:npm_local),
|
|
95
|
+
no_wait: flag.call(:no_wait), yes: true)
|
|
96
|
+
facts = Release::Runner::Preflight::Facts.new(version: args[:version], sha: args[:head])
|
|
97
|
+
Release::Runner.new(root: tree.root, options: options, commands: commands, input: StringIO.new, out: out,
|
|
98
|
+
err: err, facts: facts, **(Publishing.release_options || {}))
|
|
99
|
+
rescue ArgumentError => e
|
|
100
|
+
raise ConsoleCapture::Failure, e.message
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Pushes the gem alone, or builds it and deletes it again when unconfirmed.
|
|
104
|
+
#
|
|
105
|
+
# @param args [Hash] the record's plain fields
|
|
106
|
+
# @param tree [Tree] the checkout
|
|
107
|
+
# @param commands [#capture, #run!] starts each process
|
|
108
|
+
# @return [Hash] what was done
|
|
109
|
+
# @raise [ConsoleCapture::Failure] when the build or the push fails, or the vault is missing
|
|
110
|
+
def publish_gem(args, tree, commands)
|
|
111
|
+
registry = GemRegistry.new(root: tree.root, commands: commands)
|
|
112
|
+
version = args[:version]
|
|
113
|
+
return dry_gem(registry, version, args) unless args[:confirm] == true
|
|
114
|
+
raise ConsoleCapture::Failure, "1Password CLI (op) not found; install it: brew install 1password-cli" unless
|
|
115
|
+
SecretVault.new(commands: commands).installed?
|
|
116
|
+
|
|
117
|
+
registry.push!(version)
|
|
118
|
+
verified = registry.published?(version)
|
|
119
|
+
outcome("Released hecks #{version}.", args, tagged: false, published: true, verified: verified)
|
|
120
|
+
rescue Release::Runner::CommandFailed, Release::Runner::Refusal => e
|
|
121
|
+
raise ConsoleCapture::Failure, e.message
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @return [Hash] the answer of a gem push that only built the gem
|
|
125
|
+
def dry_gem(registry, version, args)
|
|
126
|
+
registry.build_only!(version)
|
|
127
|
+
outcome("dry run, built hecks-#{version}.gem and deleted it; nothing was pushed (add --confirm)",
|
|
128
|
+
args, tagged: false, published: false, verified: false)
|
|
129
|
+
rescue Release::Runner::CommandFailed => e
|
|
130
|
+
raise ConsoleCapture::Failure, e.message
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# @return [Hash] the answer the journal records: a report, what was done, and the release
|
|
134
|
+
def outcome(text, args, tagged:, published:, verified:, succeeded: true)
|
|
135
|
+
{ report: { value: text }, tagged: { value: tagged }, published: { value: published },
|
|
136
|
+
verified: { value: verified }, succeeded: { value: succeeded }, version: { value: args[:version] },
|
|
137
|
+
ir_version: { value: args[:ir_version] }, ships_from: args[:ships_from] }
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|