foobara 0.5.3 → 0.5.5
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/CHANGELOG.md +11 -0
- data/projects/command/src/command_pattern_implementation/concerns/reflection.rb +7 -6
- data/projects/command_connectors/spec/command_connector_spec.rb +17 -3
- data/projects/command_connectors/src/command_connector/concerns/desugarizers.rb +6 -6
- data/projects/command_connectors/src/command_connector/no_allowed_rule_given_error.rb +6 -0
- data/projects/command_connectors/src/command_connector.rb +27 -1
- data/projects/command_connectors/src/command_registry.rb +1 -1
- data/projects/command_connectors/src/transformed_command.rb +2 -2
- data/projects/entities/projects/weak_object_set/src/weak_object_set.rb +1 -1
- data/projects/typesystem/projects/types/src/type.rb +29 -1
- data/projects/typesystem/spec/builtin_types/attributes_spec.rb +22 -0
- data/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6527e62790180b1aeb2f98e069655d8ac72750fbff834fc63e9b75a01c35cb4e
|
|
4
|
+
data.tar.gz: a769dd2a642b71bd401dabe3c0917a1fa128069f2a7987ff79df633765ae93ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0359999dd32f56220e88e3e860ff7e415a4fd2b978bf83768868b1e10b0013c9e02597731890d1a2abb2fd11c1e288e1c1e8056b3bd6bf7a11bc9589af371ae3'
|
|
7
|
+
data.tar.gz: 33cf7a4428854d3016c1ccda045820e6da47a268e34f5bb05505bcc878ecdeff909caf1c411505d97849f4ffd69cc6e9c1c51a046ee92f6ee7ac2afe1919b359
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# [0.5.5] - 2026-02-19
|
|
2
|
+
|
|
3
|
+
- Fix bug where WeakObjectSet#delete could fail after deactivation
|
|
4
|
+
- Fix bug where arrays of allowed rules run in the wrong context
|
|
5
|
+
- Remove awkward proc defaults from manifest
|
|
6
|
+
|
|
7
|
+
# [0.5.4] - 2026-02-16
|
|
8
|
+
|
|
9
|
+
- Fix bug where adding a desugarizer to a subclass had no effect
|
|
10
|
+
- Add support for requiring allow_if: by default
|
|
11
|
+
|
|
1
12
|
# [0.5.3] - 2026-02-12
|
|
2
13
|
|
|
3
14
|
- Allow registering an allowed rule on an instance of a connector not just its class
|
|
@@ -60,16 +60,17 @@ module Foobara
|
|
|
60
60
|
possible_errors:,
|
|
61
61
|
depends_on:,
|
|
62
62
|
# TODO: allow inputs type to be nil or really any type?
|
|
63
|
-
inputs_type: inputs_type&.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
inputs_type: inputs_type&.reference_or_declaration_data_for_manifest ||
|
|
64
|
+
GlobalDomain.foobara_type_from_declaration(
|
|
65
|
+
type: "::attributes",
|
|
66
|
+
element_type_declarations: {},
|
|
67
|
+
required: []
|
|
68
|
+
).declaration_data
|
|
68
69
|
).merge(description:)
|
|
69
70
|
|
|
70
71
|
if result_type
|
|
71
72
|
# TODO: find a way to represent literal types like "nil"
|
|
72
|
-
h[:result_type] = result_type.
|
|
73
|
+
h[:result_type] = result_type.reference_or_declaration_data_for_manifest
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
super.merge(h)
|
|
@@ -488,6 +488,20 @@ RSpec.describe Foobara::CommandConnector do
|
|
|
488
488
|
expect(response.body).to eq("8")
|
|
489
489
|
end
|
|
490
490
|
|
|
491
|
+
context "when requires_allowed_rule" do
|
|
492
|
+
let(:command_connector) do
|
|
493
|
+
described_class.new(
|
|
494
|
+
authenticator:,
|
|
495
|
+
default_serializers:,
|
|
496
|
+
requires_allowed_rule: true
|
|
497
|
+
)
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
it "gives a relevant error" do
|
|
501
|
+
expect { response }.to raise_error(Foobara::CommandConnector::NoAllowedRuleGivenError)
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
|
|
491
505
|
context "with default transformers" do
|
|
492
506
|
before do
|
|
493
507
|
identity = proc { |x| x }
|
|
@@ -2074,14 +2088,14 @@ RSpec.describe Foobara::CommandConnector do
|
|
|
2074
2088
|
end
|
|
2075
2089
|
let(:command_connector) do
|
|
2076
2090
|
rule = allowed_rule_d
|
|
2077
|
-
command_connector_class_d.new do
|
|
2091
|
+
command_connector_class_d.new(requires_allowed_rule: true) do
|
|
2078
2092
|
register_allowed_rule :d, rule
|
|
2079
2093
|
end
|
|
2080
2094
|
end
|
|
2081
2095
|
|
|
2082
2096
|
it "puts the expected allowed rules on the command connector" do
|
|
2083
2097
|
command_connector.connect(command_class, suffix: "A", allow_if: :a)
|
|
2084
|
-
command_connector.connect(command_class, suffix: "B")
|
|
2098
|
+
command_connector.connect(command_class, suffix: "B", allow_if: :always)
|
|
2085
2099
|
command_connector.connect(command_class, suffix: "C", allowed_rule: :c)
|
|
2086
2100
|
command_connector.connect(command_class, suffix: "D", allowed_rule: :d)
|
|
2087
2101
|
|
|
@@ -2091,7 +2105,7 @@ RSpec.describe Foobara::CommandConnector do
|
|
|
2091
2105
|
|
|
2092
2106
|
response = command_connector.run(full_command_name: "ComputeExponentB", action:, inputs:)
|
|
2093
2107
|
expect(response.status).to be(0)
|
|
2094
|
-
expect(response.command.allowed_rule).to
|
|
2108
|
+
expect(response.command.allowed_rule).to be(described_class.always_allowed_rule)
|
|
2095
2109
|
|
|
2096
2110
|
response = command_connector.run(full_command_name: "ComputeExponentC", action:, inputs:)
|
|
2097
2111
|
expect(response.status).to be(1)
|
|
@@ -36,13 +36,13 @@ module Foobara
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def desugarizers
|
|
39
|
-
@desugarizers
|
|
39
|
+
return @desugarizers if defined?(@desugarizers)
|
|
40
40
|
|
|
41
|
-
if superclass == Object
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
@desugarizers = if superclass == Object
|
|
42
|
+
[]
|
|
43
|
+
else
|
|
44
|
+
superclass.desugarizers.dup
|
|
45
|
+
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -178,10 +178,19 @@ module Foobara
|
|
|
178
178
|
def build_auth_mapper(to_type, &)
|
|
179
179
|
TypeDeclarations::TypedTransformer.subclass(to: to_type, &).instance
|
|
180
180
|
end
|
|
181
|
+
|
|
182
|
+
def always_allowed_rule
|
|
183
|
+
# maybe move AllowedRule to CommandConnector:: instead of
|
|
184
|
+
# CommandRegistry:: which is more of an implementation detail?
|
|
185
|
+
@always_allowed_rule ||= CommandRegistry::AllowedRule.new(
|
|
186
|
+
symbol: :always,
|
|
187
|
+
explanation: "This always passes. Used to override allowed_rule_missing."
|
|
188
|
+
) { true }
|
|
189
|
+
end
|
|
181
190
|
end
|
|
182
191
|
|
|
183
192
|
attr_accessor :command_registry, :authenticator, :capture_unknown_error, :name,
|
|
184
|
-
:auth_map
|
|
193
|
+
:auth_map, :requires_allowed_rule
|
|
185
194
|
|
|
186
195
|
def initialize(name: nil,
|
|
187
196
|
authenticator: nil,
|
|
@@ -190,6 +199,7 @@ module Foobara
|
|
|
190
199
|
default_pre_commit_transformers: nil,
|
|
191
200
|
auth_map: nil,
|
|
192
201
|
current_user: nil,
|
|
202
|
+
requires_allowed_rule: false,
|
|
193
203
|
&block)
|
|
194
204
|
authenticator = self.class.to_authenticator(authenticator)
|
|
195
205
|
|
|
@@ -214,6 +224,11 @@ module Foobara
|
|
|
214
224
|
add_default_serializer(serializer)
|
|
215
225
|
end
|
|
216
226
|
|
|
227
|
+
if requires_allowed_rule
|
|
228
|
+
self.requires_allowed_rule = requires_allowed_rule
|
|
229
|
+
register_allowed_rule(CommandConnector.always_allowed_rule)
|
|
230
|
+
end
|
|
231
|
+
|
|
217
232
|
Util.array(default_pre_commit_transformers).each do |pre_commit_transformer|
|
|
218
233
|
add_default_pre_commit_transformer(pre_commit_transformer)
|
|
219
234
|
end
|
|
@@ -232,6 +247,7 @@ module Foobara
|
|
|
232
247
|
end
|
|
233
248
|
|
|
234
249
|
# TODO: should this be the official way to connect a command instead of #connect ?
|
|
250
|
+
# Probably not. But what about #export instead?
|
|
235
251
|
def command(...) = connect(...)
|
|
236
252
|
|
|
237
253
|
def connect(*args, **opts)
|
|
@@ -616,6 +632,16 @@ module Foobara
|
|
|
616
632
|
def run_command(request)
|
|
617
633
|
command = request.command
|
|
618
634
|
|
|
635
|
+
if requires_allowed_rule
|
|
636
|
+
unless command.allowed_rule
|
|
637
|
+
raise NoAllowedRuleGivenError,
|
|
638
|
+
"Must connect #{command.full_command_name} with an `allowed_if:` " \
|
|
639
|
+
"because `requires_allowed_rule` is true. You can use `allow_if: :always` if want to always allow " \
|
|
640
|
+
"this command to be ran or you can also use `requires_allowed_rule: false` " \
|
|
641
|
+
"when creating the connector if you don't want to enforce allowed_if: for all connected commands."
|
|
642
|
+
end
|
|
643
|
+
end
|
|
644
|
+
|
|
619
645
|
unless command.outcome
|
|
620
646
|
command.run
|
|
621
647
|
end
|
|
@@ -381,7 +381,7 @@ module Foobara
|
|
|
381
381
|
end
|
|
382
382
|
|
|
383
383
|
# TODO: This should support nil as an inputs_type but it breaks other projects for now
|
|
384
|
-
inputs_type = inputs_type_for_manifest&.
|
|
384
|
+
inputs_type = inputs_type_for_manifest&.reference_or_declaration_data_for_manifest ||
|
|
385
385
|
{ type: :attributes, element_type_declarations: {} }
|
|
386
386
|
|
|
387
387
|
# TODO: handle errors_types_depended_on!
|
|
@@ -390,7 +390,7 @@ module Foobara
|
|
|
390
390
|
result_types_depended_on:,
|
|
391
391
|
types_depended_on: types,
|
|
392
392
|
inputs_type:,
|
|
393
|
-
result_type: result_type&.
|
|
393
|
+
result_type: result_type&.reference_or_declaration_data_for_manifest,
|
|
394
394
|
possible_errors: possible_errors_manifest,
|
|
395
395
|
capture_unknown_error:,
|
|
396
396
|
inputs_transformers:,
|
|
@@ -420,6 +420,10 @@ module Foobara
|
|
|
420
420
|
scoped_full_name
|
|
421
421
|
end
|
|
422
422
|
|
|
423
|
+
def reference_or_declaration_data_for_manifest
|
|
424
|
+
reference_or_declaration_data(declaration_data_for_manifest)
|
|
425
|
+
end
|
|
426
|
+
|
|
423
427
|
def reference_or_declaration_data(declaration_data = self.declaration_data)
|
|
424
428
|
remove_sensitive = TypeDeclarations.foobara_manifest_context_remove_sensitive?
|
|
425
429
|
|
|
@@ -437,6 +441,30 @@ module Foobara
|
|
|
437
441
|
end
|
|
438
442
|
end
|
|
439
443
|
|
|
444
|
+
def declaration_data_for_manifest
|
|
445
|
+
data = declaration_data
|
|
446
|
+
|
|
447
|
+
if data.is_a?(::Hash) && data[:type] == :attributes
|
|
448
|
+
if data.key?(:defaults)
|
|
449
|
+
defaults = data[:defaults]
|
|
450
|
+
|
|
451
|
+
if defaults.is_a?(::Hash) && defaults.values.any? { it.is_a?(Proc) }
|
|
452
|
+
cleaned_defaults = defaults.transform_values do |value|
|
|
453
|
+
if value.is_a?(Proc)
|
|
454
|
+
"[<Lazily Set>]"
|
|
455
|
+
else
|
|
456
|
+
value
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
data = data.merge(defaults: cleaned_defaults)
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
data
|
|
466
|
+
end
|
|
467
|
+
|
|
440
468
|
# TODO: put this somewhere else
|
|
441
469
|
def foobara_manifest_reference
|
|
442
470
|
scoped_full_name
|
|
@@ -462,7 +490,7 @@ module Foobara
|
|
|
462
490
|
[possible_error.key.to_s, possible_error.foobara_manifest]
|
|
463
491
|
end.sort.to_h
|
|
464
492
|
|
|
465
|
-
declaration_data =
|
|
493
|
+
declaration_data = declaration_data_for_manifest
|
|
466
494
|
|
|
467
495
|
if remove_sensitive
|
|
468
496
|
declaration_data = TypeDeclarations.remove_sensitive_types(declaration_data)
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
RSpec.describe Foobara::BuiltinTypes::Attributes do
|
|
2
|
+
after { Foobara.reset_alls }
|
|
3
|
+
|
|
2
4
|
let(:type) {
|
|
3
5
|
Foobara::Domain.current.foobara_type_from_declaration(type_declaration)
|
|
4
6
|
}
|
|
@@ -61,6 +63,26 @@ RSpec.describe Foobara::BuiltinTypes::Attributes do
|
|
|
61
63
|
end
|
|
62
64
|
end
|
|
63
65
|
|
|
66
|
+
context "when default is a proc" do
|
|
67
|
+
let(:type_declaration) do
|
|
68
|
+
{
|
|
69
|
+
type: :attributes,
|
|
70
|
+
element_type_declarations: {
|
|
71
|
+
a: :integer,
|
|
72
|
+
b: :integer
|
|
73
|
+
},
|
|
74
|
+
defaults: { a: -> { 10 }, b: 100 }
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "applies defaults and scrubs the value in the manifest data" do
|
|
79
|
+
expect(type.process_value!({})).to eq(a: 10, b: 100)
|
|
80
|
+
|
|
81
|
+
Foobara::GlobalDomain.foobara_register_type(:some_type, type)
|
|
82
|
+
expect(type.foobara_manifest[:declaration_data][:defaults]).to eq(a: "[<Lazily Set>]", b: 100)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
64
86
|
context "when defaults contains invalid attribute names" do
|
|
65
87
|
let(:type_declaration) do
|
|
66
88
|
{
|
data/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foobara
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miles Georgi
|
|
@@ -138,6 +138,7 @@ files:
|
|
|
138
138
|
- projects/command_connectors/src/command_connector/concerns/desugarizers.rb
|
|
139
139
|
- projects/command_connectors/src/command_connector/concerns/reflection.rb
|
|
140
140
|
- projects/command_connectors/src/command_connector/invalid_context_error.rb
|
|
141
|
+
- projects/command_connectors/src/command_connector/no_allowed_rule_given_error.rb
|
|
141
142
|
- projects/command_connectors/src/command_connector/no_command_found_error.rb
|
|
142
143
|
- projects/command_connectors/src/command_connector/no_command_or_type_found_error.rb
|
|
143
144
|
- projects/command_connectors/src/command_connector/no_type_found_error.rb
|