hecks 3.10.0 → 3.12.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/examples/pizzas/bluebook/pizzas.bluebook +29 -0
- data/examples/pizzas/bluebook/pizzas.hecksagon +7 -0
- data/exe/hecks +4 -4
- data/lib/hecks/adapters/driven/d1.rb +2 -10
- data/lib/hecks/adapters/driven/heki.adapter +1 -1
- data/lib/hecks/adapters/driven/heki.rb +2 -12
- data/lib/hecks/adapters/driven/lambda.adapter +1 -1
- data/lib/hecks/adapters/driven/lambda.rb +3 -18
- data/lib/hecks/adapters/driven/postgres.rb +4 -11
- data/lib/hecks/adapters/driven/sqlite.adapter +1 -1
- data/lib/hecks/adapters/driven/sqlite.rb +2 -10
- data/lib/hecks/adapters/driving/admission.rb +46 -0
- data/lib/hecks/adapters/driving/cli/nesting.rb +36 -0
- data/lib/hecks/adapters/driving/cli/shorthand.rb +88 -0
- data/lib/hecks/adapters/driving/cli.rb +127 -0
- data/lib/hecks/adapters/driving/cli_runner/answers.rb +160 -0
- data/lib/hecks/adapters/driving/cli_runner/resolution.rb +158 -0
- data/lib/hecks/adapters/driving/cli_runner/settling.rb +120 -0
- data/lib/hecks/adapters/driving/cli_runner/streaming.rb +93 -0
- data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +47 -0
- data/lib/hecks/adapters/driving/cli_runner.rb +70 -0
- data/lib/hecks/adapters/driving/command_request.rb +121 -0
- data/lib/hecks/adapters/driving/handle.rb +214 -0
- data/lib/hecks/adapters/driving/json.rb +136 -0
- data/lib/hecks/adapters/driving/launcher_options.rb +267 -0
- data/lib/hecks/adapters/driving/mcp/properties.rb +49 -0
- data/lib/hecks/adapters/driving/mcp/tool_calls.rb +116 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/auditing.rb +53 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/calling.rb +71 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/reading.rb +99 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions.rb +18 -0
- data/lib/hecks/adapters/driving/mcp.rb +159 -0
- data/lib/hecks/adapters/driving/mcp_guide_cache.rb +78 -0
- data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +97 -0
- data/lib/hecks/adapters/driving/mcp_scope/env_problems.rb +69 -0
- data/lib/hecks/adapters/driving/mcp_scope/presenter.rb +83 -0
- data/lib/hecks/adapters/driving/mcp_scope.rb +213 -0
- data/lib/hecks/adapters/driving/newcomer.rb +50 -0
- data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +171 -0
- data/lib/hecks/adapters/driving/ruby/chapter.rb +91 -0
- data/lib/hecks/adapters/driving/ruby.rb +83 -0
- data/lib/hecks/adapters/driving/usage_cache.rb +144 -0
- data/lib/hecks/{doors.rb → adapters/driving.rb} +10 -6
- data/lib/hecks/behaviors/expectations/boot.rb +1 -1
- data/lib/hecks/bench/ruby_runner.rb +1 -1
- data/lib/hecks/bluebook/ask_resolution.rb +130 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +8 -2
- data/lib/hecks/bluebook/assembly/contracts/read_models.rb +1 -1
- data/lib/hecks/bluebook/assembly/contracts/rules.rb +4 -2
- data/lib/hecks/bluebook/assembly/contracts/structure.rb +3 -1
- data/lib/hecks/bluebook/assembly/marks.rb +4 -15
- data/lib/hecks/bluebook/assembly/scalars.rb +39 -0
- data/lib/hecks/bluebook/attribute.rb +1 -1
- data/lib/hecks/bluebook/behaviour/command.rb +13 -8
- data/lib/hecks/bluebook/behaviour/policy.rb +30 -0
- data/lib/hecks/bluebook/capabilities/attribute_values.rb +72 -0
- data/lib/hecks/bluebook/capabilities.rb +91 -9
- data/lib/hecks/bluebook/domain_port.rb +16 -4
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +18 -6
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +13 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/computed_sources.rb +98 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/fan_out_rows.rb +42 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/projected_fields.rb +14 -2
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/provisions.rb +69 -3
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/with_projections.rb +17 -10
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +5 -0
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -0
- data/lib/hecks/bluebook/dsl/command_builder/mutations.rb +8 -1
- data/lib/hecks/bluebook/dsl/command_builder/operands.rb +121 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +2 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +10 -1
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +45 -2
- data/lib/hecks/bluebook/dsl/policy_builder.rb +47 -10
- data/lib/hecks/bluebook/dsl/rule_reference.rb +7 -4
- data/lib/hecks/bluebook/dsl/world_builder.rb +1 -1
- data/lib/hecks/bluebook/expression/ast_json/emitters.rb +6 -0
- data/lib/hecks/bluebook/expression/ast_json.rb +9 -6
- data/lib/hecks/bluebook/expression/ast_reader.rb +14 -9
- data/lib/hecks/bluebook/expression/projection.json +36 -0
- data/lib/hecks/bluebook/expression/resolver/operations.rb +31 -0
- data/lib/hecks/bluebook/expression/resolver/parsing.rb +38 -5
- data/lib/hecks/bluebook/expression/resolver/scanning.rb +22 -5
- data/lib/hecks/bluebook/expression/resolver/values.rb +10 -0
- data/lib/hecks/bluebook/expression/resolver.rb +20 -1
- data/lib/hecks/bluebook/hecksagon.rb +23 -3
- data/lib/hecks/bluebook/lifecycle.rb +22 -3
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +13 -1
- data/lib/hecks/bluebook/meta_validator/modes.rb +4 -1
- data/lib/hecks/bluebook/meta_validator/readings.rb +24 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +2 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +6 -3
- data/lib/hecks/bluebook/meta_validator/shapes.rb +5 -0
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +1 -1
- data/lib/hecks/bluebook/meta_validator.rb +12 -12
- data/lib/hecks/bluebook/model_check/ask_checks.rb +71 -0
- data/lib/hecks/bluebook/model_check/policy_checks.rb +2 -1
- data/lib/hecks/bluebook/model_check/reference_checks.rb +70 -0
- data/lib/hecks/bluebook/model_check.rb +8 -2
- data/lib/hecks/bluebook/policy.rb +4 -2
- data/lib/hecks/bluebook/smoke_test.rb +1 -1
- data/lib/hecks/bluebook/synthesizer.rb +2 -0
- data/lib/hecks/bluebook.rb +2 -0
- data/lib/hecks/cli/command_table.rb +1 -1
- data/lib/hecks/cli/console.rb +2 -1
- data/lib/hecks/cli/document.rb +1 -1
- data/lib/hecks/cli/launcher_words.rb +4 -4
- data/lib/hecks/cli/mcp.rb +4 -4
- data/lib/hecks/cli/project_cli/launcher_source.rb +2 -2
- data/lib/hecks/cli/project_cli/templates.rb +5 -5
- data/lib/hecks/cli/project_cli.rb +9 -6
- data/lib/hecks/cli/run.rb +2 -2
- data/lib/hecks/cli/smoke_http/checks.rb +4 -1
- data/lib/hecks/cli/smoke_http/transport.rb +3 -3
- data/lib/hecks/cli/smoke_http.rb +3 -0
- data/lib/hecks/codemod.rb +5 -2
- data/lib/hecks/corpus/routes.rb +7 -0
- data/lib/hecks/corpus/rust.rb +3 -2
- data/lib/hecks/deploy/bluebook/deploy.bluebook +34 -4
- data/lib/hecks/doc/reference/rendering.rb +6 -3
- data/lib/hecks/forms/app/commands.rb +8 -7
- data/lib/hecks/forms/app/queries.rb +2 -1
- data/lib/hecks/forms/app.rb +1 -1
- data/lib/hecks/forms/record_renderer.rb +1 -1
- data/lib/hecks/framework/bluebook/privacy.bluebook +11 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +4 -1
- data/lib/hecks/fuzzing/failure_triage.rb +2 -1
- data/lib/hecks/fuzzing/mutation/run.rb +11 -4
- data/lib/hecks/fuzzing/properties/catalog.rb +6 -4
- data/lib/hecks/fuzzing/properties/guaranteed_by_construction.rb +18 -11
- data/lib/hecks/fuzzing/properties/guards.rb +1 -1
- data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +1 -1
- data/lib/hecks/fuzzing/self_consistency.rb +6 -2
- data/lib/hecks/fuzzing/shrinker.rb +3 -1
- data/lib/hecks/fuzzing/value_generator.rb +19 -5
- data/lib/hecks/gate/stages.yml +33 -7
- data/lib/hecks/grammar/evolve.rb +1 -1
- data/lib/hecks/grammar/expression_operators.json +372 -0
- data/lib/hecks/grammar/operators.rb +3 -1
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +10 -10
- data/lib/hecks/hecks/adapters/codebase/inspection/rubycritic.rb +35 -0
- data/lib/hecks/hecks/adapters/codebase/inspection.rb +104 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +2 -1
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +12 -2
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +2 -1
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +1 -1
- data/lib/hecks/hecks/adapters/cost_explorer.rb +8 -5
- data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +2 -1
- data/lib/hecks/hecks/adapters/finding_github.rb +13 -6
- data/lib/hecks/hecks/adapters/first_admin.rb +2 -2
- data/lib/hecks/hecks/adapters/github_rulesets.rb +6 -3
- data/lib/hecks/hecks/adapters/in_process_boot.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +10 -20
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +28 -5
- data/lib/hecks/hecks/adapters/local_files.rb +2 -2
- data/lib/hecks/hecks/adapters/rehearsal/audit_report.rb +107 -0
- data/lib/hecks/hecks/adapters/rehearsal/census.rb +71 -0
- data/lib/hecks/hecks/adapters/rehearsal/declaration.rb +133 -0
- data/lib/hecks/hecks/adapters/rehearsal/environment.rb +83 -0
- data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +142 -0
- data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +96 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_census.rb +100 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +69 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_store.rb +133 -0
- data/lib/hecks/hecks/adapters/rehearsal/rows.rb +41 -0
- data/lib/hecks/hecks/adapters/rehearsal/rust_audit.rb +83 -0
- data/lib/hecks/hecks/adapters/rehearsal/subject.rb +104 -0
- data/lib/hecks/hecks/adapters/rehearsal.rb +54 -0
- data/lib/hecks/hecks/adapters/rehearsal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/rehearsal_store.rb +81 -0
- data/lib/hecks/hecks/adapters/terminal.rb +13 -11
- data/lib/hecks/hecks/codebase.behaviors +13 -1
- data/lib/hecks/hecks/codebase.bluebook +239 -5
- data/lib/hecks/hecks/custodian.behaviors +24 -6
- data/lib/hecks/hecks/custodian.bluebook +6 -1227
- data/lib/hecks/hecks/deploy.behaviors +1 -1
- data/lib/hecks/hecks/deploy.world +1 -3
- data/lib/hecks/hecks/hecks.behaviors +1 -1
- data/lib/hecks/hecks/hecks.hecksagon +53 -18
- data/lib/hecks/hecks/hecks.world +13 -10
- data/lib/hecks/hecks/rehearsal.bluebook +477 -0
- data/lib/hecks/hecks/site.behaviors +1 -1
- data/lib/hecks/hecks/site.world +0 -1
- data/lib/hecks/hecks/tooling.bluebook +1238 -0
- data/lib/hecks/indifferent_key.rb +20 -0
- data/lib/hecks/language/adapter.bluebook +13 -3
- data/lib/hecks/language/bluebook/aggregate.bluebook +23 -0
- data/lib/hecks/language/bluebook/bluebook.behaviors +23 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -0
- data/lib/hecks/language/bluebook/entity.bluebook +18 -0
- data/lib/hecks/language/bluebook/policy.behaviors +19 -0
- data/lib/hecks/language/bluebook/policy.bluebook +9 -1
- data/lib/hecks/language/bluebook/query.bluebook +1 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +63 -4
- data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -1
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +22 -0
- data/lib/hecks/language/oidc.json +10 -0
- data/lib/hecks/language/port.bluebook +4 -4
- data/lib/hecks/literal.rb +12 -3
- data/lib/hecks/ports/key_vault.rb +7 -2
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +21 -10
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +4 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +2 -1
- data/lib/hecks/ports/persistence/repository_factory.rb +6 -3
- data/lib/hecks/projection_files/expression_tables.rb +7 -2
- data/lib/hecks/projections/deploy/box/compose.rb +6 -4
- data/lib/hecks/projections/deploy/box/edge.rb +62 -0
- data/lib/hecks/projections/deploy/box/logging.rb +99 -0
- data/lib/hecks/projections/deploy/box/roll_scripts.rb +16 -8
- data/lib/hecks/projections/deploy/box/settings/cdn.rb +40 -0
- data/lib/hecks/projections/deploy/box/settings/logs.rb +40 -0
- data/lib/hecks/projections/deploy/box/settings/patterns.rb +11 -0
- data/lib/hecks/projections/deploy/box/settings/types.rb +16 -1
- data/lib/hecks/projections/deploy/box/settings.rb +6 -2
- data/lib/hecks/projections/deploy/box/stack_yaml.rb +5 -2
- data/lib/hecks/projections/deploy/box/templates/Makefile.tmpl +16 -0
- data/lib/hecks/projections/deploy/box/templates/box.yaml.tmpl +8 -4
- data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +32 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/box/templates/edge.mk.tmpl +17 -0
- data/lib/hecks/projections/deploy/box/templates/edge.yaml.tmpl +65 -0
- data/lib/hecks/projections/deploy/box/templates/log-group.yaml.tmpl +12 -0
- data/lib/hecks/projections/deploy/box/templates/log-policy.yaml.tmpl +7 -0
- data/lib/hecks/projections/deploy/box/templates/render-compose-taskdef.sh.tmpl +5 -4
- data/lib/hecks/projections/deploy/box/templates/render-compose.sh.tmpl +5 -4
- data/lib/hecks/projections/deploy/box.rb +15 -3
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/shared.rb +5 -2
- data/lib/hecks/projections/model/deviations.rb +2 -2
- data/lib/hecks/projections/model.rb +2 -2
- data/lib/hecks/projections/oidc.rb +13 -1
- data/lib/hecks/projections/shape.rb +5 -2
- data/lib/hecks/projections/site/cms_editor/attributes.rb +26 -6
- data/lib/hecks/projections/site/cms_editor/blocks.rb +157 -0
- data/lib/hecks/projections/site/cms_editor/checks.rb +14 -1
- data/lib/hecks/projections/site/cms_editor/clearing.rb +70 -0
- data/lib/hecks/projections/site/cms_editor/color.rb +124 -0
- data/lib/hecks/projections/site/cms_editor/composition.rb +42 -0
- data/lib/hecks/projections/site/cms_editor/destructive.rb +61 -0
- data/lib/hecks/projections/site/cms_editor/drafts.rb +102 -0
- data/lib/hecks/projections/site/cms_editor/hints.rb +74 -0
- data/lib/hecks/projections/site/cms_editor/icons.rb +86 -0
- data/lib/hecks/projections/site/cms_editor/key_kinds.rb +31 -0
- data/lib/hecks/projections/site/cms_editor/limits.rb +72 -0
- data/lib/hecks/projections/site/cms_editor/media.rb +1 -1
- data/lib/hecks/projections/site/cms_editor/moment.rb +34 -0
- data/lib/hecks/projections/site/cms_editor/palette.rb +115 -0
- data/lib/hecks/projections/site/cms_editor/pickers.rb +85 -0
- data/lib/hecks/projections/site/cms_editor/preview.rb +91 -0
- data/lib/hecks/projections/site/cms_editor/relations.rb +92 -0
- data/lib/hecks/projections/site/cms_editor/scale_checks.rb +66 -0
- data/lib/hecks/projections/site/cms_editor/scheduling.rb +150 -0
- data/lib/hecks/projections/site/cms_editor/schema.rb +96 -19
- data/lib/hecks/projections/site/cms_editor/setting.rb +52 -9
- data/lib/hecks/projections/site/cms_editor/targets.rb +86 -0
- data/lib/hecks/projections/site/cms_editor/templates/package.json.tmpl +18 -1
- data/lib/hecks/projections/site/cms_editor/templates/src/app.ts.tmpl +251 -57
- data/lib/hecks/projections/site/cms_editor/templates/src/assets.ts.tmpl +98 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/auth/membership.ts.tmpl +32 -24
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/app.css.tmpl +412 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/autosave.js.tmpl +144 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/blocks.js.tmpl +500 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_doc.js.tmpl +175 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_editor.js.tmpl +418 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/epoch.js.tmpl +61 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/forms.js.tmpl +210 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/lists.js.tmpl +40 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/main.js.tmpl +26 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/media_picker.js.tmpl +232 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/moments.js.tmpl +73 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/pickers.js.tmpl +152 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/preview.js.tmpl +98 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/shell.js.tmpl +140 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/toast.js.tmpl +66 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/choices.ts.tmpl +99 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/commands.ts.tmpl +78 -24
- data/lib/hecks/projections/site/cms_editor/templates/src/config.ts.tmpl +6 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/flash.ts.tmpl +52 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/host.ts.tmpl +19 -2
- data/lib/hecks/projections/site/cms_editor/templates/src/media/handler.ts.tmpl +31 -8
- data/lib/hecks/projections/site/cms_editor/templates/src/names.ts.tmpl +36 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/schema.ts.tmpl +131 -2
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/availability.ts.tmpl +15 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/block_list.js.tmpl +213 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/blocks.ts.tmpl +275 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_model.js.tmpl +8 -5
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/detail.ts.tmpl +88 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/dialogs.ts.tmpl +43 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/fields.ts.tmpl +229 -34
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/html.ts.tmpl +40 -81
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/icons.ts.tmpl +15 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/input.ts.tmpl +29 -12
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/links.ts.tmpl +100 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/moments.ts.tmpl +44 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/outline.ts.tmpl +53 -17
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/pages.ts.tmpl +178 -88
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/paging.ts.tmpl +82 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/pickers.ts.tmpl +110 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/preview.ts.tmpl +87 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/related.ts.tmpl +97 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/schedule.ts.tmpl +160 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/shell.ts.tmpl +211 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/table.ts.tmpl +151 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/theme.js.tmpl +16 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/values.ts.tmpl +69 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/words.ts.tmpl +97 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/world.ts.tmpl +35 -0
- data/lib/hecks/projections/site/cms_editor/templates/tsconfig.json.tmpl +2 -1
- data/lib/hecks/projections/site/cms_editor/theme.rb +29 -0
- data/lib/hecks/projections/site/cms_editor/theme_checks.rb +57 -0
- data/lib/hecks/projections/site/cms_editor.rb +49 -23
- data/lib/hecks/projections/site/role_probe.rb +2 -0
- data/lib/hecks/projections/site/site_root/workflow.rb +5 -0
- data/lib/hecks/projector/cli_audience.rb +22 -1
- data/lib/hecks/projector/cli_projector/listing.rb +1 -1
- data/lib/hecks/projector/cli_projector/option_specs.rb +1 -1
- data/lib/hecks/projector/cli_projector/usage.rb +15 -4
- data/lib/hecks/projector/docs_projector/closing.rb +1 -1
- data/lib/hecks/projector/docs_projector.rb +1 -1
- data/lib/hecks/projector/exporter/bindings.rb +40 -10
- data/lib/hecks/projector/exporter/capability_values.rb +55 -0
- data/lib/hecks/projector/narrate_projector/reactions.rb +1 -1
- data/lib/hecks/projector/target.rb +11 -0
- data/lib/hecks/projector.rb +32 -5
- data/lib/hecks/quality_control/adapters/github_checks.rb +12 -8
- data/lib/hecks/quality_control/adapters/github_issues.rb +8 -4
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +2 -2
- data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep.rb +1 -1
- data/lib/hecks/quality_control/quality_control.bluebook +6 -2
- data/lib/hecks/release/approval.rb +64 -0
- data/lib/hecks/router/{door.rb → aggregate_reader.rb} +5 -4
- data/lib/hecks/router/namespace_installer.rb +16 -16
- data/lib/hecks/router.rb +1 -1
- data/lib/hecks/runtime/best_effort.rb +22 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +12 -2
- data/lib/hecks/runtime/command_interpreter.rb +3 -2
- data/lib/hecks/runtime/command_rules/emission.rb +1 -1
- data/lib/hecks/runtime/dispatcher.rb +4 -4
- data/lib/hecks/runtime/entity_element/location.rb +1 -1
- data/lib/hecks/runtime/event.rb +5 -0
- data/lib/hecks/runtime/identity.rb +7 -6
- data/lib/hecks/runtime/interpreting.rb +2 -1
- data/lib/hecks/runtime/invocation_builder.rb +1 -1
- data/lib/hecks/runtime/loader/boot_steps.rb +8 -5
- data/lib/hecks/runtime/loader.rb +10 -10
- data/lib/hecks/runtime/policy_interpreter/arguments.rb +7 -4
- data/lib/hecks/runtime/policy_interpreter/fan_out.rb +3 -3
- data/lib/hecks/runtime/policy_interpreter.rb +6 -6
- data/lib/hecks/runtime/port_operation_interpreter.rb +1 -1
- data/lib/hecks/runtime/reaction_invocation.rb +1 -1
- data/lib/hecks/runtime/rebuild_sweep.rb +11 -1
- data/lib/hecks/runtime/registry/ask_verification.rb +35 -0
- data/lib/hecks/runtime/registry/hecksagon_rules.rb +10 -0
- data/lib/hecks/runtime/registry/merging.rb +1 -1
- data/lib/hecks/runtime/registry/providers.rb +16 -0
- data/lib/hecks/runtime/registry/read_repository.rb +6 -4
- data/lib/hecks/runtime/registry/verification.rb +4 -1
- data/lib/hecks/runtime/registry/world_defaults.rb +29 -0
- data/lib/hecks/runtime/registry.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter/compensation.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter/delivery.rb +4 -4
- data/lib/hecks/runtime/saga_interpreter/transitions.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter.rb +3 -3
- data/lib/hecks/runtime/tenant_check.rb +5 -4
- data/lib/hecks/runtime/value/coercion.rb +2 -2
- data/lib/hecks/runtime/value/validation.rb +16 -4
- data/lib/hecks/runtime.rb +9 -9
- data/lib/hecks/rust_build/host.rb +11 -4
- data/lib/hecks/rust_build/prebuilt_binary.rb +101 -0
- data/lib/hecks/rust_build/project_rust/target_ir.rb +1 -1
- data/lib/hecks/rust_build/wasm.rb +1 -1
- data/lib/hecks/rust_build/wasm_browser.rb +1 -1
- data/lib/hecks/rust_build.rb +11 -0
- data/lib/hecks/served_options.rb +53 -0
- data/lib/hecks/site/bluebook/site.bluebook +1 -0
- data/lib/hecks/storehouse/audit.rb +1 -1
- data/lib/hecks/storehouse/dispatching.rb +8 -6
- data/lib/hecks/storehouse/introspection.rb +2 -2
- data/lib/hecks/storehouse/querying.rb +6 -4
- data/lib/hecks/storehouse.rb +4 -4
- data/lib/hecks/tools/ci_gate_decision.rb +35 -0
- data/lib/hecks/tools/ci_gates.rb +20 -1
- data/lib/hecks/tools/comment_style/source_file.rb +4 -1
- data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +4 -1
- data/lib/hecks/tools/lanes/files.rb +8 -0
- data/lib/hecks/tools/lanes/prebuilt_workflow.rb +81 -0
- data/lib/hecks/tools/lanes/rows.rb +6 -0
- data/lib/hecks/tools/lanes.rb +1 -0
- data/lib/hecks/tools/oidc_manifests.rb +4 -5
- data/lib/hecks/tools/regeneration_run.rb +11 -4
- data/lib/hecks/tools/release_only.rb +111 -0
- data/lib/hecks/tools/site_routes/editor_files.rb +12 -5
- data/lib/hecks/tools/tenant_provisioning.rb +2 -2
- data/lib/hecks/tools/tools_doc.rb +4 -4
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +19 -5
- data/lib/hecks.rb +15 -15
- data/lib/rubocop/cop/hecks/env_dump.rb +69 -0
- data/lib/rubocop/cop/hecks/monotonic_duration.rb +53 -0
- data/lib/rubocop/cop/hecks/no_wall_clock_in_runtime.rb +34 -0
- data/lib/rubocop/cop/hecks/raw_shell_interpolation.rb +79 -0
- data/lib/rubocop/cop/hecks/sleep_in_spec.rb +34 -0
- data/lib/rubocop/cop/hecks/swallowed_rescue.rb +37 -0
- data/lib/rubocop/cop/hecks/symbol_string_key_mix.rb +50 -0
- data/lib/rubocop/cop/hecks/untyped_raise.rb +37 -0
- data/prebuilt/9ee54e2f0d4d6d3fe046827779b221e02de665fba911a048ae5dd8b8fbfb7d90.marshal +0 -0
- data/prebuilt/d74a00e996222c1d8b676d5959092effc46b4dc59e0555f3bf9554ac58e3094a.marshal +0 -0
- data/prebuilt/verdicts-df19f35868d3284a70f55e42dcef87ef4e65e6a678e5135f72e1f6cff4c1357b.json +1 -0
- data/rust/.gitignore +6 -0
- data/rust/Cargo.toml +6 -0
- data/rust/build/src/binding_pass.rs +103 -0
- data/rust/build/src/cargo_sync.rs +6 -0
- data/rust/build/src/lineage_pass.rs +3 -3
- data/rust/build/src/main.rs +17 -5
- data/rust/build/src/pipeline.rs +48 -5
- data/rust/build/src/seams_pass.rs +123 -0
- data/rust/build/src/translation_pass.rs +167 -0
- data/rust/codegen/src/asks.rs +103 -0
- data/rust/codegen/src/commands.rs +13 -8
- data/rust/codegen/src/constraints.rs +25 -0
- data/rust/codegen/src/domain_generator.rs +2 -0
- data/rust/codegen/src/expr_emitter.rs +13 -0
- data/rust/codegen/src/json_codec.rs +54 -15
- data/rust/codegen/src/main.rs +1 -0
- data/rust/codegen/src/mutations.rs +128 -3
- data/rust/codegen/src/queries.rs +11 -2
- data/rust/codegen/src/reactions.rs +1 -1
- data/rust/codegen/src/types.rs +166 -8
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/src/api.rs +4 -4
- data/rust/host/src/bin/validate_harness.rs +43 -0
- data/rust/host/src/boundary_fuzz/expr_json.rs +2 -2
- data/rust/host/src/boundary_fuzz/ir.rs +1 -0
- data/rust/host/src/boundary_fuzz/server.rs +1 -1
- data/rust/host/src/checkout.rs +35 -19
- data/rust/host/src/commerce_ir.rs +408 -2
- data/rust/host/src/expr_json.rs +118 -0
- data/rust/host/src/extension.rs +13 -1
- data/rust/host/src/lib.rs +1 -0
- data/rust/host/src/mint.rs +1 -1
- data/rust/host/src/payments/tests.rs +27 -1
- data/rust/host/src/payments.rs +12 -4
- data/rust/host/src/platform_signin/attack_tests.rs +1100 -0
- data/rust/host/src/platform_signin/config.rs +512 -0
- data/rust/host/src/platform_signin/cookie.rs +237 -0
- data/rust/host/src/platform_signin/extension.rs +190 -0
- data/rust/host/src/platform_signin/fetcher.rs +322 -0
- data/rust/host/src/platform_signin/handler.rs +251 -0
- data/rust/host/src/platform_signin/handler_tests.rs +554 -0
- data/rust/host/src/platform_signin/jti.rs +196 -0
- data/rust/host/src/platform_signin/jwks.rs +542 -0
- data/rust/host/src/platform_signin/jws.rs +249 -0
- data/rust/host/src/platform_signin/known_answer_tests.rs +237 -0
- data/rust/host/src/platform_signin/mapping_tests.rs +254 -0
- data/rust/host/src/platform_signin/mod.rs +75 -0
- data/rust/host/src/platform_signin/mode_tests.rs +382 -0
- data/rust/host/src/platform_signin/pages.rs +204 -0
- data/rust/host/src/platform_signin/query.rs +233 -0
- data/rust/host/src/platform_signin/session.rs +151 -0
- data/rust/host/src/platform_signin/settings.rs +385 -0
- data/rust/host/src/platform_signin/strict_json.rs +351 -0
- data/rust/host/src/platform_signin/test_support.rs +235 -0
- data/rust/host/src/platform_signin/ttl_tests.rs +94 -0
- data/rust/host/src/platform_signin/verify.rs +604 -0
- data/rust/host/src/platform_signin/wiring_support.rs +319 -0
- data/rust/host/src/query_step.rs +22 -4
- data/rust/host/src/reference_validate.rs +653 -108
- data/rust/host/src/resend.rs +2 -0
- data/rust/host/src/server.rs +19 -6
- data/rust/host/src/ui_schema.rs +132 -5
- data/rust/host/src/web/newsletter.rs +7 -8
- data/rust/host/src/web/newsletter_send.rs +38 -13
- data/rust/host/src/web/registrations.rs +229 -26
- data/rust/host/src/web.rs +53 -9
- data/rust/parser/src/emit.rs +38 -6
- data/rust/parser/src/expr/ast_json.rs +7 -1
- data/rust/parser/src/expr/resolver.rs +171 -6
- data/rust/parser/src/ir.rs +7 -0
- data/rust/parser/src/keywords.rs +24 -0
- data/rust/parser/src/main.rs +3 -0
- data/rust/parser/src/parse/aggregate.rs +2 -1
- data/rust/parser/src/parse/chapter.rs +2 -2
- data/rust/parser/src/parse/command.rs +2 -0
- data/rust/parser/src/parse/hecksagon.rs +5 -2
- data/rust/parser/src/parse/lifecycle.rs +81 -0
- data/rust/parser/src/parse/mod.rs +15 -1
- data/rust/parser/src/parse/policy.rs +13 -2
- data/rust/parser/src/parse/value_object.rs +34 -17
- data/rust/parser/src/ruby_value.rs +1 -1
- data/rust/src/exemplar/commands.rs +4 -4
- data/rust/src/exemplar/constraints.rs +1 -1
- data/rust/src/exemplar/json.rs +43 -1
- data/rust/src/kernel/cli.rs +7 -5
- data/rust/src/kernel/dispatch.rs +2 -2
- data/rust/src/kernel/dispatch_guard_tests.rs +1 -1
- data/rust/src/kernel/expr.rs +66 -3
- data/rust/src/kernel/expression_operators/arithmetic.rs +130 -5
- data/rust/src/kernel/expression_operators/text.rs +26 -2
- data/rust/src/kernel/json.rs +15 -0
- data/rust/src/kernel/mod.rs +1 -1
- data/rust/src/kernel/orchestrate.rs +54 -5
- data/rust/src/kernel/orchestrate_guard_tests.rs +67 -0
- data/rust/src/kernel/pattern.rs +60 -0
- data/rust/src/kernel/reference_lookup.rs +90 -7
- metadata +178 -38
- data/lib/hecks/doors/cli_door/nesting.rb +0 -34
- data/lib/hecks/doors/cli_door/shorthand.rb +0 -85
- data/lib/hecks/doors/cli_door.rb +0 -124
- data/lib/hecks/doors/cli_runner/answers.rb +0 -138
- data/lib/hecks/doors/cli_runner/resolution.rb +0 -146
- data/lib/hecks/doors/cli_runner/settling.rb +0 -115
- data/lib/hecks/doors/cli_runner/streaming.rb +0 -90
- data/lib/hecks/doors/cli_runner/suggestions.rb +0 -43
- data/lib/hecks/doors/cli_runner.rb +0 -66
- data/lib/hecks/doors/command_request.rb +0 -119
- data/lib/hecks/doors/handle.rb +0 -208
- data/lib/hecks/doors/json_door.rb +0 -132
- data/lib/hecks/doors/launcher_options.rb +0 -247
- data/lib/hecks/doors/mcp_door/properties.rb +0 -47
- data/lib/hecks/doors/mcp_door/tool_calls.rb +0 -113
- data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +0 -51
- data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +0 -69
- data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +0 -97
- data/lib/hecks/doors/mcp_door/tool_definitions.rb +0 -15
- data/lib/hecks/doors/mcp_door.rb +0 -156
- data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +0 -92
- data/lib/hecks/doors/mcp_door_scope/env_problems.rb +0 -55
- data/lib/hecks/doors/mcp_door_scope/presenter.rb +0 -78
- data/lib/hecks/doors/mcp_door_scope.rb +0 -201
- data/lib/hecks/doors/mcp_guide_cache.rb +0 -75
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +0 -162
- data/lib/hecks/doors/ruby_door/chapter.rb +0 -89
- data/lib/hecks/doors/ruby_door.rb +0 -80
- data/lib/hecks/doors/usage_cache.rb +0 -139
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_widget.js.tmpl +0 -282
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/media_picker.js.tmpl +0 -109
- data/prebuilt/c28d6d9db14eea3e17161e9d9c262efee30b256cf97693a7cfd552bce24b2f7f.marshal +0 -0
- data/prebuilt/cb375cba61ca0dbe8ddb9739c306510fe05e5f4b7a9b6955caff8224c63ea0e0.marshal +0 -0
- data/prebuilt/verdicts-d6d584ad43b5f3cebf88aafbbdbf024c38574acf18e06adffbc555f7786b1c2f.json +0 -1
data/lib/hecks/rust_build.rb
CHANGED
|
@@ -83,6 +83,17 @@ module Hecks
|
|
|
83
83
|
raise Failure, "`#{command.join(" ")}` failed#{" in #{chdir}" if chdir}"
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
+
# Asks rustup whether a compile target is installed for the active toolchain.
|
|
87
|
+
#
|
|
88
|
+
# @param target [String] the target triple, such as `wasm32-unknown-unknown`
|
|
89
|
+
# @return [Boolean] false when rustup is missing or does not list the target
|
|
90
|
+
def target_installed?(target)
|
|
91
|
+
listed = IO.popen(["rustup", "target", "list", "--installed", { err: File::NULL }], &:read)
|
|
92
|
+
listed.split("\n").include?(target)
|
|
93
|
+
rescue SystemCallError
|
|
94
|
+
false
|
|
95
|
+
end
|
|
96
|
+
|
|
86
97
|
# Runs a tool and holds what it printed.
|
|
87
98
|
#
|
|
88
99
|
# @param tool [String] a key of `TOOLS`
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require "rack"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
# What a domain's world file says it is served by: each `served_by("Adapter") { ... }` line
|
|
5
|
+
# names an inbound adapter and the per-environment values it needs. The route is derived,
|
|
6
|
+
# never written: a driving adapter answers at `/webhooks/<adapter name, snake-cased>` unless
|
|
7
|
+
# its `path` says otherwise, so a world holds only what the domain cannot know (secret,
|
|
8
|
+
# path override) and the same domain can be served differently in each environment.
|
|
9
|
+
#
|
|
10
|
+
# A secret is named by the environment variable that holds it, never inline.
|
|
11
|
+
module ServedOptions
|
|
12
|
+
VERB = "served_by".freeze
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
# @param world [Bluebook::World, nil] a domain's judged world
|
|
17
|
+
# @return [Array<Hash>] one entry per `served_by` line: `adapter`, `path` and its settings
|
|
18
|
+
def entries(world)
|
|
19
|
+
return [] unless world
|
|
20
|
+
|
|
21
|
+
world.settings.filter_map do |key, values|
|
|
22
|
+
next unless key.to_s.start_with?("#{VERB}:")
|
|
23
|
+
|
|
24
|
+
adapter = values.fetch(:adapter)
|
|
25
|
+
values.merge(adapter: adapter, path: values.fetch(:path) { "/webhooks/#{snake(adapter)}" })
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# A Rack app mounting every `served_by` adapter the world names at its derived path.
|
|
30
|
+
#
|
|
31
|
+
# @param world [Bluebook::World, nil]
|
|
32
|
+
# @param adapters [Hash{String => Class}] driving adapter classes by the name a world uses;
|
|
33
|
+
# each is built with `secret:` read from the environment variable the line names
|
|
34
|
+
# @param env [#fetch] where secrets are read from (`ENV` in production)
|
|
35
|
+
# @return [Rack::URLMap]
|
|
36
|
+
# @raise [KeyError] when a line names an adapter no class answers for
|
|
37
|
+
# @raise [ArgumentError] when a line names a secret variable the environment does not hold
|
|
38
|
+
def rack_app(world, adapters:, env: ENV)
|
|
39
|
+
routes = entries(world).to_h do |entry|
|
|
40
|
+
klass = adapters.fetch(entry[:adapter])
|
|
41
|
+
[entry[:path], klass.new(secret: secret_for(entry, env))]
|
|
42
|
+
end
|
|
43
|
+
Rack::URLMap.new(routes)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def secret_for(entry, env)
|
|
47
|
+
name = entry.fetch(:secret) { raise ArgumentError, "#{entry[:adapter]} names no secret" }
|
|
48
|
+
env.fetch(name) { raise ArgumentError, "#{entry[:adapter]}: environment variable #{name} is not set" }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def snake(name) = name.to_s.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -33,7 +33,7 @@ module Hecks
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
# Tails this bus's own dispatch/query/state audit log — a pull-based
|
|
36
|
-
# substitute for a push subscription, since a stdio
|
|
36
|
+
# substitute for a push subscription, since a stdio server answers one
|
|
37
37
|
# request at a time with no channel to push through.
|
|
38
38
|
#
|
|
39
39
|
# @param runtime [Runtime::Registry] the booted domain to tail
|
|
@@ -34,9 +34,9 @@ module Hecks
|
|
|
34
34
|
|
|
35
35
|
# :nodoc:
|
|
36
36
|
def command_envelope(args, spec)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
Adapters::Driving::CommandRequest.normalize(Adapters::Driving::Json.deep_symbolize(args),
|
|
38
|
+
receiver: spec[:receiver],
|
|
39
|
+
legacy_receiver: spec[:legacy_receiver])
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
# :nodoc:
|
|
@@ -52,7 +52,9 @@ module Hecks
|
|
|
52
52
|
ok(summary: summary,
|
|
53
53
|
id: result.id,
|
|
54
54
|
state: settled_state(runtime, spec, result),
|
|
55
|
-
events: result.events.map
|
|
55
|
+
events: result.events.map do |event|
|
|
56
|
+
{ name: event.name, payload: Adapters::Driving::Json.materialize(event.payload) }
|
|
57
|
+
end)
|
|
56
58
|
end
|
|
57
59
|
|
|
58
60
|
# The record as its repository holds it once every reaction has run, which is the state the
|
|
@@ -65,7 +67,7 @@ module Hecks
|
|
|
65
67
|
def settled_state(runtime, spec, result)
|
|
66
68
|
return if result.state.nil?
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
Adapters::Driving::Json.materialize(settled_record(runtime, spec, result) || result.state)
|
|
69
71
|
end
|
|
70
72
|
|
|
71
73
|
# :nodoc:
|
|
@@ -141,7 +143,7 @@ module Hecks
|
|
|
141
143
|
|
|
142
144
|
# :nodoc:
|
|
143
145
|
def batch_step(runtime, raw, summary, options)
|
|
144
|
-
step =
|
|
146
|
+
step = Adapters::Driving::Json.deep_symbolize(raw)
|
|
145
147
|
dispatch(runtime: runtime, command: step[:command], args: step[:args] || {}, summary: summary, **options)
|
|
146
148
|
end
|
|
147
149
|
end
|
|
@@ -68,7 +68,7 @@ module Hecks
|
|
|
68
68
|
# @return [Hash] {ok: true, domain:, valid: true} plus :findings when deep;
|
|
69
69
|
# {ok: false, domain:, valid: false, error:} if the boot itself failed
|
|
70
70
|
def validate(domain:, deep: false)
|
|
71
|
-
runtime = Hecks.boot(confine!(domain, "domain"),
|
|
71
|
+
runtime = Hecks.boot(confine!(domain, "domain"), install_driving: false)
|
|
72
72
|
result = { ok: true, domain: domain, valid: true }
|
|
73
73
|
result[:findings] = model_findings(runtime) if deep
|
|
74
74
|
result
|
|
@@ -103,7 +103,7 @@ module Hecks
|
|
|
103
103
|
|
|
104
104
|
# :nodoc:
|
|
105
105
|
def journal_entries(repository)
|
|
106
|
-
repository.entries.map { |entry| { operation: entry.operation, id: entry.id, state:
|
|
106
|
+
repository.entries.map { |entry| { operation: entry.operation, id: entry.id, state: Adapters::Driving::Json.materialize(entry.state) } }
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# Runs a domain's hand-curated .behaviors examples and reports the results.
|
|
@@ -27,12 +27,14 @@ module Hecks
|
|
|
27
27
|
spec = resolve!(cli_for(request.bluebook), request.name, asking: true)
|
|
28
28
|
rows = with_caller(request.role, request.actor_id) { answer(request, spec) }
|
|
29
29
|
|
|
30
|
-
ok(summary: request.summary, rows: rows.map
|
|
30
|
+
ok(summary: request.summary, rows: rows.map do |row|
|
|
31
|
+
Adapters::Driving::Json.materialize(row)
|
|
32
|
+
end).merge(verb: spec[:command])
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
# :nodoc:
|
|
34
36
|
def answer(request, spec)
|
|
35
|
-
request.runtime.query(spec[:command], **
|
|
37
|
+
request.runtime.query(spec[:command], **Adapters::Driving::Json.deep_symbolize(request.args))
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
# Reads one aggregate's stored records directly, bypassing any declared
|
|
@@ -63,7 +65,7 @@ module Hecks
|
|
|
63
65
|
repository = runtime.registry.repository(bluebook.name, ir)
|
|
64
66
|
return ok(summary: summary, record: single_record(repository, ir, id)) if id
|
|
65
67
|
|
|
66
|
-
records = repository.all.map { |instance|
|
|
68
|
+
records = repository.all.map { |instance| Adapters::Driving::Json.materialize(instance.to_h) }
|
|
67
69
|
ok(summary: summary, count: records.length, records: records)
|
|
68
70
|
end
|
|
69
71
|
|
|
@@ -71,7 +73,7 @@ module Hecks
|
|
|
71
73
|
def single_record(repository, aggregate_ir, identity)
|
|
72
74
|
instance = repository.find(identity) or
|
|
73
75
|
raise Runtime::NotFound, "no #{aggregate_ir.hecks_name} found for id #{identity.inspect}"
|
|
74
|
-
|
|
76
|
+
Adapters::Driving::Json.materialize(instance.to_h)
|
|
75
77
|
end
|
|
76
78
|
end
|
|
77
79
|
end
|
data/lib/hecks/storehouse.rb
CHANGED
|
@@ -3,8 +3,8 @@ require "json"
|
|
|
3
3
|
require "fileutils"
|
|
4
4
|
require "time"
|
|
5
5
|
require_relative "cache_dir"
|
|
6
|
-
require_relative "
|
|
7
|
-
require_relative "
|
|
6
|
+
require_relative "adapters/driving/command_request"
|
|
7
|
+
require_relative "adapters/driving/json"
|
|
8
8
|
require_relative "naming"
|
|
9
9
|
require_relative "projector"
|
|
10
10
|
require_relative "runtime/errors"
|
|
@@ -55,7 +55,7 @@ module Hecks
|
|
|
55
55
|
"own root (HECKS_STOREHOUSE_ROOT to widen it)"
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
# The one bluebook this runtime booted; every whole-domain
|
|
58
|
+
# The one bluebook this runtime booted; every whole-domain entry point assumes
|
|
59
59
|
# the same one-bluebook-per-boot shape.
|
|
60
60
|
# :nodoc:
|
|
61
61
|
def bluebook_for(runtime)
|
|
@@ -137,7 +137,7 @@ module Hecks
|
|
|
137
137
|
def audit_fields(request) = request.to_h.slice(:summary, :source, :role, :actor_id)
|
|
138
138
|
|
|
139
139
|
# dry_run? (Runtime::Dispatcher) only understands the pre-envelope flat
|
|
140
|
-
# args shape; this is the one
|
|
140
|
+
# args shape; this is the one entry point back into it from dispatch's own envelope.
|
|
141
141
|
# :nodoc:
|
|
142
142
|
def flatten_legacy(envelope, receiver, legacy_receiver)
|
|
143
143
|
facts = envelope[:with] || {}
|
|
@@ -5,6 +5,7 @@ require "open3"
|
|
|
5
5
|
require "hecks/vocabulary"
|
|
6
6
|
require_relative "../tools"
|
|
7
7
|
require_relative "ci_gates"
|
|
8
|
+
require_relative "release_only"
|
|
8
9
|
|
|
9
10
|
module Hecks
|
|
10
11
|
module Tools
|
|
@@ -43,6 +44,8 @@ module Hecks
|
|
|
43
44
|
# @param env [Hash{String => String}] the runner's environment
|
|
44
45
|
# @return [Boolean] whether the gated job should run
|
|
45
46
|
def touched?(gate, root:, env:)
|
|
47
|
+
return !inherits?(gate, root: root, env: env) if gate.fetch("mode") == "release_only"
|
|
48
|
+
|
|
46
49
|
changed, reason = change_set(gate, root: root, env: env)
|
|
47
50
|
if reason
|
|
48
51
|
explain(gate, reason)
|
|
@@ -54,6 +57,38 @@ module Hecks
|
|
|
54
57
|
gate.fetch("mode") == "touches" ? matches.any? : matches.any?(false)
|
|
55
58
|
end
|
|
56
59
|
|
|
60
|
+
# Whether the change is only a release bump on a base whose required checks all passed, so
|
|
61
|
+
# the run may inherit the base's certification (`ReleaseOnly`). Anything unconfirmed answers
|
|
62
|
+
# false and the suite runs.
|
|
63
|
+
#
|
|
64
|
+
# @param gate [Hash{String => String}] the `CiGate` row
|
|
65
|
+
# @return [Boolean]
|
|
66
|
+
def inherits?(gate, root:, env:)
|
|
67
|
+
base = base_of(gate, root: root, env: env)
|
|
68
|
+
reason = inheritance_refusal(base, root: root, env: env)
|
|
69
|
+
warn "decide_ci_gate: #{reason}: running the suite rather than inheriting certification" if reason
|
|
70
|
+
reason.nil?
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [String, nil] why the change cannot inherit, nil when it can
|
|
74
|
+
def inheritance_refusal(base, root:, env:)
|
|
75
|
+
return "no usable base to diff against" if base.nil? || base.empty? || base == NO_COMMIT
|
|
76
|
+
|
|
77
|
+
changes = ReleaseOnly.changes(base, env.fetch("GITHUB_SHA", "HEAD"), root: root)
|
|
78
|
+
return "git diff itself failed" if changes.nil?
|
|
79
|
+
return "the change is not only release files and lines" unless ReleaseOnly.release_only?(changes)
|
|
80
|
+
|
|
81
|
+
base_refusal(base, env)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @return [String, nil] why the base is not certified, nil when it is
|
|
85
|
+
def base_refusal(base, env)
|
|
86
|
+
runs = ReleaseOnly.check_runs(env.fetch("GITHUB_REPOSITORY", ""), base, env: env)
|
|
87
|
+
return "the base's check runs could not be read" if runs.nil?
|
|
88
|
+
|
|
89
|
+
"the base is not fully certified" unless ReleaseOnly.certified?(runs)
|
|
90
|
+
end
|
|
91
|
+
|
|
57
92
|
# @return [Array(Array<String>, nil), Array(nil, String)] the changed paths, or the reason the
|
|
58
93
|
# change cannot be confirmed
|
|
59
94
|
def change_set(gate, root:, env:)
|
data/lib/hecks/tools/ci_gates.rb
CHANGED
|
@@ -46,7 +46,7 @@ module Hecks
|
|
|
46
46
|
|
|
47
47
|
# The values a row's `mode` and `push` may take: the language holds one closed set to a value
|
|
48
48
|
# object, so the rest are held here.
|
|
49
|
-
MODES = %w[touches skips_unless].freeze
|
|
49
|
+
MODES = %w[touches skips_unless release_only].freeze
|
|
50
50
|
PUSHES = %w[skip before_sha].freeze
|
|
51
51
|
|
|
52
52
|
# @return [Array<Hash{String => String}>] the `CiGate` rows
|
|
@@ -111,16 +111,35 @@ module Hecks
|
|
|
111
111
|
" #{name}:",
|
|
112
112
|
" runs-on: ubuntu-latest",
|
|
113
113
|
" timeout-minutes: 10",
|
|
114
|
+
*job_permissions(gate),
|
|
114
115
|
*job_condition(gate)]
|
|
115
116
|
end
|
|
116
117
|
|
|
117
118
|
# @return [Array<String>] the deciding step and the closing marker
|
|
118
119
|
def job_footer(gate, name)
|
|
119
120
|
[" name: #{quoted(gate.fetch("label"))}",
|
|
121
|
+
*job_env(gate),
|
|
120
122
|
" run: bundle exec exe/hecks regeneration_run.decide_ci_gate gate=#{name} --wait",
|
|
121
123
|
" # END GENERATED ci_gate #{name}"]
|
|
122
124
|
end
|
|
123
125
|
|
|
126
|
+
# A `release_only` gate reads the base commit's check runs through the API, so its job may
|
|
127
|
+
# read checks and nothing more.
|
|
128
|
+
#
|
|
129
|
+
# @return [Array<String>] the job's `permissions:` lines, none for any other mode
|
|
130
|
+
def job_permissions(gate)
|
|
131
|
+
return [] unless gate.fetch("mode") == "release_only"
|
|
132
|
+
|
|
133
|
+
[" permissions:", " contents: read", " checks: read"]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# @return [Array<String>] the deciding step's `env:` lines, none unless the gate calls the API
|
|
137
|
+
def job_env(gate)
|
|
138
|
+
return [] unless gate.fetch("mode") == "release_only"
|
|
139
|
+
|
|
140
|
+
[" env:", " GH_TOKEN: ${{ github.token }}"]
|
|
141
|
+
end
|
|
142
|
+
|
|
124
143
|
# @param gate [Hash{String => String}] a `CiGate` row
|
|
125
144
|
# @return [Array<String>] the job-level `if:` lines for a gate that skips push runs
|
|
126
145
|
def job_condition(gate)
|
|
@@ -14,6 +14,9 @@ module Hecks
|
|
|
14
14
|
module CommentStyle
|
|
15
15
|
# One parsed source file and the violations found in it.
|
|
16
16
|
class SourceFile
|
|
17
|
+
# Raised when an automatic fix would change code rather than comments.
|
|
18
|
+
class Error < RuntimeError; end
|
|
19
|
+
|
|
17
20
|
include LongBlocks
|
|
18
21
|
include Masking
|
|
19
22
|
include CapsWords
|
|
@@ -51,7 +54,7 @@ module Hecks
|
|
|
51
54
|
return @source if output == @source
|
|
52
55
|
|
|
53
56
|
unchanged = CommentStyle.code_tokens(@source) == CommentStyle.code_tokens(output)
|
|
54
|
-
raise "#{path}: fix would change code, refusing" unless unchanged
|
|
57
|
+
raise Error, "#{path}: fix would change code, refusing" unless unchanged
|
|
55
58
|
|
|
56
59
|
output
|
|
57
60
|
end
|
|
@@ -9,6 +9,9 @@ module Hecks
|
|
|
9
9
|
module DeployRecipeLint
|
|
10
10
|
# Generated fixture domains for the deploy generator, so the lint has real Makefiles to read.
|
|
11
11
|
module Fixtures
|
|
12
|
+
# Raised when a deploy fixture cannot be generated.
|
|
13
|
+
class Error < RuntimeError; end
|
|
14
|
+
|
|
12
15
|
# The fixture's bluebook, where `__NAME__` stands for the domain's name.
|
|
13
16
|
FIXTURE_BLUEBOOK = <<~BLUEBOOK
|
|
14
17
|
Hecks.bluebook "__NAME__" do
|
|
@@ -59,7 +62,7 @@ module Hecks
|
|
|
59
62
|
Dir.mktmpdir do |dir|
|
|
60
63
|
domain_dir = write_fixture(dir, basename, world_body, env_local: env_local)
|
|
61
64
|
outcome = Hecks::Adapters::ConsoleCapture.capture { DeployRecipe.main([domain_dir], root: root) }
|
|
62
|
-
outcome.ok? or raise "hecks deploy project failed generating the #{basename} fixture: #{outcome.output}"
|
|
65
|
+
outcome.ok? or raise Error, "hecks deploy project failed generating the #{basename} fixture: #{outcome.output}"
|
|
63
66
|
end
|
|
64
67
|
File.join(root, "deploy", basename)
|
|
65
68
|
end
|
|
@@ -18,6 +18,7 @@ module Hecks
|
|
|
18
18
|
def projection
|
|
19
19
|
rulesets.merge(workflow(Lanes::WORKFLOW, "follows") { |lanes| Lanes.workflow(lanes) })
|
|
20
20
|
.merge(workflow(Lanes::WATCH_WORKFLOW, "alert_after") { |lanes| WatchWorkflow.text(lanes) })
|
|
21
|
+
.merge(prebuilt)
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
# @param files [Hash{String => String}] the projection
|
|
@@ -44,6 +45,13 @@ module Hecks
|
|
|
44
45
|
Lanes.rulesets.to_h { |name, ruleset| [ruleset_path(name), "#{JSON.pretty_generate(ruleset)}\n"] }
|
|
45
46
|
end
|
|
46
47
|
|
|
48
|
+
# The workflow that publishes each `PrebuiltBinary` row.
|
|
49
|
+
def prebuilt
|
|
50
|
+
Hecks::Vocabulary.rows("PrebuiltBinary").to_h do |row|
|
|
51
|
+
[File.join(@root, PrebuiltWorkflow.path(row)), PrebuiltWorkflow.text(row)]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
47
55
|
# The workflow at `path` for the lanes whose `column` is set, or no file if none is.
|
|
48
56
|
def workflow(path, column)
|
|
49
57
|
lanes = Lanes.lanes.reject { |lane| lane[column].to_s.empty? }
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Tools
|
|
5
|
+
module Lanes
|
|
6
|
+
# The workflow that builds and publishes one `PrebuiltBinary` row (ADR 0110): after a push to
|
|
7
|
+
# `main` that touches the row's crate, it builds the binary on the row's runner and, unless
|
|
8
|
+
# a release for that key already exists, publishes it with its sha256. What the key is and
|
|
9
|
+
# where a client looks is `Hecks::RustBuild::PrebuiltBinary`, not anything written here.
|
|
10
|
+
module PrebuiltWorkflow
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
# @param row [Hash{String => String}] a `PrebuiltBinary` row
|
|
14
|
+
# @return [String] the path of the workflow, relative to the checkout
|
|
15
|
+
def path(row) = ".github/workflows/publish-#{row["name"]}.yml"
|
|
16
|
+
|
|
17
|
+
# @param row [Hash{String => String}] a `PrebuiltBinary` row
|
|
18
|
+
# @return [String] the workflow
|
|
19
|
+
def text(row)
|
|
20
|
+
[*header(row), *trigger(row), *job(row)].join("\n") << "\n"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def header(row)
|
|
24
|
+
name = row["name"]
|
|
25
|
+
["name: Publish #{name}", "",
|
|
26
|
+
"# Generated by hecks project_lanes from the PrebuiltBinary rows of the Vocabulary chapter. Do not hand-edit.",
|
|
27
|
+
"#",
|
|
28
|
+
"# Builds #{row["executable"]} from #{row["crate"]} for #{row["target"]} and publishes it as the release",
|
|
29
|
+
"# #{name}-<key>, where the key is a hash of the crate's build inputs. A client that needs the same",
|
|
30
|
+
"# bytes downloads it instead of compiling (Hecks::RustBuild::PrebuiltBinary); a key that already has a",
|
|
31
|
+
"# release is left alone, so a push that changed nothing the build reads publishes nothing."]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def trigger(row)
|
|
35
|
+
["on:", " push:", " branches: [main]", " paths:", " - \"#{row["crate"]}/**\"",
|
|
36
|
+
" - \".github/workflows/publish-#{row["name"]}.yml\"",
|
|
37
|
+
" - \"lib/hecks/rust_build/prebuilt_binary.rb\"",
|
|
38
|
+
" workflow_dispatch: {}", "",
|
|
39
|
+
"concurrency:", " group: publish-#{row["name"]}", " cancel-in-progress: false", "",
|
|
40
|
+
"permissions:", " contents: write", ""]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def job(row)
|
|
44
|
+
["jobs:", " publish:", " runs-on: #{row["runner"]}", " timeout-minutes: 40", " steps:",
|
|
45
|
+
" - uses: actions/checkout@v4", " - uses: ./.github/actions/setup-ruby", *key_step(row),
|
|
46
|
+
*build_steps(row), *release_step(row)]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def key_step(row)
|
|
50
|
+
[" - name: Name the release", " id: key", " run: |",
|
|
51
|
+
" key=$(bundle exec ruby -Ilib -rhecks/rust_build/prebuilt_binary -e \\",
|
|
52
|
+
" 'puts Hecks::RustBuild::PrebuiltBinary.key(ARGV.fetch(0))' #{row["crate"]})",
|
|
53
|
+
" tag=#{row["name"]}-$key",
|
|
54
|
+
" echo \"tag=$tag\" >> \"$GITHUB_OUTPUT\"",
|
|
55
|
+
" if gh release view \"$tag\" > /dev/null 2>&1; then echo \"exists=true\" >> \"$GITHUB_OUTPUT\"; fi",
|
|
56
|
+
" env:", " GH_TOKEN: ${{ github.token }}"]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def build_steps(row)
|
|
60
|
+
[" - name: Build #{row["executable"]}", " if: steps.key.outputs.exists != 'true'",
|
|
61
|
+
" working-directory: #{row["crate"]}", " run: |",
|
|
62
|
+
" rustup toolchain install stable --profile minimal",
|
|
63
|
+
" rustup run stable cargo build --release --target #{row["target"]} --bin #{row["executable"]}"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def release_step(row)
|
|
67
|
+
asset = "#{row["executable"]}-#{row["target"]}"
|
|
68
|
+
[" - name: Publish the release", " if: steps.key.outputs.exists != 'true'",
|
|
69
|
+
" env:", " GH_TOKEN: ${{ github.token }}", " TAG: ${{ steps.key.outputs.tag }}",
|
|
70
|
+
" run: |",
|
|
71
|
+
" mkdir out",
|
|
72
|
+
" cp #{row["crate"]}/target/#{row["target"]}/release/#{row["executable"]} out/#{asset}",
|
|
73
|
+
" (cd out && sha256sum #{asset} > #{asset}.sha256)",
|
|
74
|
+
" gh release create \"$TAG\" out/#{asset} out/#{asset}.sha256 --prerelease --target \"$GITHUB_SHA\" \\",
|
|
75
|
+
" --title \"$TAG\" \\",
|
|
76
|
+
" --notes \"#{row["executable"]} for #{row["target"]}, built from #{row["crate"]} at $GITHUB_SHA.\""]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -29,9 +29,15 @@ module Hecks
|
|
|
29
29
|
return "#{name} has guarded #{lane["guarded"].inspect}" unless %w[yes no].include?(lane["guarded"])
|
|
30
30
|
return "#{name} has alert_after #{lane["alert_after"].inspect}, not whole hours" unless hours?(lane)
|
|
31
31
|
|
|
32
|
+
return "#{name} has release_trailer #{lane["release_trailer"].inspect}, not a trailer word" unless trailer?(lane)
|
|
33
|
+
|
|
32
34
|
follows_problem(lane, names)
|
|
33
35
|
end
|
|
34
36
|
|
|
37
|
+
# @return [Boolean] whether `release_trailer` is empty (nothing is released from the lane)
|
|
38
|
+
# or a git trailer key such as `Release-Approved-By`
|
|
39
|
+
def trailer?(lane) = lane["release_trailer"].to_s.match?(/\A([A-Za-z][A-Za-z0-9]*(-[A-Za-z0-9]+)*)?\z/)
|
|
40
|
+
|
|
35
41
|
# @return [Boolean] whether `alert_after` is empty (never late) or whole hours
|
|
36
42
|
def hours?(lane) = lane["alert_after"].to_s.match?(/\A\d*\z/)
|
|
37
43
|
|
data/lib/hecks/tools/lanes.rb
CHANGED
|
@@ -10,9 +10,8 @@ module Hecks
|
|
|
10
10
|
#
|
|
11
11
|
# A domain that has no bluebook is skipped and one that cannot be projected is reported, so a
|
|
12
12
|
# sweep over the whole checkout carries on past either. `hecks deploy
|
|
13
|
-
# oidc_manifest.project_oidc`
|
|
14
|
-
# `
|
|
15
|
-
# as `[\n\n]`, a diff spec/oidc_manifest_spec.rb would report as drift.
|
|
13
|
+
# oidc_manifest.project_oidc` writes through `Hecks::Projections::OIDC.render`, which spells an
|
|
14
|
+
# empty list `[]` whichever json release is loaded, so the text does not depend on the machine.
|
|
16
15
|
module OidcManifests
|
|
17
16
|
# Directories that hold a `.hecksagon` but are never domains.
|
|
18
17
|
NOT_DOMAINS = %r{\A(rust|deploy|tmp|coverage)/}
|
|
@@ -50,7 +49,7 @@ module Hecks
|
|
|
50
49
|
# @param path [String] a domain directory, relative to `root`
|
|
51
50
|
# @return [void]
|
|
52
51
|
def project(root, path)
|
|
53
|
-
runtime = Hecks.boot(File.join(root, path),
|
|
52
|
+
runtime = Hecks.boot(File.join(root, path), install_driving: false)
|
|
54
53
|
name = runtime.registry.bluebooks.keys.first
|
|
55
54
|
return warn(" #{path}: no bluebook found — skipped") unless name
|
|
56
55
|
|
|
@@ -65,7 +64,7 @@ module Hecks
|
|
|
65
64
|
# @param out [String] where the manifest goes
|
|
66
65
|
# @return [void]
|
|
67
66
|
def write_manifest(registry, name, out)
|
|
68
|
-
Hecks::
|
|
67
|
+
File.write(out, Hecks::Projections::OIDC.render(Hecks::Projector.call(:oidc, bluebook: registry.bluebook(name))))
|
|
69
68
|
end
|
|
70
69
|
end
|
|
71
70
|
end
|
|
@@ -8,13 +8,13 @@ require_relative "../corpus"
|
|
|
8
8
|
|
|
9
9
|
module Hecks
|
|
10
10
|
module Tools
|
|
11
|
-
# Regenerates every corpus domain's
|
|
12
|
-
#
|
|
11
|
+
# Regenerates every corpus domain's Rust output with `hecks project_rust`, or checks that the
|
|
12
|
+
# output on disk is what that would write. Only pizzas, `mod.rs` and `Cargo.toml` are committed.
|
|
13
13
|
#
|
|
14
14
|
# The domain list comes from `Hecks::Corpus.rust_regen_order`, never a hand-kept list. The
|
|
15
15
|
# order is fixed (sorted by relative path): domains that share governance/, identity/,
|
|
16
|
-
# Cargo.toml and generated/mod.rs stamp them with whichever ran last, so it must not flap.
|
|
17
|
-
# the domain set or the sort rule changes, re-run and commit
|
|
16
|
+
# Cargo.toml and generated/mod.rs stamp them with whichever ran last, so it must not flap.
|
|
17
|
+
# If the domain set or the sort rule changes, re-run and commit what changed.
|
|
18
18
|
#
|
|
19
19
|
# hecks regenerate_corpus # discover, regenerate, print the plan
|
|
20
20
|
# hecks regenerate_corpus --check # regenerate into a scratch crate; fail on any difference
|
|
@@ -27,6 +27,11 @@ module Hecks
|
|
|
27
27
|
"wrong directory, or something upstream deleted rust/src/generated/ entirely. Refusing " \
|
|
28
28
|
"to silently treat that as \"nothing to regenerate.\""
|
|
29
29
|
|
|
30
|
+
# The refusal when a check finds nothing generated to compare.
|
|
31
|
+
NOT_MATERIALIZED = "hecks regenerate_corpus --check: rust/src/generated has no generated output to compare. " \
|
|
32
|
+
"Only pizzas, mod.rs and Cargo.toml are committed; run " \
|
|
33
|
+
"`hecks regenerate_corpus --confirm` first, then the check."
|
|
34
|
+
|
|
30
35
|
module_function
|
|
31
36
|
|
|
32
37
|
# Regenerates the corpus, or checks it.
|
|
@@ -147,6 +152,8 @@ module Hecks
|
|
|
147
152
|
# @param root [String] the checkout
|
|
148
153
|
# @return [String] the scratch directory
|
|
149
154
|
def scratch_crate(root)
|
|
155
|
+
abort NOT_MATERIALIZED unless File.directory?(File.join(root, "rust/src/generated/meta"))
|
|
156
|
+
|
|
150
157
|
scratch = Dir.mktmpdir("regen-codegen-check")
|
|
151
158
|
FileUtils.mkdir_p(File.join(scratch, "src"))
|
|
152
159
|
FileUtils.cp_r(File.join(root, "rust/src/generated"), File.join(scratch, "src/generated"))
|