hecks 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/hecks +11 -0
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +18 -99
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres.rb +145 -134
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +7 -30
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +15 -37
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +32 -142
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +17 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +38 -26
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +10 -48
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +14 -63
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +17 -65
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -189
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +19 -106
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +37 -660
- data/lib/hecks/bluebook/hexagon.rb +5 -28
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +54 -268
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -308
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +79 -349
- data/lib/hecks/bluebook/model_check/client_profile.rb +10 -91
- data/lib/hecks/bluebook/model_check.rb +102 -600
- data/lib/hecks/bluebook/pattern_subset.rb +11 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +9 -48
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +8 -98
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +84 -0
- data/lib/hecks/cli/document.rb +86 -0
- data/lib/hecks/cli/ir.rb +45 -0
- data/lib/hecks/cli/mcp.rb +31 -0
- data/lib/hecks/cli/mcp_door.rb +366 -0
- data/lib/hecks/cli/model_check.rb +203 -0
- data/lib/hecks/cli/project_cli.rb +90 -0
- data/lib/hecks/cli/project_diagrams.rb +36 -0
- data/lib/hecks/cli/run.rb +173 -0
- data/lib/hecks/cli/smoke_test.rb +45 -0
- data/lib/hecks/cli/stores.rb +53 -0
- data/lib/hecks/cli.rb +160 -0
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +4 -71
- data/lib/hecks/facade/cli_door.rb +24 -106
- data/lib/hecks/facade/cli_runner.rb +28 -172
- data/lib/hecks/facade/command_request.rb +13 -33
- data/lib/hecks/facade/handle.rb +34 -121
- data/lib/hecks/facade/json_door.rb +31 -146
- data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
- data/lib/hecks/facade/surface/chapter.rb +10 -54
- data/lib/hecks/facade/surface.rb +8 -23
- data/lib/hecks/facade.rb +10 -25
- data/lib/hecks/forms/app.rb +15 -70
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +30 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +12 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +98 -197
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_door_scope.rb +95 -0
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +62 -65
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +7 -26
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +22 -122
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +23 -103
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projections/bootstrap_table.rb +11 -43
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +35 -202
- data/lib/hecks/projections/deploy/lambda.rb +151 -679
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +2 -58
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +47 -146
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +20 -582
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +15 -42
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +9 -28
- data/lib/hecks/projections/reference.rb +9 -16
- data/lib/hecks/projections/rust_vocabulary.rb +12 -250
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +60 -375
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +46 -138
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +93 -0
- data/lib/hecks/release/runner/commands.rb +66 -0
- data/lib/hecks/release/runner/console.rb +52 -0
- data/lib/hecks/release/runner/gem_publisher.rb +43 -0
- data/lib/hecks/release/runner/git.rb +48 -0
- data/lib/hecks/release/runner/npm_publisher.rb +75 -0
- data/lib/hecks/release/runner/preflight.rb +104 -0
- data/lib/hecks/release/runner/published.rb +55 -0
- data/lib/hecks/release/runner/tagger.rb +80 -0
- data/lib/hecks/release/runner.rb +215 -0
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +12 -36
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
- data/lib/hecks/runtime/command_interpreter.rb +125 -307
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +30 -102
- data/lib/hecks/runtime/dispatcher.rb +82 -241
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +65 -220
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +11 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +48 -186
- data/lib/hecks/runtime/outbox.rb +38 -261
- data/lib/hecks/runtime/policy_interpreter.rb +38 -200
- data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
- data/lib/hecks/runtime/query_interpreter.rb +45 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/read_model_interpreter.rb +139 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +8 -89
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +52 -225
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +103 -244
- data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +155 -641
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value.rb +12 -84
- data/lib/hecks/runtime.rb +17 -65
- data/lib/hecks/storehouse.rb +146 -567
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks/vocabulary.rb +5 -0
- data/lib/hecks.rb +32 -82
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- metadata +30 -59
- data/lib/hecks/bench/cli.rb +0 -74
- data/lib/hecks/bench/environment.rb +0 -100
- data/lib/hecks/bench/postgres_probe.rb +0 -41
- data/lib/hecks/bench/report.rb +0 -116
- data/lib/hecks/bench/ruby_runner.rb +0 -151
- data/lib/hecks/bench/run.rb +0 -55
- data/lib/hecks/bench/rust_runner.rb +0 -165
- data/lib/hecks/bench/stats.rb +0 -75
- data/lib/hecks/bench/suite.rb +0 -172
- data/lib/hecks/bench/workload.rb +0 -137
- data/lib/hecks/bench.rb +0 -28
- data/lib/hecks/codemod.rb +0 -443
- data/lib/hecks/corpus.rb +0 -479
- data/lib/hecks/doc/reference.rb +0 -585
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +0 -684
- data/lib/hecks/fuzzing/combination_miner.rb +0 -178
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +0 -469
- data/lib/hecks/fuzzing/coverage_campaign.rb +0 -161
- data/lib/hecks/fuzzing/differential.rb +0 -192
- data/lib/hecks/fuzzing/domain_generator.rb +0 -871
- data/lib/hecks/fuzzing/era_boundary.rb +0 -154
- data/lib/hecks/fuzzing/form_census.rb +0 -285
- data/lib/hecks/fuzzing/generated_domain_check.rb +0 -171
- data/lib/hecks/fuzzing/invalid_value_generator.rb +0 -125
- data/lib/hecks/fuzzing/isolated_boot.rb +0 -658
- data/lib/hecks/fuzzing/nondeterministic.rb +0 -79
- data/lib/hecks/fuzzing/persistence_parity.rb +0 -253
- data/lib/hecks/fuzzing/properties/corrections.rb +0 -125
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +0 -688
- data/lib/hecks/fuzzing/properties/guards.rb +0 -398
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +0 -399
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +0 -137
- data/lib/hecks/fuzzing/properties/outbox.rb +0 -180
- data/lib/hecks/fuzzing/properties/querying.rb +0 -260
- data/lib/hecks/fuzzing/properties.rb +0 -267
- data/lib/hecks/fuzzing/qa_settings.rb +0 -164
- data/lib/hecks/fuzzing/replay.rb +0 -930
- data/lib/hecks/fuzzing/rotation_priority.rb +0 -114
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +0 -139
- data/lib/hecks/fuzzing/self_consistency.rb +0 -825
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +0 -532
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +0 -171
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +0 -127
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +0 -116
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +0 -138
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +0 -344
- data/lib/hecks/fuzzing/sequence_generator.rb +0 -311
- data/lib/hecks/fuzzing/shrinker.rb +0 -309
- data/lib/hecks/fuzzing/structural_skips.rb +0 -53
- data/lib/hecks/fuzzing/sweep_depth.rb +0 -61
- data/lib/hecks/fuzzing/target_capabilities.rb +0 -255
- data/lib/hecks/fuzzing/value_generator.rb +0 -340
- data/lib/hecks/fuzzing.rb +0 -23
- data/lib/hecks/grammar/evolve.rb +0 -524
- data/lib/hecks/query_ir.rb +0 -482
|
@@ -1,37 +1,8 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Projections
|
|
3
3
|
module Deploy
|
|
4
|
-
# The smoke-test files a deployed stack can opt in to: a client-independent
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# Not a registered `Projector::Target` of its own. It adds files to whatever a
|
|
8
|
-
# deploy target already produced, so `bin/project_deploy` merges what `files`
|
|
9
|
-
# returns into the artifact, and a stack that has not opted in gets nothing.
|
|
10
|
-
#
|
|
11
|
-
# ## Opting in
|
|
12
|
-
#
|
|
13
|
-
# In the domain's `.world`, inside its `deployed_to` block:
|
|
14
|
-
#
|
|
15
|
-
# deployed_to("AwsFargate") do
|
|
16
|
-
# smoke true
|
|
17
|
-
# smoke_role_arn "arn:aws:iam::123456789012:role/example-smoke"
|
|
18
|
-
# smoke_secret_id "example-stack/session-secret"
|
|
19
|
-
# smoke_site_url "https://example.org"
|
|
20
|
-
# end
|
|
21
|
-
#
|
|
22
|
-
# `smoke_secret_field` names a JSON field when the secret is a JSON document,
|
|
23
|
-
# `smoke_secret_env` names the variable the harness reads it from (default
|
|
24
|
-
# `SESSION_SECRET`), `smoke_schedule` is a cron expression (default every 15
|
|
25
|
-
# minutes), `smoke_harness` and `smoke_config` are the repository-relative paths
|
|
26
|
-
# the workflow runs (defaults `smoke/harness.js` and `smoke/config.js`), and
|
|
27
|
-
# `smoke_setup` is one shell command run before the AWS steps, such as an
|
|
28
|
-
# install step the client's checks need.
|
|
29
|
-
#
|
|
30
|
-
# ## What stays with the client
|
|
31
|
-
#
|
|
32
|
-
# The harness knows nothing about any site. The pages and flows to assert, the
|
|
33
|
-
# cookie name, and the expected-era file are the client's own `config.js`, which
|
|
34
|
-
# this never writes.
|
|
4
|
+
# The smoke-test files a deployed stack can opt in to: a client-independent harness
|
|
5
|
+
# plus a scheduled GitHub Actions workflow, merged into whatever the deploy target made.
|
|
35
6
|
module Smoke
|
|
36
7
|
TEMPLATES = File.expand_path("smoke", __dir__).freeze
|
|
37
8
|
DEFAULTS = {
|
|
@@ -59,10 +30,6 @@ module Hecks
|
|
|
59
30
|
|
|
60
31
|
module_function
|
|
61
32
|
|
|
62
|
-
# Whether the domain's `deployed_to` settings ask for the smoke files.
|
|
63
|
-
#
|
|
64
|
-
# @param deploy_settings [Hash{Symbol => Object}] the `deployed_to` block's settings
|
|
65
|
-
# @return [Boolean] true only when `smoke true` was declared
|
|
66
33
|
def enabled?(deploy_settings)
|
|
67
34
|
deploy_settings[:smoke] == true
|
|
68
35
|
end
|
|
@@ -87,12 +54,6 @@ module Hecks
|
|
|
87
54
|
}
|
|
88
55
|
end
|
|
89
56
|
|
|
90
|
-
# Applies the defaults and validates every value.
|
|
91
|
-
#
|
|
92
|
-
# @param deploy_settings [Hash{Symbol => Object}] the `deployed_to` block's settings
|
|
93
|
-
# @return [Hash{Symbol => String, nil}] the template values, keyed by placeholder name
|
|
94
|
-
# @raise [ArgumentError] if a required setting is missing or a value does not match its
|
|
95
|
-
# pattern
|
|
96
57
|
def resolve(deploy_settings)
|
|
97
58
|
missing = REQUIRED.reject { |name| deploy_settings[setting_key(name)] }
|
|
98
59
|
unless missing.empty?
|
|
@@ -109,22 +70,12 @@ module Hecks
|
|
|
109
70
|
picked
|
|
110
71
|
end
|
|
111
72
|
|
|
112
|
-
# The `
|
|
113
|
-
# deploy target's own; every other value has a `smoke_` prefix.
|
|
114
|
-
#
|
|
115
|
-
# @param name [Symbol] a template value name, such as `:role_arn`
|
|
116
|
-
# @return [Symbol] the setting key, such as `:smoke_role_arn`
|
|
73
|
+
# The region has no `smoke_` prefix; every other setting does.
|
|
117
74
|
def setting_key(name)
|
|
118
75
|
name == :region ? :region : :"smoke_#{name}"
|
|
119
76
|
end
|
|
120
77
|
|
|
121
|
-
#
|
|
122
|
-
# disappears whole rather than leaving a blank.
|
|
123
|
-
#
|
|
124
|
-
# @param template [String] the workflow template text
|
|
125
|
-
# @param values [Hash{Symbol => String, nil}] placeholder values, plus `:name`
|
|
126
|
-
# @return [String] the rendered workflow
|
|
127
|
-
# @raise [ArgumentError] if a placeholder is left unfilled
|
|
78
|
+
# A placeholder line that resolves to nothing disappears whole, not as a blank line.
|
|
128
79
|
def render(template, values)
|
|
129
80
|
filled = template.gsub(/^@@setup@@\n/) { setup_step(values[:setup]) }
|
|
130
81
|
filled = filled.gsub("@@secret_field_pipe@@") { secret_field_pipe(values[:secret_field]) }
|
|
@@ -134,20 +85,12 @@ module Hecks
|
|
|
134
85
|
filled
|
|
135
86
|
end
|
|
136
87
|
|
|
137
|
-
# Renders the optional setup step, quoting the command for YAML.
|
|
138
|
-
#
|
|
139
|
-
# @param command [String, nil] the shell command from `smoke_setup`
|
|
140
|
-
# @return [String] a workflow step running it, or nothing
|
|
141
88
|
def setup_step(command)
|
|
142
89
|
return "" if command.nil?
|
|
143
90
|
|
|
144
91
|
" - name: Set up the smoke run\n run: '#{command.gsub("'", "''")}'\n\n"
|
|
145
92
|
end
|
|
146
93
|
|
|
147
|
-
# Builds the pipe that pulls one field out of a JSON secret document.
|
|
148
|
-
#
|
|
149
|
-
# @param field [String, nil] the JSON field of the secret document
|
|
150
|
-
# @return [String] the pipe that extracts it, or nothing when the secret is plain text
|
|
151
94
|
def secret_field_pipe(field)
|
|
152
95
|
return "" if field.nil?
|
|
153
96
|
|
|
@@ -2,29 +2,14 @@ module Hecks
|
|
|
2
2
|
module Projections
|
|
3
3
|
module Deploy
|
|
4
4
|
module TemplateDiff
|
|
5
|
-
# Compares two loaded CloudFormation templates
|
|
6
|
-
#
|
|
7
|
-
# Resources, parameters, outputs, conditions and mappings are matched
|
|
8
|
-
# by name, then compared property by property. A list of mappings that
|
|
9
|
-
# each carry a `Name`, `Id`, `Key` or similar field (container
|
|
10
|
-
# definitions, environment variables, tags, origins) is matched by that
|
|
11
|
-
# field, not by position, so inserting one entry reports one addition
|
|
12
|
-
# instead of a cascade of shifted values. Cache behaviors are matched
|
|
13
|
-
# the same way but their order is also checked, because CloudFront
|
|
14
|
-
# takes the first pattern that matches.
|
|
15
|
-
#
|
|
16
|
-
# Two values that differ only in how they are written (a number and
|
|
17
|
-
# the same digits as text, a `!Sub` with nothing but one `${Name}` and
|
|
18
|
-
# a `!Ref Name`) are equal after normalization or marked `cosmetic`.
|
|
5
|
+
# Compares two loaded CloudFormation templates, matching entries by an
|
|
6
|
+
# identity field such as `Name` or `Id` rather than by position.
|
|
19
7
|
module Comparer
|
|
20
8
|
module_function
|
|
21
9
|
|
|
22
10
|
Change = Struct.new(:path, :kind, :before, :after, :cosmetic, keyword_init: true)
|
|
23
11
|
Entity = Struct.new(:name, :type, :changes, :replaced, keyword_init: true)
|
|
24
12
|
SectionDiff = Struct.new(:added, :removed, :changed, keyword_init: true) do
|
|
25
|
-
# Tells whether nothing in the section differs.
|
|
26
|
-
#
|
|
27
|
-
# @return [Boolean] true when no entity was added, removed or changed
|
|
28
13
|
def empty? = added.empty? && removed.empty? && changed.empty?
|
|
29
14
|
end
|
|
30
15
|
|
|
@@ -32,14 +17,7 @@ module Hecks
|
|
|
32
17
|
IDENTITY_KEYS = %w[Name Id Key PolicyName PathPattern HeaderName ContainerName Sid Field].freeze
|
|
33
18
|
ORDERED_BY = %w[PathPattern].freeze
|
|
34
19
|
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
# @param before [Hash{String => Object}] the template as `Loader.load` returns it
|
|
38
|
-
# @param after [Hash{String => Object}] the template to compare it with
|
|
39
|
-
# @return [Hash{String => SectionDiff, Array<Change>}] one `SectionDiff` per entity
|
|
40
|
-
# section
|
|
41
|
-
# that either template has, and `"Template"` mapped to the changes in every other
|
|
42
|
-
# top-level key such as `Description`
|
|
20
|
+
# Diffs each entity section by name, with other top-level keys grouped under "Template".
|
|
43
21
|
def compare(before, after)
|
|
44
22
|
before = normalize(before)
|
|
45
23
|
after = normalize(after)
|
|
@@ -4,17 +4,8 @@ module Hecks
|
|
|
4
4
|
module Projections
|
|
5
5
|
module Deploy
|
|
6
6
|
module TemplateDiff
|
|
7
|
-
# Reads a CloudFormation template in YAML into plain Ruby data
|
|
8
|
-
#
|
|
9
|
-
# CloudFormation's short forms (`!Ref Name`, `!GetAtt A.B`, `!Sub "..."`)
|
|
10
|
-
# are YAML tags that a stock loader refuses or drops. This loader walks
|
|
11
|
-
# the parsed document and turns each into the long form CloudFormation
|
|
12
|
-
# itself reads (`{"Ref" => "Name"}`, `{"Fn::GetAtt" => ["A", "B"]}`), so
|
|
13
|
-
# a template written with short forms and one written with long forms
|
|
14
|
-
# load to the same data. Comments and key order do not survive loading,
|
|
15
|
-
# which is what a comparison of two templates wants.
|
|
16
|
-
#
|
|
17
|
-
# Nothing here evaluates a template or contacts AWS.
|
|
7
|
+
# Reads a CloudFormation template in YAML into plain Ruby data, converting
|
|
8
|
+
# short-form intrinsics (`!Ref`, `!GetAtt`, `!Sub`) into their long form.
|
|
18
9
|
module Loader
|
|
19
10
|
module_function
|
|
20
11
|
|
|
@@ -5,39 +5,13 @@ require_relative "template_diff/comparer"
|
|
|
5
5
|
module Hecks
|
|
6
6
|
module Projections
|
|
7
7
|
module Deploy
|
|
8
|
-
# An offline
|
|
9
|
-
#
|
|
10
|
-
# It answers "what would change if this template replaced that one"
|
|
11
|
-
# from the two files alone, the offline half of checking that a
|
|
12
|
-
# generated template leaves a live stack untouched: when the generated
|
|
13
|
-
# template and the one already deployed differ in nothing but comments,
|
|
14
|
-
# ordering and spelling, a change set against the live stack should be
|
|
15
|
-
# empty too. It reads no AWS state and changes nothing.
|
|
16
|
-
#
|
|
17
|
-
# ## What it reports
|
|
18
|
-
#
|
|
19
|
-
# Resources, parameters, outputs, conditions and mappings that were
|
|
20
|
-
# added, removed or changed, by logical id, and for a changed one every
|
|
21
|
-
# property that differs, with the value before and after. Other
|
|
22
|
-
# top-level keys, such as `Description`, are compared as values.
|
|
23
|
-
# Comments and the order of keys do not count, and the short and long
|
|
24
|
-
# forms of an intrinsic (`!Ref Name`, `{"Ref": "Name"}`) are the same
|
|
25
|
-
# thing. A change to a resource's `Type` is marked as a replacement.
|
|
26
|
-
# Differences that are only in how a value is written are marked
|
|
27
|
-
# cosmetic and do not count as a difference unless `strict` is set.
|
|
28
|
-
#
|
|
29
|
-
# ## What it does not do
|
|
30
|
-
#
|
|
31
|
-
# It does not know which property changes CloudFormation applies in
|
|
32
|
-
# place and which replace the resource beyond a change of `Type`, so a
|
|
33
|
-
# changed immutable property is listed as a change, not flagged.
|
|
8
|
+
# An offline diff of two CloudFormation templates: what would change if one replaced
|
|
9
|
+
# the other, ignoring comments, key order and equivalent intrinsic spellings.
|
|
34
10
|
module TemplateDiff
|
|
35
11
|
module_function
|
|
36
12
|
|
|
37
13
|
Report = Struct.new(:sections, :strict, keyword_init: true) do
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
# @return [Boolean] false when every difference is cosmetic and the report is not strict
|
|
14
|
+
# False when every difference is cosmetic and the report is not strict.
|
|
41
15
|
def different?
|
|
42
16
|
sections.any? do |name, diff|
|
|
43
17
|
if name == "Template"
|
|
@@ -48,32 +22,13 @@ module Hecks
|
|
|
48
22
|
end
|
|
49
23
|
end
|
|
50
24
|
|
|
51
|
-
# Keeps the changes that count towards a difference.
|
|
52
|
-
#
|
|
53
|
-
# @param changes [Array<Comparer::Change>] the changes to filter
|
|
54
|
-
# @return [Array<Comparer::Change>] every change, or only the non-cosmetic ones unless
|
|
55
|
-
# strict
|
|
56
25
|
def counted(changes) = strict ? changes : changes.reject(&:cosmetic)
|
|
57
26
|
end
|
|
58
27
|
|
|
59
|
-
# Compares two template texts.
|
|
60
|
-
#
|
|
61
|
-
# @param before [String] the first template, YAML
|
|
62
|
-
# @param after [String] the second template, YAML
|
|
63
|
-
# @param strict [Boolean] whether cosmetic differences count as differences
|
|
64
|
-
# @return [Report] the differences, by section
|
|
65
|
-
# @raise [ArgumentError] if either text is not a valid template
|
|
66
28
|
def diff(before, after, strict: false)
|
|
67
29
|
Report.new(sections: Comparer.compare(Loader.load(before), Loader.load(after)), strict: strict)
|
|
68
30
|
end
|
|
69
31
|
|
|
70
|
-
# Compares two template files.
|
|
71
|
-
#
|
|
72
|
-
# @param before_path [String] the path of the first template
|
|
73
|
-
# @param after_path [String] the path of the template to compare it with
|
|
74
|
-
# @param strict [Boolean] whether cosmetic differences count as differences
|
|
75
|
-
# @return [Report] the differences, by section
|
|
76
|
-
# @raise [ArgumentError] if either file is missing or is not a valid template
|
|
77
32
|
def diff_files(before_path, after_path, strict: false)
|
|
78
33
|
Report.new(
|
|
79
34
|
sections: Comparer.compare(Loader.load_file(before_path), Loader.load_file(after_path)),
|
|
@@ -81,11 +36,7 @@ module Hecks
|
|
|
81
36
|
)
|
|
82
37
|
end
|
|
83
38
|
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
# @param report [Report] the differences to describe
|
|
87
|
-
# @return [String] one section per kind of entity, each entity on a `+`, `-` or `~` line,
|
|
88
|
-
# or `no differences` when nothing differs
|
|
39
|
+
# One line per entity: `+` added, `-` removed, `~` changed; `no differences` when none.
|
|
89
40
|
def render(report)
|
|
90
41
|
lines = report.sections.flat_map do |name, diff|
|
|
91
42
|
name == "Template" ? template_lines(report, diff) : section_lines(report, name, diff)
|
|
@@ -96,10 +47,7 @@ module Hecks
|
|
|
96
47
|
"#{(lines + note).join("\n")}\n"
|
|
97
48
|
end
|
|
98
49
|
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
# @param report [Report] the differences to describe
|
|
102
|
-
# @return [String] a JSON document with `different` and one entry per section
|
|
50
|
+
# Top-level keys: `different` and one entry per section.
|
|
103
51
|
def render_json(report)
|
|
104
52
|
sections = report.sections.to_h do |name, diff|
|
|
105
53
|
[name, name == "Template" ? diff.map { |change| change_hash(change) } : section_hash(diff)]
|