hecks 2.6.0 → 2.8.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 +13 -0
- data/lib/hecks/adapters/driven/google_authentication.rb +1 -1
- data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
- data/lib/hecks/adapters/driven/memory.rb +1 -1
- data/lib/hecks/adapters/driven/postgres.rb +1 -1
- data/lib/hecks/adapters/driven/prism.rb +2 -2
- data/lib/hecks/adapters/driven/sqlite/projection.rb +1 -1
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +31 -10
- data/lib/hecks/behaviors/expectations.rb +2 -2
- data/lib/hecks/bluebook/assembly/contract.rb +1 -1
- data/lib/hecks/bluebook/assembly/contracts.rb +5 -5
- data/lib/hecks/bluebook/assembly/specializer.rb +2 -2
- data/lib/hecks/bluebook/assembly.rb +1 -1
- data/lib/hecks/bluebook/behaviour/chapter.rb +5 -2
- data/lib/hecks/bluebook/behaviour/read_model.rb +18 -0
- data/lib/hecks/bluebook/capabilities.rb +2 -2
- data/lib/hecks/bluebook/chapter.rb +1 -1
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +2 -2
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +6 -1
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +2 -2
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +3 -3
- data/lib/hecks/bluebook/dsl/entity_builder.rb +1 -1
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +1 -1
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +14 -9
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +1 -1
- data/lib/hecks/bluebook/dsl/rule_reference.rb +3 -3
- data/lib/hecks/bluebook/dsl/translation_builder.rb +1 -1
- data/lib/hecks/bluebook/dsl/world_builder.rb +47 -3
- data/lib/hecks/bluebook/hexagon.rb +15 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +3 -3
- data/lib/hecks/bluebook/meta_validator/plan.rb +4 -4
- data/lib/hecks/bluebook/meta_validator/readings.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +2 -2
- data/lib/hecks/bluebook/meta_validator/shapes.rb +1 -1
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +11 -10
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +3 -1
- data/lib/hecks/bluebook/meta_validator.rb +1 -1
- data/lib/hecks/bluebook/model_check/client_profile.rb +4 -70
- data/lib/hecks/bluebook/model_check.rb +13 -14
- data/lib/hecks/cache_dir.rb +103 -0
- data/lib/hecks/cli/document.rb +104 -0
- data/lib/hecks/cli/ir.rb +47 -0
- data/lib/hecks/cli/mcp.rb +32 -0
- data/lib/hecks/cli/mcp_door.rb +461 -0
- data/lib/hecks/cli/model_check.rb +270 -0
- data/lib/hecks/cli/project_cli.rb +123 -0
- data/lib/hecks/cli/project_diagrams.rb +43 -0
- data/lib/hecks/cli/run.rb +219 -0
- data/lib/hecks/cli/smoke_test.rb +59 -0
- data/lib/hecks/cli/stores.rb +54 -0
- data/lib/hecks/cli.rb +166 -0
- data/lib/hecks/embryonaut_bluebook/lock.rb +72 -0
- data/lib/hecks/embryonaut_bluebook/shape.rb +47 -0
- data/lib/hecks/embryonaut_bluebook/vendor.rb +194 -0
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +88 -0
- data/lib/hecks/embryonaut_bluebook.rb +29 -3
- data/lib/hecks/facade/handle.rb +2 -2
- data/lib/hecks/facade/surface/aggregate_door.rb +1 -1
- data/lib/hecks/forms/value_object_shape.rb +1 -1
- data/lib/hecks/framework/bluebook/console_settings.bluebook +3 -3
- data/lib/hecks/language/bluebook/vocabulary.bluebook +16 -0
- data/lib/hecks/language/world/world.bluebook +32 -2
- data/lib/hecks/mcp_door_scope.rb +176 -0
- data/lib/hecks/ports/key_vault.rb +1 -1
- data/lib/hecks/ports/persistence/append_only.rb +1 -1
- data/lib/hecks/ports/persistence/binding_policy.rb +16 -5
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +3 -2
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +2 -2
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +2 -2
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +132 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +2 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +13 -7
- data/lib/hecks/ports/persistence/plugins/era.rb +7 -4
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +73 -0
- data/lib/hecks/ports/persistence/postgres_dump.rb +125 -0
- data/lib/hecks/ports/persistence/repository_factory.rb +2 -2
- data/lib/hecks/ports/persistence/state_codec.rb +1 -1
- data/lib/hecks/ports/persistence.rb +4 -0
- data/lib/hecks/projections/deploy/fargate/assembly.rb +193 -0
- data/lib/hecks/projections/deploy/fargate/cdn.rb +318 -0
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +87 -0
- data/lib/hecks/projections/deploy/fargate/check.rb +172 -0
- data/lib/hecks/projections/deploy/fargate/containers.rb +412 -0
- data/lib/hecks/projections/deploy/fargate/extras.rb +268 -0
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +448 -0
- data/lib/hecks/projections/deploy/fargate/settings.rb +235 -0
- data/lib/hecks/projections/deploy/fargate/yaml.rb +116 -0
- data/lib/hecks/projections/deploy/fargate.rb +188 -139
- data/lib/hecks/projections/deploy/lambda.rb +8 -8
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +145 -0
- data/lib/hecks/projections/deploy/preview/containers.rb +218 -0
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +446 -0
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +216 -0
- data/lib/hecks/projections/deploy/preview/script.rb +40 -0
- data/lib/hecks/projections/deploy/preview/settings.rb +140 -0
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +215 -0
- data/lib/hecks/projections/deploy/preview/template.rb +247 -0
- data/lib/hecks/projections/deploy/preview/yaml_text.rb +48 -0
- data/lib/hecks/projections/deploy/preview.rb +103 -0
- data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +182 -0
- data/lib/hecks/projections/deploy/scripts/expected-era.header +17 -0
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +54 -0
- data/lib/hecks/projections/deploy/scripts/settings.rb +114 -0
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +232 -0
- data/lib/hecks/projections/deploy/scripts.rb +171 -0
- data/lib/hecks/projections/deploy/smoke/harness.js +366 -0
- data/lib/hecks/projections/deploy/smoke/workflow.yml.tmpl +56 -0
- data/lib/hecks/projections/deploy/smoke.rb +159 -0
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +231 -0
- data/lib/hecks/projections/deploy/template_diff/loader.rb +105 -0
- data/lib/hecks/projections/deploy/template_diff.rb +173 -0
- data/lib/hecks/projections/glossary/sensitivity.rb +1 -1
- data/lib/hecks/projections/reference.rb +7 -1
- data/lib/hecks/projections.rb +2 -0
- data/lib/hecks/projector/exporter.rb +4 -4
- data/lib/hecks/projector/target.rb +1 -1
- data/lib/hecks/release/gem_pin/published_versions.rb +58 -0
- data/lib/hecks/release/gem_pin.rb +112 -0
- data/lib/hecks/release/runner/ci_publisher.rb +96 -0
- data/lib/hecks/release/runner/commands.rb +68 -0
- data/lib/hecks/release/runner/console.rb +52 -0
- data/lib/hecks/release/runner/gem_publisher.rb +44 -0
- data/lib/hecks/release/runner/git.rb +48 -0
- data/lib/hecks/release/runner/npm_publisher.rb +89 -0
- data/lib/hecks/release/runner/preflight.rb +119 -0
- data/lib/hecks/release/runner/published.rb +55 -0
- data/lib/hecks/release/runner/tagger.rb +87 -0
- data/lib/hecks/release/runner.rb +244 -0
- data/lib/hecks/router/namespace_installer.rb +1 -1
- data/lib/hecks/runtime/command_interpreter.rb +3 -3
- data/lib/hecks/runtime/command_rules/admissibility.rb +2 -2
- data/lib/hecks/runtime/command_rules/arithmetic.rb +2 -2
- data/lib/hecks/runtime/entity_element.rb +1 -1
- data/lib/hecks/runtime/entity_interpreter.rb +1 -1
- data/lib/hecks/runtime/invocation.rb +1 -1
- data/lib/hecks/runtime/loader.rb +27 -3
- data/lib/hecks/runtime/outbox.rb +1 -1
- data/lib/hecks/runtime/reaction_invocation.rb +3 -3
- data/lib/hecks/runtime/read_model_interpreter.rb +37 -15
- data/lib/hecks/runtime/reference_hop.rb +4 -4
- data/lib/hecks/runtime/registry/saga_persistence.rb +8 -2
- data/lib/hecks/runtime/registry/verification.rb +15 -13
- data/lib/hecks/runtime/registry/world_defaults.rb +106 -0
- data/lib/hecks/runtime/registry.rb +22 -13
- data/lib/hecks/runtime/saga_interpreter.rb +1 -1
- data/lib/hecks/runtime/tenant_check.rb +1 -1
- data/lib/hecks/runtime/value/coercion.rb +3 -3
- data/lib/hecks/runtime/value/entity_list_coercion.rb +1 -1
- data/lib/hecks/storehouse.rb +18 -12
- data/lib/hecks/vendoring/git_environment.rb +35 -0
- data/lib/hecks/vendoring/git_source.rb +102 -0
- data/lib/hecks/vendoring.rb +102 -0
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +5 -0
- data/lib/hecks.rb +8 -2
- metadata +72 -58
- 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 -604
- 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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "tmpdir"
|
|
3
|
+
require_relative "vendoring/git_environment"
|
|
4
|
+
require_relative "vendoring/git_source"
|
|
5
|
+
|
|
6
|
+
module Hecks
|
|
7
|
+
# Pins an exact commit of one directory of another repository into a
|
|
8
|
+
# project's own tree.
|
|
9
|
+
#
|
|
10
|
+
# ## What it is
|
|
11
|
+
#
|
|
12
|
+
# A project that consumes a package from a private repository cannot clone
|
|
13
|
+
# that repository when its image builds, and a live pull would make the build
|
|
14
|
+
# depend on whatever is checked out. So the files are exported from one
|
|
15
|
+
# commit, committed into the consumer, and a marker file beside them records
|
|
16
|
+
# which commit they came from. Only the files directly inside the named
|
|
17
|
+
# subtree are taken; the source's own specs, ports, adapters and data stay
|
|
18
|
+
# where they are.
|
|
19
|
+
#
|
|
20
|
+
# ## Marker
|
|
21
|
+
#
|
|
22
|
+
# `VENDORED_COMMIT` holds the full 40-character commit id and a newline, so
|
|
23
|
+
# `git -C <source> show <id>:<subtree>` reproduces the vendored files. The
|
|
24
|
+
# marker sits in `into`, beside the exported directory.
|
|
25
|
+
#
|
|
26
|
+
# ## Whole-directory replacement
|
|
27
|
+
#
|
|
28
|
+
# A pin replaces `into` entirely, so a file the source dropped does not
|
|
29
|
+
# linger. Nothing is touched until the export succeeded and the optional
|
|
30
|
+
# block accepted it.
|
|
31
|
+
module Vendoring
|
|
32
|
+
# Raised when a pin cannot be made or is refused.
|
|
33
|
+
class Error < StandardError; end
|
|
34
|
+
|
|
35
|
+
# File name of the commit marker written into every pinned directory.
|
|
36
|
+
MARKER = "VENDORED_COMMIT".freeze
|
|
37
|
+
|
|
38
|
+
# What a pin produced.
|
|
39
|
+
#
|
|
40
|
+
# @!attribute [r] commit
|
|
41
|
+
# @return [String] the full commit id the files were exported from
|
|
42
|
+
# @!attribute [r] dir
|
|
43
|
+
# @return [String] the directory holding the exported subtree
|
|
44
|
+
# @!attribute [r] files
|
|
45
|
+
# @return [Array<String>] the exported files' names, sorted
|
|
46
|
+
Pin = Struct.new(:commit, :dir, :files, keyword_init: true)
|
|
47
|
+
|
|
48
|
+
# Exports the top-level files of one directory at one commit into `into`.
|
|
49
|
+
#
|
|
50
|
+
# The exported files land in `into/<last segment of subtree>/`; the marker
|
|
51
|
+
# lands in `into` itself. The optional block sees the staged files before
|
|
52
|
+
# anything is replaced and may raise to refuse the pin.
|
|
53
|
+
#
|
|
54
|
+
# @param from [String] path of the local source repository
|
|
55
|
+
# @param ref [String] the commit-ish to export (branch, tag or commit id)
|
|
56
|
+
# @param subtree [String] repository-relative directory to export, such as
|
|
57
|
+
# `"payments/bluebook"`
|
|
58
|
+
# @param into [String] the directory to replace with the export
|
|
59
|
+
# @param glob [String] `File.fnmatch` pattern each exported file's name must match
|
|
60
|
+
# @param marker [String] name of the file recording the commit
|
|
61
|
+
# @yield [staged, commit] the staged files, before `into` is touched
|
|
62
|
+
# @yieldparam staged [String] directory holding the exported files
|
|
63
|
+
# @yieldparam commit [String] the resolved commit id
|
|
64
|
+
# @yieldreturn [Hash{String => String}, nil] extra files to write into `into`,
|
|
65
|
+
# keyed by file name; nil for none
|
|
66
|
+
# @return [Pin] the commit and where the files landed
|
|
67
|
+
# @raise [Vendoring::Error] if the source is missing, `ref` names no commit,
|
|
68
|
+
# the subtree holds no matching file, or the block refuses
|
|
69
|
+
def self.pin(from:, ref:, subtree:, into:, glob: "*", marker: MARKER)
|
|
70
|
+
source = GitSource.new(from)
|
|
71
|
+
commit = source.commit(ref)
|
|
72
|
+
files = source.files(commit, subtree, glob)
|
|
73
|
+
raise Error, "no #{glob} files in #{subtree} at #{ref} in #{source.path}" if files.empty?
|
|
74
|
+
|
|
75
|
+
Dir.mktmpdir("hecks-vendoring") do |stage|
|
|
76
|
+
source.export(commit, files, stage)
|
|
77
|
+
staged = File.join(stage, subtree)
|
|
78
|
+
extras = block_given? ? yield(staged, commit) : nil
|
|
79
|
+
install(staged, into, marker, commit, extras || {})
|
|
80
|
+
Pin.new(commit: commit, dir: File.join(into, File.basename(subtree)),
|
|
81
|
+
files: files.map { |file| File.basename(file) })
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Replaces `into` with the staged files, the marker and any extras.
|
|
86
|
+
#
|
|
87
|
+
# @param staged [String] directory holding the exported files
|
|
88
|
+
# @param into [String] the directory to replace
|
|
89
|
+
# @param marker [String] marker file name
|
|
90
|
+
# @param commit [String] commit id the marker records
|
|
91
|
+
# @param extras [Hash{String => String}] more files to write into `into`
|
|
92
|
+
# @return [void]
|
|
93
|
+
def self.install(staged, into, marker, commit, extras)
|
|
94
|
+
FileUtils.rm_rf(into)
|
|
95
|
+
FileUtils.mkdir_p(into)
|
|
96
|
+
FileUtils.cp_r(staged, File.join(into, File.basename(staged)))
|
|
97
|
+
File.write(File.join(into, marker), "#{commit}\n")
|
|
98
|
+
extras.each { |name, text| File.write(File.join(into, name), text) }
|
|
99
|
+
end
|
|
100
|
+
private_class_method :install
|
|
101
|
+
end
|
|
102
|
+
end
|
data/lib/hecks/version.rb
CHANGED
data/lib/hecks/vocabulary.rb
CHANGED
|
@@ -254,6 +254,10 @@ module Hecks
|
|
|
254
254
|
{"refusal"=>"InvariantViolation", "site"=>"admits_declared_set", "argument"=>"offered", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
255
255
|
{"refusal"=>"InvariantViolation", "site"=>"undeclared_set", "argument"=>"name", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
256
256
|
{"refusal"=>"InvariantViolation", "site"=>"undeclared_set", "argument"=>"admits", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
257
|
+
{"refusal"=>"InvariantViolation", "site"=>"group_by_collision", "argument"=>"read_model", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
258
|
+
{"refusal"=>"InvariantViolation", "site"=>"group_by_collision", "argument"=>"fields", "shape"=>"list", "quoting"=>"none", "separator"=>", ", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
259
|
+
{"refusal"=>"InvariantViolation", "site"=>"group_by_collision", "argument"=>"ids", "shape"=>"list", "quoting"=>"inspect", "separator"=>", ", "sorted"=>"true", "when_empty"=>""}.freeze,
|
|
260
|
+
{"refusal"=>"InvariantViolation", "site"=>"group_by_collision", "argument"=>"key", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
257
261
|
{"refusal"=>"Unauthorized", "site"=>"tenant_required", "argument"=>"query", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
258
262
|
{"refusal"=>"Unauthorized", "site"=>"tenant_required", "argument"=>"field", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
259
263
|
{"refusal"=>"Unauthorized", "site"=>"role_mismatch", "argument"=>"command", "shape"=>"scalar", "quoting"=>"none", "separator"=>"", "sorted"=>"false", "when_empty"=>""}.freeze,
|
|
@@ -314,6 +318,7 @@ module Hecks
|
|
|
314
318
|
{"refusal"=>"InvariantViolation", "site"=>"value_object_invariant", "template"=>"{name} invariant violated — {description} (given {offered})"}.freeze,
|
|
315
319
|
{"refusal"=>"InvariantViolation", "site"=>"admits_declared_set", "template"=>"{name} admits {admits} — {admitted} — got {offered}"}.freeze,
|
|
316
320
|
{"refusal"=>"InvariantViolation", "site"=>"undeclared_set", "template"=>"{name} admits {admits}, which this chapter does not declare — a closed set is named Aggregate::SetName, and it must be one the bluebook actually holds"}.freeze,
|
|
321
|
+
{"refusal"=>"InvariantViolation", "site"=>"group_by_collision", "template"=>"{read_model} groups by {fields}, but rows {ids} share {key} — a group_by leaf holds one row; add a field that tells them apart"}.freeze,
|
|
317
322
|
{"refusal"=>"Unauthorized", "site"=>"tenant_required", "template"=>"{query} declares authorize with tenant: {field} — pass {field}: to name which {field} this ask is scoped to"}.freeze,
|
|
318
323
|
{"refusal"=>"Unauthorized", "site"=>"role_mismatch", "template"=>"{command} refused — role: {role}, and the caller stated {caller_role}"}.freeze,
|
|
319
324
|
{"refusal"=>"Unauthorized", "site"=>"cross_tenant_reference", "template"=>"{aggregate} {field} is {tenant}, but {attribute} names a {target} whose own {target_field} is {other} — a cross-tenant reference"}.freeze,
|
data/lib/hecks.rb
CHANGED
|
@@ -32,10 +32,16 @@ require_relative "hecks/facade/cli_door"
|
|
|
32
32
|
require_relative "hecks/facade/cli_runner"
|
|
33
33
|
require_relative "hecks/storehouse"
|
|
34
34
|
require_relative "hecks/mcp_stdio_guard"
|
|
35
|
+
require_relative "hecks/mcp_door_scope"
|
|
35
36
|
require_relative "hecks/framework"
|
|
36
|
-
require_relative "hecks/
|
|
37
|
+
require_relative "hecks/vendoring"
|
|
37
38
|
require_relative "hecks/embryonaut_bluebook"
|
|
38
39
|
|
|
40
|
+
# Repository-only tooling: the corpus table walks `examples/`, `qa/` and
|
|
41
|
+
# `spec/`, which only a checkout has, so it loads on first use and the
|
|
42
|
+
# packaged gem leaves it out (ADR 0066).
|
|
43
|
+
Hecks.autoload(:Corpus, File.expand_path("hecks/corpus", __dir__))
|
|
44
|
+
|
|
39
45
|
# The root namespace and public facade of the whole DSL/runtime: `Hecks.boot`/
|
|
40
46
|
# `.boot_files` assemble a running domain from `.bluebook`/`.hecksagon`/
|
|
41
47
|
# `.world` files, and `.bluebook`/`.hecksagon`/`.port`/`.adapter`/`.world`/
|
|
@@ -57,7 +63,7 @@ module Hecks
|
|
|
57
63
|
# `environments/<name>.hecksagon` / `.world` overlay it loads —
|
|
58
64
|
# see Adapters::Folder#load_domain) existed on a prior commit of
|
|
59
65
|
# this repo (933d1dd), was vendored out to a real consumer
|
|
60
|
-
# (
|
|
66
|
+
# (a client site's domain), and was then lost from this repo's own
|
|
61
67
|
# history (no branch here reaches that commit). Ported forward
|
|
62
68
|
# from the consumer's vendor snapshot — the only surviving copy —
|
|
63
69
|
# and generalized: the original only loaded a `.hecksagon`
|
metadata
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hecks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Young
|
|
8
8
|
autorequire:
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 2026-09-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
@@ -30,10 +30,12 @@ description: |
|
|
|
30
30
|
Nothing is scripted: no handler body, no class you write, no schema
|
|
31
31
|
you migrate.
|
|
32
32
|
email:
|
|
33
|
-
executables:
|
|
33
|
+
executables:
|
|
34
|
+
- hecks
|
|
34
35
|
extensions: []
|
|
35
36
|
extra_rdoc_files: []
|
|
36
37
|
files:
|
|
38
|
+
- exe/hecks
|
|
37
39
|
- lib/hecks.rb
|
|
38
40
|
- lib/hecks/adapters.rb
|
|
39
41
|
- lib/hecks/adapters/driven.rb
|
|
@@ -94,17 +96,6 @@ files:
|
|
|
94
96
|
- lib/hecks/behaviors/ir.rb
|
|
95
97
|
- lib/hecks/behaviors/rspec.rb
|
|
96
98
|
- lib/hecks/behaviors/runner.rb
|
|
97
|
-
- lib/hecks/bench.rb
|
|
98
|
-
- lib/hecks/bench/cli.rb
|
|
99
|
-
- lib/hecks/bench/environment.rb
|
|
100
|
-
- lib/hecks/bench/postgres_probe.rb
|
|
101
|
-
- lib/hecks/bench/report.rb
|
|
102
|
-
- lib/hecks/bench/ruby_runner.rb
|
|
103
|
-
- lib/hecks/bench/run.rb
|
|
104
|
-
- lib/hecks/bench/rust_runner.rb
|
|
105
|
-
- lib/hecks/bench/stats.rb
|
|
106
|
-
- lib/hecks/bench/suite.rb
|
|
107
|
-
- lib/hecks/bench/workload.rb
|
|
108
99
|
- lib/hecks/bluebook.rb
|
|
109
100
|
- lib/hecks/bluebook/aggregate.rb
|
|
110
101
|
- lib/hecks/bluebook/assembly.rb
|
|
@@ -199,14 +190,27 @@ files:
|
|
|
199
190
|
- lib/hecks/bluebook/synthesizer.rb
|
|
200
191
|
- lib/hecks/bluebook/translation.rb
|
|
201
192
|
- lib/hecks/bluebook/value_object.rb
|
|
202
|
-
- lib/hecks/
|
|
193
|
+
- lib/hecks/cache_dir.rb
|
|
194
|
+
- lib/hecks/cli.rb
|
|
195
|
+
- lib/hecks/cli/document.rb
|
|
196
|
+
- lib/hecks/cli/ir.rb
|
|
197
|
+
- lib/hecks/cli/mcp.rb
|
|
198
|
+
- lib/hecks/cli/mcp_door.rb
|
|
199
|
+
- lib/hecks/cli/model_check.rb
|
|
200
|
+
- lib/hecks/cli/project_cli.rb
|
|
201
|
+
- lib/hecks/cli/project_diagrams.rb
|
|
202
|
+
- lib/hecks/cli/run.rb
|
|
203
|
+
- lib/hecks/cli/smoke_test.rb
|
|
204
|
+
- lib/hecks/cli/stores.rb
|
|
203
205
|
- lib/hecks/construct.rb
|
|
204
|
-
- lib/hecks/corpus.rb
|
|
205
206
|
- lib/hecks/deploy/bluebook/deploy.bluebook
|
|
206
207
|
- lib/hecks/deploy/bluebook/deploy.hecksagon
|
|
207
208
|
- lib/hecks/deploy/oidc.json
|
|
208
|
-
- lib/hecks/doc/reference.rb
|
|
209
209
|
- lib/hecks/embryonaut_bluebook.rb
|
|
210
|
+
- lib/hecks/embryonaut_bluebook/lock.rb
|
|
211
|
+
- lib/hecks/embryonaut_bluebook/shape.rb
|
|
212
|
+
- lib/hecks/embryonaut_bluebook/vendor.rb
|
|
213
|
+
- lib/hecks/embryonaut_bluebook/vendor_cli.rb
|
|
210
214
|
- lib/hecks/facade.rb
|
|
211
215
|
- lib/hecks/facade/cli_door.rb
|
|
212
216
|
- lib/hecks/facade/cli_runner.rb
|
|
@@ -242,47 +246,7 @@ files:
|
|
|
242
246
|
- lib/hecks/framework/bluebook/privacy.bluebook
|
|
243
247
|
- lib/hecks/framework/oidc.json
|
|
244
248
|
- lib/hecks/freezer.rb
|
|
245
|
-
- lib/hecks/fuzzing.rb
|
|
246
|
-
- lib/hecks/fuzzing/bounded_exhaustive_expressions.rb
|
|
247
|
-
- lib/hecks/fuzzing/combination_miner.rb
|
|
248
|
-
- lib/hecks/fuzzing/concurrent_dispatch.rb
|
|
249
|
-
- lib/hecks/fuzzing/coverage_campaign.rb
|
|
250
|
-
- lib/hecks/fuzzing/differential.rb
|
|
251
|
-
- lib/hecks/fuzzing/domain_generator.rb
|
|
252
|
-
- lib/hecks/fuzzing/era_boundary.rb
|
|
253
|
-
- lib/hecks/fuzzing/form_census.rb
|
|
254
|
-
- lib/hecks/fuzzing/generated_domain_check.rb
|
|
255
|
-
- lib/hecks/fuzzing/invalid_value_generator.rb
|
|
256
|
-
- lib/hecks/fuzzing/isolated_boot.rb
|
|
257
|
-
- lib/hecks/fuzzing/nondeterministic.rb
|
|
258
|
-
- lib/hecks/fuzzing/persistence_parity.rb
|
|
259
|
-
- lib/hecks/fuzzing/properties.rb
|
|
260
|
-
- lib/hecks/fuzzing/properties/corrections.rb
|
|
261
|
-
- lib/hecks/fuzzing/properties/dispatch_and_mutations.rb
|
|
262
|
-
- lib/hecks/fuzzing/properties/guards.rb
|
|
263
|
-
- lib/hecks/fuzzing/properties/invariants_and_aggregation.rb
|
|
264
|
-
- lib/hecks/fuzzing/properties/lifecycle_and_replay.rb
|
|
265
|
-
- lib/hecks/fuzzing/properties/outbox.rb
|
|
266
|
-
- lib/hecks/fuzzing/properties/querying.rb
|
|
267
|
-
- lib/hecks/fuzzing/qa_settings.rb
|
|
268
|
-
- lib/hecks/fuzzing/replay.rb
|
|
269
|
-
- lib/hecks/fuzzing/rotation_priority.rb
|
|
270
|
-
- lib/hecks/fuzzing/rust_gap_manifest.rb
|
|
271
|
-
- lib/hecks/fuzzing/self_consistency.rb
|
|
272
|
-
- lib/hecks/fuzzing/sequence_generator.rb
|
|
273
|
-
- lib/hecks/fuzzing/sequence_generator/adversary.rb
|
|
274
|
-
- lib/hecks/fuzzing/sequence_generator/catalog.rb
|
|
275
|
-
- lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb
|
|
276
|
-
- lib/hecks/fuzzing/sequence_generator/picker.rb
|
|
277
|
-
- lib/hecks/fuzzing/sequence_generator/query_binding.rb
|
|
278
|
-
- lib/hecks/fuzzing/sequence_generator/step_builder.rb
|
|
279
|
-
- lib/hecks/fuzzing/shrinker.rb
|
|
280
|
-
- lib/hecks/fuzzing/structural_skips.rb
|
|
281
|
-
- lib/hecks/fuzzing/sweep_depth.rb
|
|
282
|
-
- lib/hecks/fuzzing/target_capabilities.rb
|
|
283
|
-
- lib/hecks/fuzzing/value_generator.rb
|
|
284
249
|
- lib/hecks/grammar.rb
|
|
285
|
-
- lib/hecks/grammar/evolve.rb
|
|
286
250
|
- lib/hecks/grammar/expression.bluebook
|
|
287
251
|
- lib/hecks/grammar/expression_operators.json
|
|
288
252
|
- lib/hecks/grammar/grammar.hecksagon
|
|
@@ -314,6 +278,7 @@ files:
|
|
|
314
278
|
- lib/hecks/language/world/wiring.bluebook
|
|
315
279
|
- lib/hecks/language/world/world.bluebook
|
|
316
280
|
- lib/hecks/literal.rb
|
|
281
|
+
- lib/hecks/mcp_door_scope.rb
|
|
317
282
|
- lib/hecks/mcp_stdio_guard.rb
|
|
318
283
|
- lib/hecks/naming.rb
|
|
319
284
|
- lib/hecks/ports.rb
|
|
@@ -353,6 +318,7 @@ files:
|
|
|
353
318
|
- lib/hecks/ports/persistence/plugins/era/era_guard.rb
|
|
354
319
|
- lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb
|
|
355
320
|
- lib/hecks/ports/persistence/plugins/era/era_tamper.rb
|
|
321
|
+
- lib/hecks/ports/persistence/plugins/era/expected_era.rb
|
|
356
322
|
- lib/hecks/ports/persistence/plugins/era/lineage.rb
|
|
357
323
|
- lib/hecks/ports/persistence/plugins/era/postgres_era.rb
|
|
358
324
|
- lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb
|
|
@@ -382,6 +348,8 @@ files:
|
|
|
382
348
|
- lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb
|
|
383
349
|
- lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb
|
|
384
350
|
- lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb
|
|
351
|
+
- lib/hecks/ports/persistence/postgres_dump.rb
|
|
352
|
+
- lib/hecks/ports/persistence/postgres_dump/connection.rb
|
|
385
353
|
- lib/hecks/ports/persistence/remote_runtime.rb
|
|
386
354
|
- lib/hecks/ports/persistence/repository_factory.rb
|
|
387
355
|
- lib/hecks/ports/persistence/state_codec.rb
|
|
@@ -393,8 +361,39 @@ files:
|
|
|
393
361
|
- lib/hecks/projections.rb
|
|
394
362
|
- lib/hecks/projections/bootstrap_table.rb
|
|
395
363
|
- lib/hecks/projections/deploy/fargate.rb
|
|
364
|
+
- lib/hecks/projections/deploy/fargate/assembly.rb
|
|
365
|
+
- lib/hecks/projections/deploy/fargate/cdn.rb
|
|
366
|
+
- lib/hecks/projections/deploy/fargate/cdn_default.rb
|
|
367
|
+
- lib/hecks/projections/deploy/fargate/check.rb
|
|
368
|
+
- lib/hecks/projections/deploy/fargate/containers.rb
|
|
369
|
+
- lib/hecks/projections/deploy/fargate/extras.rb
|
|
370
|
+
- lib/hecks/projections/deploy/fargate/monitoring.rb
|
|
371
|
+
- lib/hecks/projections/deploy/fargate/settings.rb
|
|
372
|
+
- lib/hecks/projections/deploy/fargate/yaml.rb
|
|
396
373
|
- lib/hecks/projections/deploy/lambda.rb
|
|
374
|
+
- lib/hecks/projections/deploy/preview.rb
|
|
375
|
+
- lib/hecks/projections/deploy/preview/access_yaml.rb
|
|
376
|
+
- lib/hecks/projections/deploy/preview/containers.rb
|
|
377
|
+
- lib/hecks/projections/deploy/preview/preview.sh.erb
|
|
378
|
+
- lib/hecks/projections/deploy/preview/routing_yaml.rb
|
|
379
|
+
- lib/hecks/projections/deploy/preview/script.rb
|
|
380
|
+
- lib/hecks/projections/deploy/preview/settings.rb
|
|
381
|
+
- lib/hecks/projections/deploy/preview/task_yaml.rb
|
|
382
|
+
- lib/hecks/projections/deploy/preview/template.rb
|
|
383
|
+
- lib/hecks/projections/deploy/preview/yaml_text.rb
|
|
384
|
+
- lib/hecks/projections/deploy/scripts.rb
|
|
385
|
+
- lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl
|
|
386
|
+
- lib/hecks/projections/deploy/scripts/expected-era.header
|
|
387
|
+
- lib/hecks/projections/deploy/scripts/hosting.mk.tmpl
|
|
388
|
+
- lib/hecks/projections/deploy/scripts/settings.rb
|
|
389
|
+
- lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl
|
|
397
390
|
- lib/hecks/projections/deploy/shared.rb
|
|
391
|
+
- lib/hecks/projections/deploy/smoke.rb
|
|
392
|
+
- lib/hecks/projections/deploy/smoke/harness.js
|
|
393
|
+
- lib/hecks/projections/deploy/smoke/workflow.yml.tmpl
|
|
394
|
+
- lib/hecks/projections/deploy/template_diff.rb
|
|
395
|
+
- lib/hecks/projections/deploy/template_diff/comparer.rb
|
|
396
|
+
- lib/hecks/projections/deploy/template_diff/loader.rb
|
|
398
397
|
- lib/hecks/projections/diagrams.rb
|
|
399
398
|
- lib/hecks/projections/glossary.rb
|
|
400
399
|
- lib/hecks/projections/glossary/html.rb
|
|
@@ -422,7 +421,6 @@ files:
|
|
|
422
421
|
- lib/hecks/projector/ir_projector.rb
|
|
423
422
|
- lib/hecks/projector/narrate_projector.rb
|
|
424
423
|
- lib/hecks/projector/target.rb
|
|
425
|
-
- lib/hecks/query_ir.rb
|
|
426
424
|
- lib/hecks/query_specification.rb
|
|
427
425
|
- lib/hecks/query_specification/common/authorization_spec.rb
|
|
428
426
|
- lib/hecks/query_specification/common/comparators.rb
|
|
@@ -441,6 +439,18 @@ files:
|
|
|
441
439
|
- lib/hecks/query_specification/field_path.rb
|
|
442
440
|
- lib/hecks/query_specification/hop_path.rb
|
|
443
441
|
- lib/hecks/query_specification/read_model/specification.rb
|
|
442
|
+
- lib/hecks/release/gem_pin.rb
|
|
443
|
+
- lib/hecks/release/gem_pin/published_versions.rb
|
|
444
|
+
- lib/hecks/release/runner.rb
|
|
445
|
+
- lib/hecks/release/runner/ci_publisher.rb
|
|
446
|
+
- lib/hecks/release/runner/commands.rb
|
|
447
|
+
- lib/hecks/release/runner/console.rb
|
|
448
|
+
- lib/hecks/release/runner/gem_publisher.rb
|
|
449
|
+
- lib/hecks/release/runner/git.rb
|
|
450
|
+
- lib/hecks/release/runner/npm_publisher.rb
|
|
451
|
+
- lib/hecks/release/runner/preflight.rb
|
|
452
|
+
- lib/hecks/release/runner/published.rb
|
|
453
|
+
- lib/hecks/release/runner/tagger.rb
|
|
444
454
|
- lib/hecks/rendering.rb
|
|
445
455
|
- lib/hecks/router.rb
|
|
446
456
|
- lib/hecks/router/namespace_installer.rb
|
|
@@ -481,6 +491,7 @@ files:
|
|
|
481
491
|
- lib/hecks/runtime/registry.rb
|
|
482
492
|
- lib/hecks/runtime/registry/saga_persistence.rb
|
|
483
493
|
- lib/hecks/runtime/registry/verification.rb
|
|
494
|
+
- lib/hecks/runtime/registry/world_defaults.rb
|
|
484
495
|
- lib/hecks/runtime/remote_dispatcher.rb
|
|
485
496
|
- lib/hecks/runtime/routing.rb
|
|
486
497
|
- lib/hecks/runtime/saga_interpreter.rb
|
|
@@ -496,6 +507,9 @@ files:
|
|
|
496
507
|
- lib/hecks/storehouse.rb
|
|
497
508
|
- lib/hecks/tenancy/bluebook/tenancy.bluebook
|
|
498
509
|
- lib/hecks/tenancy/bluebook/tenancy.hecksagon
|
|
510
|
+
- lib/hecks/vendoring.rb
|
|
511
|
+
- lib/hecks/vendoring/git_environment.rb
|
|
512
|
+
- lib/hecks/vendoring/git_source.rb
|
|
499
513
|
- lib/hecks/version.rb
|
|
500
514
|
- lib/hecks/vocabulary.rb
|
|
501
515
|
- lib/rubocop/cop/hecks/fallback_hash_lookup.rb
|
data/lib/hecks/bench/cli.rb
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
require "optparse"
|
|
2
|
-
require_relative "suite"
|
|
3
|
-
require_relative "report"
|
|
4
|
-
|
|
5
|
-
module Hecks
|
|
6
|
-
module Bench
|
|
7
|
-
# The command line behind `bin/bench`: parses flags, runs the `Suite`, prints the report.
|
|
8
|
-
#
|
|
9
|
-
# Kept in `lib/` so a spec can drive it with a tiny configuration and read what it
|
|
10
|
-
# prints, rather than shelling out to a script.
|
|
11
|
-
module CLI
|
|
12
|
-
# The defaults `bin/bench` runs with when no flag says otherwise.
|
|
13
|
-
DEFAULTS = { domains: %w[pizzas banking], targets: Suite::TARGETS, warmup: 200, iterations: 1000,
|
|
14
|
-
runs: 3 }.freeze
|
|
15
|
-
|
|
16
|
-
module_function
|
|
17
|
-
|
|
18
|
-
# Runs the benchmark described by the command line and prints its report.
|
|
19
|
-
#
|
|
20
|
-
# @param argv [Array<String>] the command-line arguments
|
|
21
|
-
# @param out [#puts] where the report goes
|
|
22
|
-
# @param err [#puts] where progress and usage errors go
|
|
23
|
-
# @return [Integer] the process exit status: 0 on success, 2 for a usage error
|
|
24
|
-
def run(argv, out: $stdout, err: $stderr)
|
|
25
|
-
options = parse(argv)
|
|
26
|
-
result = Suite.call(options.fetch(:config), log: err)
|
|
27
|
-
out.puts(options[:format] == "json" ? Report.json(result) : Report.markdown(result))
|
|
28
|
-
File.write(options[:output], Report.json(result)) if options[:output]
|
|
29
|
-
0
|
|
30
|
-
rescue OptionParser::ParseError, ArgumentError => e
|
|
31
|
-
err.puts "bin/bench: #{e.message}"
|
|
32
|
-
2
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Turns command-line arguments into a configuration and output choices.
|
|
36
|
-
#
|
|
37
|
-
# @param argv [Array<String>] the command-line arguments
|
|
38
|
-
# @return [Hash{Symbol => Object}] `:config` (a `Suite::Config`), `:format` and `:output`
|
|
39
|
-
# @raise [OptionParser::ParseError] on an unknown or malformed flag
|
|
40
|
-
def parse(argv)
|
|
41
|
-
values = DEFAULTS.dup
|
|
42
|
-
extras = { format: "markdown", output: nil, rust_binary: nil }
|
|
43
|
-
parser(values, extras).parse(argv.dup)
|
|
44
|
-
{ config: Suite::Config.new(**values, rust_binary: extras[:rust_binary]),
|
|
45
|
-
format: extras[:format], output: extras[:output] }
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Builds the flag parser.
|
|
49
|
-
#
|
|
50
|
-
# @param values [Hash{Symbol => Object}] the `Suite::Config` fields, filled in as flags parse
|
|
51
|
-
# @param extras [Hash{Symbol => Object}] the output choices, filled in as flags parse
|
|
52
|
-
# @return [OptionParser] the parser
|
|
53
|
-
def parser(values, extras)
|
|
54
|
-
OptionParser.new do |opts|
|
|
55
|
-
opts.banner = "usage: bin/bench [options]"
|
|
56
|
-
opts.on("--domain NAMES", Array, "pizzas, banking (default: both)") { |v| values[:domains] = v }
|
|
57
|
-
opts.on("--targets NAMES", Array, "#{Suite::TARGETS.join(', ')} (default: all)") { |v| values[:targets] = v }
|
|
58
|
-
opts.on("--iterations N", Integer, "timed cycles per run (default #{DEFAULTS[:iterations]})") do |v|
|
|
59
|
-
values[:iterations] = v
|
|
60
|
-
end
|
|
61
|
-
opts.on("--warmup N", Integer, "discarded cycles before timing (default #{DEFAULTS[:warmup]})") do |v|
|
|
62
|
-
values[:warmup] = v
|
|
63
|
-
end
|
|
64
|
-
opts.on("--runs N", Integer, "fresh boots per target, median reported (default #{DEFAULTS[:runs]})") do |v|
|
|
65
|
-
values[:runs] = v
|
|
66
|
-
end
|
|
67
|
-
opts.on("--rust-binary PATH", "use this `rust` binary instead of building one") { |v| extras[:rust_binary] = v }
|
|
68
|
-
opts.on("--format FORMAT", %w[markdown json], "markdown (default) or json") { |v| extras[:format] = v }
|
|
69
|
-
opts.on("--output PATH", "also write the full JSON result here") { |v| extras[:output] = v }
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
require "etc"
|
|
2
|
-
require "open3"
|
|
3
|
-
|
|
4
|
-
module Hecks
|
|
5
|
-
module Bench
|
|
6
|
-
# A description of the machine and toolchain a benchmark ran on.
|
|
7
|
-
#
|
|
8
|
-
# A number without its hardware is not reproducible, so every report carries
|
|
9
|
-
# this. Each probe is best effort: a missing tool becomes `"unknown"` rather
|
|
10
|
-
# than an error, since the benchmark itself is still valid without it.
|
|
11
|
-
module Environment
|
|
12
|
-
module_function
|
|
13
|
-
|
|
14
|
-
# Collects the machine and toolchain facts a report should carry.
|
|
15
|
-
#
|
|
16
|
-
# @return [Hash{Symbol => Object}] `:cpu`, `:cores`, `:memory_gib`, `:os`, `:ruby`,
|
|
17
|
-
# `:yjit`, `:rustc`, `:cargo`, `:hecks`, `:commit` and `:load_average`
|
|
18
|
-
def describe
|
|
19
|
-
{
|
|
20
|
-
cpu: cpu, cores: Etc.nprocessors, memory_gib: memory_gib, os: os,
|
|
21
|
-
ruby: RUBY_DESCRIPTION, yjit: yjit?,
|
|
22
|
-
rustc: capture("rustc", "-V"), cargo: capture("cargo", "-V"),
|
|
23
|
-
hecks: Hecks::VERSION, commit: commit, load_average: load_average
|
|
24
|
-
}
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Reads the one-minute load average, the quickest sign that something else was
|
|
28
|
-
# busy while a benchmark ran. `Suite.call` reads it before and after and reports both.
|
|
29
|
-
#
|
|
30
|
-
# @return [Float, nil] the one-minute load average, or nil when it cannot be read
|
|
31
|
-
def load_average
|
|
32
|
-
text = RUBY_PLATFORM.include?("darwin") ? capture("sysctl", "-n", "vm.loadavg").delete("{}") : File.read("/proc/loadavg")
|
|
33
|
-
text.split.first.to_f.round(2)
|
|
34
|
-
rescue SystemCallError
|
|
35
|
-
nil
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Names the processor.
|
|
39
|
-
#
|
|
40
|
-
# @return [String] the CPU model, or `"unknown"`
|
|
41
|
-
def cpu
|
|
42
|
-
return capture("sysctl", "-n", "machdep.cpu.brand_string") if RUBY_PLATFORM.include?("darwin")
|
|
43
|
-
|
|
44
|
-
model = File.foreach("/proc/cpuinfo").find { |line| line.start_with?("model name") }
|
|
45
|
-
model ? model.split(":", 2).last.strip : "unknown"
|
|
46
|
-
rescue SystemCallError
|
|
47
|
-
"unknown"
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Reads installed memory.
|
|
51
|
-
#
|
|
52
|
-
# @return [Float, String] physical memory in GiB, or `"unknown"`
|
|
53
|
-
def memory_gib
|
|
54
|
-
bytes =
|
|
55
|
-
if RUBY_PLATFORM.include?("darwin")
|
|
56
|
-
capture("sysctl", "-n", "hw.memsize").to_i
|
|
57
|
-
else
|
|
58
|
-
File.read("/proc/meminfo")[/MemTotal:\s+(\d+)/, 1].to_i * 1024
|
|
59
|
-
end
|
|
60
|
-
bytes.zero? ? "unknown" : (bytes / (1024.0**3)).round(1)
|
|
61
|
-
rescue SystemCallError
|
|
62
|
-
"unknown"
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# Names the operating system.
|
|
66
|
-
#
|
|
67
|
-
# @return [String] the OS name and version, or `"unknown"`
|
|
68
|
-
def os
|
|
69
|
-
return "macOS #{capture('sw_vers', '-productVersion')} (#{capture('uname', '-m')})" if RUBY_PLATFORM.include?("darwin")
|
|
70
|
-
|
|
71
|
-
capture("uname", "-sr")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# Says whether Ruby's `YJIT` compiler was running.
|
|
75
|
-
#
|
|
76
|
-
# @return [Boolean] true when `YJIT` is enabled in this process
|
|
77
|
-
def yjit?
|
|
78
|
-
defined?(RubyVM::YJIT) ? RubyVM::YJIT.enabled? : false
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Names the Hecks source revision under test.
|
|
82
|
-
#
|
|
83
|
-
# @return [String] the short commit hash, or `"unknown"` outside a git checkout
|
|
84
|
-
def commit
|
|
85
|
-
capture("git", "-C", File.expand_path("../../..", __dir__), "rev-parse", "--short", "HEAD")
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Runs a command and returns its first line of output.
|
|
89
|
-
#
|
|
90
|
-
# @param command [Array<String>] the program and its arguments
|
|
91
|
-
# @return [String] the trimmed first line of stdout, or `"unknown"` if it cannot run
|
|
92
|
-
def capture(*command)
|
|
93
|
-
out, status = Open3.capture2(*command, err: File::NULL)
|
|
94
|
-
status.success? && !out.strip.empty? ? out.lines.first.strip : "unknown"
|
|
95
|
-
rescue SystemCallError
|
|
96
|
-
"unknown"
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
module Hecks
|
|
2
|
-
module Bench
|
|
3
|
-
# Decides whether the Postgres targets can run at all.
|
|
4
|
-
#
|
|
5
|
-
# Postgres is optional. A machine with no server, or without the `pg` gem, gets a
|
|
6
|
-
# skipped target and a sentence saying why, never a stack trace. Connection
|
|
7
|
-
# settings come from libpq's own environment (`PGHOST`, `PGPORT`, `PGUSER`,
|
|
8
|
-
# `PGPASSWORD`), the same way the fuzzer's Postgres adapters read them.
|
|
9
|
-
module PostgresProbe
|
|
10
|
-
module_function
|
|
11
|
-
|
|
12
|
-
# Tries to reach the server's maintenance database.
|
|
13
|
-
#
|
|
14
|
-
# @return [String, nil] nil when a server answered, otherwise one sentence saying why
|
|
15
|
-
# the Postgres targets cannot run
|
|
16
|
-
def unavailable_reason
|
|
17
|
-
require "pg"
|
|
18
|
-
PG.connect(dbname: "postgres", connect_timeout: 2).close
|
|
19
|
-
nil
|
|
20
|
-
rescue LoadError
|
|
21
|
-
"the `pg` gem is not installed"
|
|
22
|
-
rescue PG::Error => e
|
|
23
|
-
"no Postgres server is reachable (#{e.message.lines.first.to_s.strip}); start one, or point " \
|
|
24
|
-
"PGHOST, PGPORT and PGUSER at one"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Reads the server's version for the report's environment block.
|
|
28
|
-
#
|
|
29
|
-
# @return [String] the `server_version` setting, or `"unknown"` if it cannot be read
|
|
30
|
-
def server_version
|
|
31
|
-
require "pg"
|
|
32
|
-
connection = PG.connect(dbname: "postgres", connect_timeout: 2)
|
|
33
|
-
connection.exec("SHOW server_version").getvalue(0, 0)
|
|
34
|
-
rescue LoadError, PG::Error
|
|
35
|
-
"unknown"
|
|
36
|
-
ensure
|
|
37
|
-
connection&.close
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|