hecks 3.3.0 → 3.4.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/lib/hecks/bluebook/dsl/hecksagon_builder.rb +21 -23
- data/lib/hecks/cli/interview_draft.rb +2 -2
- data/lib/hecks/cli/interview_shape.rb +19 -0
- data/lib/hecks/corpus.rb +3 -5
- data/lib/hecks/doors.rb +0 -17
- data/lib/hecks/fuzzing/isolated_boot.rb +1 -4
- data/lib/hecks/fuzzing/target_capabilities.rb +1 -1
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +0 -5
- data/lib/hecks/runtime/loader.rb +6 -7
- data/lib/hecks/runtime.rb +6 -11
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks.rb +6 -12
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/parser/src/keywords.rs +0 -4
- data/rust/parser/src/lex.rs +1 -1
- data/rust/parser/src/parse/hecksagon.rs +15 -24
- metadata +1 -2
- data/lib/hecks/facade.rb +0 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b6180e44456a48f89b02b8812b4f327fe1642f98756e8e4c0b1bb295a04f826b
|
|
4
|
+
data.tar.gz: 6bc10cd76fb9c112ce9d7a5b82295a2e2a4c101d1b10b195ab48cd1afefd75c7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56cfe2cebc08a7aac900d8ef700590aa66855ea0baf28eebb9096f0f74c4d51da5ef42167cffdc6f1bcc733c3cacf8e329bf1352821655247c36e17275614123
|
|
7
|
+
data.tar.gz: 37cc4287ecf68af46b507dff79b3041de0a6e28fe2a1a7e5d89bea393b74d5f84eead4e11509c0f16d47d11ec8abfe9b292d73ec14845d9466e086dcec3bf350
|
|
@@ -57,9 +57,12 @@ module Hecks
|
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
|
|
60
|
+
# Spellings of `attaches` that 3.4.0 removed, each with the form that replaces it. They
|
|
61
|
+
# are refused by name so an old hecksagon fails loudly, never as a stray default bind.
|
|
62
|
+
REMOVED_WORDS = {
|
|
63
|
+
"uses_framework" => ->(name) { "attaches #{name.to_s.inspect}" },
|
|
64
|
+
"uses_embryonaut_bluebook" => ->(name) { "attaches #{name.to_s.inspect}, from: :vendor" }
|
|
65
|
+
}.freeze
|
|
63
66
|
|
|
64
67
|
attr_reader :binds, :subscriptions, :attachments
|
|
65
68
|
|
|
@@ -100,20 +103,6 @@ module Hecks
|
|
|
100
103
|
from == :vendor ? attach_vendored(name) : attach_gem(name)
|
|
101
104
|
end
|
|
102
105
|
|
|
103
|
-
# The deprecated spelling of `attaches "Name"` for a framework member.
|
|
104
|
-
def uses_framework(name)
|
|
105
|
-
deprecated_word("uses_framework", "attaches #{name.to_s.inspect}")
|
|
106
|
-
@attachments << Attachment.new(name: name.to_s, source: :gem)
|
|
107
|
-
self.class.with_real_modules { Hecks::Framework.load!(name) }
|
|
108
|
-
Hecks.current_registry&.mark_bounded(name.to_s)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# The deprecated spelling of `attaches "name", from: :vendor`.
|
|
112
|
-
def uses_embryonaut_bluebook(name)
|
|
113
|
-
deprecated_word("uses_embryonaut_bluebook", "attaches #{name.to_s.inspect}, from: :vendor")
|
|
114
|
-
attach_vendored(name)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
106
|
# Declares a port at the hecksagon's root — the chapter as a whole, not one aggregate.
|
|
118
107
|
def port_impl(name, &block)
|
|
119
108
|
bluebook_ir = Hecks.current_registry.bluebook(@domain) or
|
|
@@ -170,15 +159,11 @@ module Hecks
|
|
|
170
159
|
end
|
|
171
160
|
private :attach_vendored
|
|
172
161
|
|
|
173
|
-
# Tells the author that a word is going away.
|
|
174
|
-
def deprecated_word(word, instead)
|
|
175
|
-
warn "[hecks] `#{word}` is deprecated and is removed in #{REMOVAL}; use `#{instead}`"
|
|
176
|
-
end
|
|
177
|
-
private :deprecated_word
|
|
178
|
-
|
|
179
162
|
# Records any verb the grammar doesn't own as a domain-wide default bind, e.g. bare
|
|
180
163
|
# `persisted_by "Heki"` at the top of a block, applied unless an aggregate overrides it.
|
|
181
164
|
def method_missing(verb, *args, **kwargs, &block)
|
|
165
|
+
refuse_removed_word(verb, args.first)
|
|
166
|
+
|
|
182
167
|
# Grammar words (like `port`) get first refusal via explicit dispatch; only when that's
|
|
183
168
|
# not admitted does the open-ended `persisted_by`-style bind vocabulary below apply.
|
|
184
169
|
result = word_gate_dispatch(verb, args, kwargs, block)
|
|
@@ -191,6 +176,19 @@ module Hecks
|
|
|
191
176
|
self
|
|
192
177
|
end
|
|
193
178
|
|
|
179
|
+
# Raises for a word 3.4.0 removed, naming the spelling that replaces it.
|
|
180
|
+
#
|
|
181
|
+
# @param verb [Symbol] the word the hecksagon block called
|
|
182
|
+
# @param name [Object, nil] its first argument, echoed into the replacement
|
|
183
|
+
# @raise [Malformed] when the word is one of `REMOVED_WORDS`
|
|
184
|
+
def refuse_removed_word(verb, name)
|
|
185
|
+
instead = REMOVED_WORDS[verb.to_s]
|
|
186
|
+
return unless instead
|
|
187
|
+
|
|
188
|
+
raise Malformed, "`#{verb}` was removed in 3.4.0; use `#{instead.call(name)}`"
|
|
189
|
+
end
|
|
190
|
+
private :refuse_removed_word
|
|
191
|
+
|
|
194
192
|
def respond_to_missing?(_name, _include_private = false) = true
|
|
195
193
|
|
|
196
194
|
# Evaluates a `Hecks.hecksagon` block with bare `Domain::Aggregate` constants resolving to
|
|
@@ -113,7 +113,7 @@ module Hecks
|
|
|
113
113
|
# The aggregates, with their commands: the part a later interview offers to merge.
|
|
114
114
|
# @api private
|
|
115
115
|
def fragment(interview)
|
|
116
|
-
things = accepted(interview, :things)
|
|
116
|
+
things = accepted(interview, :things).uniq { |t| word(t[:name]) }
|
|
117
117
|
actions = accepted(interview, :actions)
|
|
118
118
|
placed = things.map { |t| word(t[:name]) }
|
|
119
119
|
blocks = things.map { |thing| aggregate(interview, thing, actions) }
|
|
@@ -151,7 +151,7 @@ module Hecks
|
|
|
151
151
|
def shape_of(interview, thing, actions)
|
|
152
152
|
name = word(thing[:name])
|
|
153
153
|
identifier = Naming.snake(word(thing[:identifier]))
|
|
154
|
-
mine = actions.select { |a| word(a[:thing]) == name }
|
|
154
|
+
mine = InterviewShape.merged_actions(actions.select { |a| word(a[:thing]) == name })
|
|
155
155
|
steps = accepted(interview, :transitions).select { |s| word(s[:thing]) == name }
|
|
156
156
|
found = accepted(interview, :fields).select { |f| word(f[:thing]) == name }
|
|
157
157
|
type = identifier_type(name, identifier)
|
|
@@ -121,6 +121,25 @@ module Hecks
|
|
|
121
121
|
" end", *loose.map { |step| loose_line(step) }]
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
+
# One action for each name: an expert who refines an answer gets the same action accepted more
|
|
125
|
+
# than once, and a command can be declared only once. The first one's event and place in the
|
|
126
|
+
# interview stay; what each takes is joined, who does it is joined, and it creates if any did.
|
|
127
|
+
#
|
|
128
|
+
# @param actions [Array<Hash>] a thing's accepted actions
|
|
129
|
+
# @return [Array<Hash>] the actions, with each name once and in the order first accepted
|
|
130
|
+
def merged_actions(actions)
|
|
131
|
+
actions.group_by { |action| InterviewDraft.word(action[:name]) }.values.map do |group|
|
|
132
|
+
group.first.merge(creates: group.any? { |a| a[:creates] }, takes: joined(group, :takes, ", "),
|
|
133
|
+
by: joined(group, :by, " or "))
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# @api private
|
|
138
|
+
def joined(group, key, separator)
|
|
139
|
+
parts = group.flat_map { |a| a[key].to_s.split(separator == ", " ? /\s*,\s*/ : /\s+or\s+/) }
|
|
140
|
+
parts.map(&:strip).reject(&:empty?).uniq.join(separator)
|
|
141
|
+
end
|
|
142
|
+
|
|
124
143
|
# @api private
|
|
125
144
|
def field_row(finding, taken, identifier, lifecycle)
|
|
126
145
|
field = Naming.snake(InterviewDraft.word(finding[:name]))
|
data/lib/hecks/corpus.rb
CHANGED
|
@@ -241,8 +241,7 @@ module Hecks
|
|
|
241
241
|
"of rust/src/generated, and there is no directory to fuzz")
|
|
242
242
|
}.freeze
|
|
243
243
|
|
|
244
|
-
# Every place a Rust-facing domain's own `attaches`
|
|
245
|
-
# `uses_embryonaut_bluebook`) attachment could be declared.
|
|
244
|
+
# Every place a Rust-facing domain's own `attaches` attachment could be declared.
|
|
246
245
|
#
|
|
247
246
|
# @param root [String] repository root to search under
|
|
248
247
|
# @return [String] every reachable hecksagon file's own text, joined by newlines
|
|
@@ -310,11 +309,10 @@ module Hecks
|
|
|
310
309
|
|
|
311
310
|
# The stamp hecks project_rust writes into metadata.rs, e.g.
|
|
312
311
|
# `examples/pizzas` or `the self-hosted language (...)`, with any
|
|
313
|
-
# ` (attaches "X")`/` (attaches "x", from: :vendor)` suffix stripped
|
|
314
|
-
# `uses_framework` / `uses_embryonaut_bluebook` spellings too).
|
|
312
|
+
# ` (attaches "X")`/` (attaches "x", from: :vendor)` suffix stripped.
|
|
315
313
|
SOURCE_STAMP = /
|
|
316
314
|
GENERATED\ by\ hecks\ project_rust\ —\ (.+?)
|
|
317
|
-
(?:\ \(
|
|
315
|
+
(?:\ \(attaches\ "\w+"(?:,\ from:\ :vendor)?\))?
|
|
318
316
|
's\ own\ canonical\ IR,
|
|
319
317
|
/x
|
|
320
318
|
|
data/lib/hecks/doors.rb
CHANGED
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
# The class-free public surface, installed per boot by `Runtime::Loader.bind_runtime`.
|
|
3
3
|
module Doors
|
|
4
|
-
# The removal release of the `Facade` and `install_facade:` spellings.
|
|
5
|
-
REMOVAL = "3.4.0".freeze
|
|
6
|
-
|
|
7
|
-
module_function
|
|
8
|
-
|
|
9
|
-
# Resolves the boot switch from the current keyword and its deprecated spelling.
|
|
10
|
-
#
|
|
11
|
-
# @param install_doors [Boolean] the `install_doors:` keyword
|
|
12
|
-
# @param install_facade [Boolean, nil] the deprecated `install_facade:` keyword; nil when
|
|
13
|
-
# the caller did not pass it
|
|
14
|
-
# @return [Boolean] whether to install the Ruby door constants
|
|
15
|
-
def install?(install_doors, install_facade = nil)
|
|
16
|
-
return install_doors if install_facade.nil?
|
|
17
|
-
|
|
18
|
-
warn "[hecks] `install_facade:` is deprecated and is removed in #{REMOVAL}; use `install_doors:`"
|
|
19
|
-
install_facade
|
|
20
|
-
end
|
|
21
4
|
end
|
|
22
5
|
|
|
23
6
|
# Installs facade constants at top level, replacing only what it installed itself.
|
|
@@ -12,9 +12,6 @@ module Hecks
|
|
|
12
12
|
# A vendored package named by `attaches "name", from: :vendor`.
|
|
13
13
|
VENDORED_ATTACHED = /attaches\s*\(?\s*"([\w-]+)"\s*\)?\s*,\s*from:\s*:vendor/
|
|
14
14
|
|
|
15
|
-
# A vendored package named by the deprecated `uses_embryonaut_bluebook "name"`.
|
|
16
|
-
VENDORED_DEPRECATED = /uses_embryonaut_bluebook\s*\(?\s*"([\w-]+)"/
|
|
17
|
-
|
|
18
15
|
module_function
|
|
19
16
|
|
|
20
17
|
# Copies `domain_path` to a tmpdir, rebinds its persistence to `adapter`, and
|
|
@@ -74,7 +71,7 @@ module Hecks
|
|
|
74
71
|
def carry_vendored_bluebooks!(source, destination)
|
|
75
72
|
names = Dir.glob(File.join(destination, "**", "*.hecksagon")).flat_map do |path|
|
|
76
73
|
text = File.read(path)
|
|
77
|
-
|
|
74
|
+
text.scan(VENDORED_ATTACHED).flatten
|
|
78
75
|
end
|
|
79
76
|
names.uniq.each do |name|
|
|
80
77
|
package = File.join(File.dirname(source), "vendor", "embryonaut_bluebooks", name)
|
|
@@ -16,7 +16,7 @@ module Hecks
|
|
|
16
16
|
POSTGRES_ERA_VARIABLE = /^\s*([a-z_]\w*)\s*=\s*"PostgresEra"\s*(?:#.*)?$/
|
|
17
17
|
|
|
18
18
|
# Captures the member a hecksagon attaches; authorization is read off its declaration.
|
|
19
|
-
FRAMEWORK_ATTACHED = /
|
|
19
|
+
FRAMEWORK_ATTACHED = /attaches\s*\(?\s*"([^"]+)"/
|
|
20
20
|
|
|
21
21
|
# A command-level `role "..."`, the only construct a role check can compare a caller against.
|
|
22
22
|
ROLE_GATED = /^\s*role\s+"/
|
|
@@ -83,9 +83,6 @@ Hecks.bluebook "Hecksagon" do
|
|
|
83
83
|
member word: "hecksagon", context: "File", body: "keywords", inner: "Hecksagon", opens: "Hecksagon", fills: ""
|
|
84
84
|
member word: "subscribe", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "subscriptions"
|
|
85
85
|
member word: "attaches", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "attachments"
|
|
86
|
-
# Deprecated spellings of `attaches`; they warn and are removed in 3.4.0.
|
|
87
|
-
member word: "uses_framework", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "attachments", status: "deprecated"
|
|
88
|
-
member word: "uses_embryonaut_bluebook", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "attachments", status: "deprecated"
|
|
89
86
|
member word: "port", context: "Hecksagon", body: "keywords", inner: "DomainPort", opens: "DomainPort", fills: "", calls: "port_impl"
|
|
90
87
|
# A cross-domain reaction wired here rather than in the bluebook; reuses the Policy context.
|
|
91
88
|
# No `calls:` — HecksagonBuilder#translates is an ordinary method, found before `word_gate`.
|
|
@@ -116,8 +113,6 @@ Hecks.bluebook "Hecksagon" do
|
|
|
116
113
|
member keyword: "subscribe", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "subscriptions"
|
|
117
114
|
member keyword: "attaches", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "attachments"
|
|
118
115
|
member keyword: "attaches", context: "Hecksagon", at: "", named: "from", kind: "symbol", required: "false", fills: "source"
|
|
119
|
-
member keyword: "uses_framework", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "attachments"
|
|
120
|
-
member keyword: "uses_embryonaut_bluebook", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "attachments"
|
|
121
116
|
member keyword: "port", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
122
117
|
member keyword: "translates", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "name"
|
|
123
118
|
|
data/lib/hecks/runtime/loader.rb
CHANGED
|
@@ -27,9 +27,9 @@ module Hecks
|
|
|
27
27
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted dispatcher
|
|
28
28
|
# @raise [Errno::ENOENT] if `path` names no domain directory
|
|
29
29
|
# @raise [Runtime::WiringError] if a boot gate finds a wiring problem
|
|
30
|
-
def self.boot(path, shared: nil, install_doors: true,
|
|
30
|
+
def self.boot(path, shared: nil, install_doors: true, environment: FROM_ENV)
|
|
31
31
|
described = describe(path, shared: shared, environment: environment)
|
|
32
|
-
boot_described(described, install_doors: install_doors
|
|
32
|
+
boot_described(described, install_doors: install_doors)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
# Finishes a boot from declarations `describe` already loaded: runs every boot gate and binds
|
|
@@ -37,16 +37,15 @@ module Hecks
|
|
|
37
37
|
#
|
|
38
38
|
# @param described [Described] what `describe` answered for the domain to boot
|
|
39
39
|
# @param install_doors [Boolean] install the `Widget::Item.Add(...)` global facade sugar
|
|
40
|
-
# @param install_facade [Boolean, nil] the deprecated spelling of `install_doors`
|
|
41
40
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted dispatcher
|
|
42
41
|
# @raise [Runtime::WiringError] if a boot gate finds a wiring problem
|
|
43
|
-
def self.boot_described(described, install_doors: true
|
|
42
|
+
def self.boot_described(described, install_doors: true)
|
|
44
43
|
registry = described.registry
|
|
45
44
|
run_boot_gates!(registry, described.directory)
|
|
46
45
|
dispatcher = dispatcher_for(registry)
|
|
47
46
|
redrive_outbox!(dispatcher)
|
|
48
47
|
seed_privacy_markings!(dispatcher, registry)
|
|
49
|
-
|
|
48
|
+
install_doors ? bind_runtime(dispatcher) : dispatcher
|
|
50
49
|
end
|
|
51
50
|
|
|
52
51
|
# What `describe` answers: the loaded declarations and nothing bound to run them.
|
|
@@ -153,7 +152,7 @@ module Hecks
|
|
|
153
152
|
# defaults to `HECKS_ENVIRONMENT`, and an explicit nil loads none
|
|
154
153
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted dispatcher
|
|
155
154
|
# @raise [Runtime::WiringError] if a boot gate finds a wiring problem
|
|
156
|
-
def self.boot_files(paths, shared: nil, install_doors: true,
|
|
155
|
+
def self.boot_files(paths, shared: nil, install_doors: true, environment: FROM_ENV)
|
|
157
156
|
loading = Ports::Loading.bootstrap
|
|
158
157
|
files = Array(paths).map { |path| File.expand_path(path) }
|
|
159
158
|
directory = File.dirname(files.first)
|
|
@@ -168,7 +167,7 @@ module Hecks
|
|
|
168
167
|
|
|
169
168
|
run_boot_gates!(registry, directory)
|
|
170
169
|
dispatcher = dispatcher_for(registry)
|
|
171
|
-
|
|
170
|
+
install_doors ? bind_runtime(dispatcher) : dispatcher
|
|
172
171
|
end
|
|
173
172
|
|
|
174
173
|
# Runs every registered boot gate against `registry`, in order:
|
data/lib/hecks/runtime.rb
CHANGED
|
@@ -43,13 +43,11 @@ module Hecks
|
|
|
43
43
|
# @param path [String] path to a domain directory, or a file inside one
|
|
44
44
|
# @param shared [String, nil] a shared-root override
|
|
45
45
|
# @param install_doors [Boolean] whether to install the Ruby facade constants
|
|
46
|
-
# @param install_facade [Boolean, nil] the deprecated spelling of `install_doors`; warns
|
|
47
46
|
# @param environment [String, nil] the environment name for `Adapters::Folder#load_domain`
|
|
48
47
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] the dispatcher bound
|
|
49
48
|
# to the booted domain
|
|
50
|
-
def boot(path, shared: nil, install_doors: true,
|
|
51
|
-
Loader.boot(path, shared: shared, install_doors: install_doors, environment: environment
|
|
52
|
-
install_facade: install_facade)
|
|
49
|
+
def boot(path, shared: nil, install_doors: true, environment: Runtime::Loader::FROM_ENV)
|
|
50
|
+
Loader.boot(path, shared: shared, install_doors: install_doors, environment: environment)
|
|
53
51
|
end
|
|
54
52
|
|
|
55
53
|
# Loads a domain's declarations without binding any adapter. See Loader.describe.
|
|
@@ -66,11 +64,10 @@ module Hecks
|
|
|
66
64
|
#
|
|
67
65
|
# @param described [Runtime::Loader::Described] what `describe` answered
|
|
68
66
|
# @param install_doors [Boolean] whether to install the Ruby facade constants
|
|
69
|
-
# @param install_facade [Boolean, nil] the deprecated spelling of `install_doors`; warns
|
|
70
67
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] the dispatcher bound
|
|
71
68
|
# to the booted domain
|
|
72
|
-
def boot_described(described, install_doors: true
|
|
73
|
-
Loader.boot_described(described, install_doors: install_doors
|
|
69
|
+
def boot_described(described, install_doors: true)
|
|
70
|
+
Loader.boot_described(described, install_doors: install_doors)
|
|
74
71
|
end
|
|
75
72
|
|
|
76
73
|
# Loads only the given files of a domain; otherwise like `boot`. See Loader.boot_files.
|
|
@@ -78,13 +75,11 @@ module Hecks
|
|
|
78
75
|
# @param paths [String, Array<String>] one or more file paths within the domain
|
|
79
76
|
# @param shared [String, nil] a shared-root override
|
|
80
77
|
# @param install_doors [Boolean] whether to install the Ruby facade constants
|
|
81
|
-
# @param install_facade [Boolean, nil] the deprecated spelling of `install_doors`; warns
|
|
82
78
|
# @param environment [String, nil] the environment name for the selected-file loader
|
|
83
79
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] the dispatcher bound
|
|
84
80
|
# to the booted domain
|
|
85
|
-
def boot_files(paths, shared: nil, install_doors: true,
|
|
86
|
-
Loader.boot_files(paths, shared: shared, install_doors: install_doors, environment: environment
|
|
87
|
-
install_facade: install_facade)
|
|
81
|
+
def boot_files(paths, shared: nil, install_doors: true, environment: Runtime::Loader::FROM_ENV)
|
|
82
|
+
Loader.boot_files(paths, shared: shared, install_doors: install_doors, environment: environment)
|
|
88
83
|
end
|
|
89
84
|
|
|
90
85
|
# Bind the ambient registry for the duration of the block, restoring
|
data/lib/hecks/version.rb
CHANGED
data/lib/hecks.rb
CHANGED
|
@@ -13,7 +13,6 @@ require_relative "hecks/construct"
|
|
|
13
13
|
require_relative "hecks/ir"
|
|
14
14
|
require_relative "hecks/literal"
|
|
15
15
|
require_relative "hecks/doors"
|
|
16
|
-
require_relative "hecks/facade"
|
|
17
16
|
require_relative "hecks/query_specification"
|
|
18
17
|
|
|
19
18
|
require_relative "hecks/ports"
|
|
@@ -58,13 +57,11 @@ module Hecks
|
|
|
58
57
|
# @param path [String] path to a domain directory, or a file inside one
|
|
59
58
|
# @param shared [String, nil] a shared-root override; see `Runtime::Loader.boot`
|
|
60
59
|
# @param install_doors [Boolean] install the `Widget::Item.Add`-style facade
|
|
61
|
-
# @param install_facade [Boolean, nil] the deprecated spelling of `install_doors`; warns
|
|
62
60
|
# @param environment [String, nil] env name; its `.hecksagon`/`.world` overlay,
|
|
63
61
|
# if present, loads after the domain's own. Defaults to `HECKS_ENVIRONMENT`; nil loads none
|
|
64
62
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] dispatcher bound to the domain
|
|
65
|
-
def boot(path, shared: nil, install_doors: true,
|
|
66
|
-
Runtime.boot(path, shared: shared, install_doors: install_doors, environment: environment
|
|
67
|
-
install_facade: install_facade)
|
|
63
|
+
def boot(path, shared: nil, install_doors: true, environment: Runtime::Loader::FROM_ENV)
|
|
64
|
+
Runtime.boot(path, shared: shared, install_doors: install_doors, environment: environment)
|
|
68
65
|
end
|
|
69
66
|
|
|
70
67
|
# Loads a domain's declarations without binding any adapter or opening any store.
|
|
@@ -82,10 +79,9 @@ module Hecks
|
|
|
82
79
|
#
|
|
83
80
|
# @param described [Runtime::Loader::Described] what `describe` answered
|
|
84
81
|
# @param install_doors [Boolean] install the `Widget::Item.Add`-style facade
|
|
85
|
-
# @param install_facade [Boolean, nil] the deprecated spelling of `install_doors`; warns
|
|
86
82
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] dispatcher bound to the domain
|
|
87
|
-
def boot_described(described, install_doors: true
|
|
88
|
-
Runtime.boot_described(described, install_doors: install_doors
|
|
83
|
+
def boot_described(described, install_doors: true)
|
|
84
|
+
Runtime.boot_described(described, install_doors: install_doors)
|
|
89
85
|
end
|
|
90
86
|
|
|
91
87
|
# Boots a domain from an explicit list of files (a `.bluebook`, its
|
|
@@ -94,12 +90,10 @@ module Hecks
|
|
|
94
90
|
# @param paths [String, Array<String>] one or more file paths within the domain
|
|
95
91
|
# @param shared [String, nil] a shared-root override; see `Runtime::Loader.boot_files`
|
|
96
92
|
# @param install_doors [Boolean] install the `Widget::Item.Add`-style facade
|
|
97
|
-
# @param install_facade [Boolean, nil] the deprecated spelling of `install_doors`; warns
|
|
98
93
|
# @param environment [String, nil] environment name passed to the selected-file loader
|
|
99
94
|
# @return [Runtime::Dispatcher, Runtime::RemoteDispatcher] dispatcher bound to the domain
|
|
100
|
-
def boot_files(paths, shared: nil, install_doors: true,
|
|
101
|
-
Runtime.boot_files(paths, shared: shared, install_doors: install_doors, environment: environment
|
|
102
|
-
install_facade: install_facade)
|
|
95
|
+
def boot_files(paths, shared: nil, install_doors: true, environment: Runtime::Loader::FROM_ENV)
|
|
96
|
+
Runtime.boot_files(paths, shared: shared, install_doors: install_doors, environment: environment)
|
|
103
97
|
end
|
|
104
98
|
|
|
105
99
|
# Binds the ambient registry for the duration of the block.
|
data/rust/host/HECKS_RELEASE
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.4.0
|
data/rust/parser/src/keywords.rs
CHANGED
|
@@ -184,8 +184,6 @@ pub static KEYWORDS: &[KeywordRow] = &[
|
|
|
184
184
|
KeywordRow { word: "hecksagon", context: "File", body: "keywords", inner: "Hecksagon", opens: "Hecksagon", fills: "", status: "admitted", was: "", resolves_via: "", disambiguator: "" },
|
|
185
185
|
KeywordRow { word: "subscribe", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "subscriptions", status: "admitted", was: "", resolves_via: "", disambiguator: "" },
|
|
186
186
|
KeywordRow { word: "attaches", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "attachments", status: "admitted", was: "", resolves_via: "", disambiguator: "" },
|
|
187
|
-
KeywordRow { word: "uses_framework", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "attachments", status: "deprecated", was: "", resolves_via: "", disambiguator: "" },
|
|
188
|
-
KeywordRow { word: "uses_embryonaut_bluebook", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "attachments", status: "deprecated", was: "", resolves_via: "", disambiguator: "" },
|
|
189
187
|
KeywordRow { word: "port", context: "Hecksagon", body: "keywords", inner: "DomainPort", opens: "DomainPort", fills: "", status: "admitted", was: "", resolves_via: "", disambiguator: "" },
|
|
190
188
|
KeywordRow { word: "translates", context: "Hecksagon", body: "keywords", inner: "Policy", opens: "Policy", fills: "", status: "admitted", was: "", resolves_via: "", disambiguator: "" },
|
|
191
189
|
KeywordRow { word: "bounded", context: "Hecksagon", body: "none", inner: "", opens: "", fills: "", status: "admitted", was: "", resolves_via: "", disambiguator: "" },
|
|
@@ -470,8 +468,6 @@ pub static ARGUMENTS: &[ArgumentRow] = &[
|
|
|
470
468
|
ArgumentRow { keyword: "subscribe", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "subscriptions", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
|
471
469
|
ArgumentRow { keyword: "attaches", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "attachments", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
|
472
470
|
ArgumentRow { keyword: "attaches", context: "Hecksagon", at: "", named: "from", kind: "symbol", required: "false", fills: "source", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
|
473
|
-
ArgumentRow { keyword: "uses_framework", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "attachments", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
|
474
|
-
ArgumentRow { keyword: "uses_embryonaut_bluebook", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "attachments", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
|
475
471
|
ArgumentRow { keyword: "port", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "name", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
|
476
472
|
ArgumentRow { keyword: "translates", context: "Hecksagon", at: "1", named: "", kind: "text", required: "true", fills: "name", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
|
477
473
|
ArgumentRow { keyword: "reference_to", context: "PortOperation", at: "1", named: "", kind: "constant", required: "true", fills: "type", selects: "", pair_key_fills: "", pair_value_fills: "", pairs_shape: "", status: "admitted", variadic: "", minimum: "" },
|
data/rust/parser/src/lex.rs
CHANGED
|
@@ -567,7 +567,7 @@ mod tests {
|
|
|
567
567
|
#[test]
|
|
568
568
|
fn does_not_strip_a_bare_lowercase_call() {
|
|
569
569
|
assert_eq!(
|
|
570
|
-
strip_aggregate_receiver("
|
|
570
|
+
strip_aggregate_receiver("attaches \"Governance\""),
|
|
571
571
|
None
|
|
572
572
|
);
|
|
573
573
|
assert_eq!(strip_aggregate_receiver("subscribe \"Deposited\""), None);
|
|
@@ -14,9 +14,8 @@ pub fn not_implemented(file: &str, line: usize, word: &str) -> Diagnostic {
|
|
|
14
14
|
/// Applies a `.hecksagon` body onto an already-built `ir::Bluebook`, attaching
|
|
15
15
|
/// aggregate-scoped ports to the aggregates the sibling `.bluebook` registered.
|
|
16
16
|
///
|
|
17
|
-
/// `gem_chapter_names` collects each `attaches "Name"`
|
|
18
|
-
/// `vendored_bluebook_names` each `attaches "name", from: :vendor`
|
|
19
|
-
/// `uses_embryonaut_bluebook`), in file order, for `hecks-parse resolve`; `ir.json` itself
|
|
17
|
+
/// `gem_chapter_names` collects each `attaches "Name"` and
|
|
18
|
+
/// `vendored_bluebook_names` each `attaches "name", from: :vendor`, in file order, for `hecks-parse resolve`; `ir.json` itself
|
|
20
19
|
/// carries neither.
|
|
21
20
|
///
|
|
22
21
|
/// `require_matching_aggregate` is `false` for resolve, which never sees a `.bluebook`, so an
|
|
@@ -65,8 +64,20 @@ pub fn apply(
|
|
|
65
64
|
if let LineShape::Call(call) = lex::classify(file, &line)? {
|
|
66
65
|
if !matches!(
|
|
67
66
|
call.word.as_str(),
|
|
68
|
-
"port" | "subscribe" | "
|
|
67
|
+
"port" | "subscribe" | "attaches" | "translates" | "bounded" | "end"
|
|
69
68
|
) {
|
|
69
|
+
let instead = match call.word.as_str() {
|
|
70
|
+
"uses_framework" => Some("attaches \"Name\""),
|
|
71
|
+
"uses_embryonaut_bluebook" => Some("attaches \"name\", from: :vendor"),
|
|
72
|
+
_ => None,
|
|
73
|
+
};
|
|
74
|
+
if let Some(instead) = instead {
|
|
75
|
+
return Err(Diagnostic::new(
|
|
76
|
+
file,
|
|
77
|
+
line.number,
|
|
78
|
+
format!("`{}` was removed in 3.4.0; use `{instead}`", call.word),
|
|
79
|
+
));
|
|
80
|
+
}
|
|
70
81
|
*pos += 1;
|
|
71
82
|
if matches!(call.opener, Opener::DoBlock { .. }) {
|
|
72
83
|
skip_dropped_body(file, lines, pos)?;
|
|
@@ -98,26 +109,6 @@ pub fn apply(
|
|
|
98
109
|
let built = policy::parse_body(file, lines, pos, &name)?;
|
|
99
110
|
bluebook.policies.push(built);
|
|
100
111
|
}
|
|
101
|
-
// Deprecated spelling of `attaches "Name"`; gated, then collected.
|
|
102
|
-
"uses_framework" => {
|
|
103
|
-
gem_chapter_names.push(super::positional_text(
|
|
104
|
-
file,
|
|
105
|
-
gated.line.number,
|
|
106
|
-
"uses_framework",
|
|
107
|
-
&gated.args,
|
|
108
|
-
1,
|
|
109
|
-
)?);
|
|
110
|
-
}
|
|
111
|
-
// Deprecated spelling of `attaches "name", from: :vendor`; collected the same way.
|
|
112
|
-
"uses_embryonaut_bluebook" => {
|
|
113
|
-
vendored_bluebook_names.push(super::positional_text(
|
|
114
|
-
file,
|
|
115
|
-
gated.line.number,
|
|
116
|
-
"uses_embryonaut_bluebook",
|
|
117
|
-
&gated.args,
|
|
118
|
-
1,
|
|
119
|
-
)?);
|
|
120
|
-
}
|
|
121
112
|
"subscribe" => {}
|
|
122
113
|
// One word for a chapter the gem carries and for a vendored package; a binding
|
|
123
114
|
// fact collected for `resolve`, absent from `ir.json`. Only `from: :vendor`
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hecks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Young
|
|
@@ -288,7 +288,6 @@ files:
|
|
|
288
288
|
- lib/hecks/embryonaut_bluebook/vendor.rb
|
|
289
289
|
- lib/hecks/embryonaut_bluebook/vendor_cli.rb
|
|
290
290
|
- lib/hecks/engine_agreement.rb
|
|
291
|
-
- lib/hecks/facade.rb
|
|
292
291
|
- lib/hecks/forms.rb
|
|
293
292
|
- lib/hecks/forms/app.rb
|
|
294
293
|
- lib/hecks/forms/banking_presentation.rb
|
data/lib/hecks/facade.rb
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# The deprecated alias shim: `Hecks::Facade` is now `Hecks::Doors` and `Doors::Surface` is
|
|
2
|
-
# `Doors::RubyDoor`. Both old constants still resolve and warn; they are removed in
|
|
3
|
-
# `Hecks::Doors::REMOVAL`.
|
|
4
|
-
require_relative "doors"
|
|
5
|
-
|
|
6
|
-
# The root namespace; this file holds only the deprecated aliases.
|
|
7
|
-
module Hecks
|
|
8
|
-
# Resolves the constants that now live in `Doors` under their old names, warning on each use.
|
|
9
|
-
#
|
|
10
|
-
# Extended onto `Hecks` and `Hecks::Doors`, ahead of `Module#const_missing`.
|
|
11
|
-
module DoorsAliases
|
|
12
|
-
# Old constant name mapped to the new one, per namespace that carried it.
|
|
13
|
-
RENAMED = { Hecks => { Facade: "Hecks::Doors" }, Hecks::Doors => { Surface: "Hecks::Doors::RubyDoor" } }.freeze
|
|
14
|
-
|
|
15
|
-
# Answers a renamed constant with its replacement and a warning; anything else
|
|
16
|
-
# goes to the next `const_missing`.
|
|
17
|
-
#
|
|
18
|
-
# @param name [Symbol] the missing constant
|
|
19
|
-
# @return [Module] the replacement module
|
|
20
|
-
def const_missing(name)
|
|
21
|
-
target = RENAMED.fetch(self, {})[name]
|
|
22
|
-
return super unless target
|
|
23
|
-
|
|
24
|
-
warn "[hecks] #{self}::#{name} is deprecated and is removed in #{Hecks::Doors::REMOVAL}; use #{target}"
|
|
25
|
-
Object.const_get(target)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
extend DoorsAliases
|
|
30
|
-
Doors.extend(DoorsAliases)
|
|
31
|
-
end
|