foobara 0.0.59 → 0.0.61
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 -1
- data/projects/command/src/command_pattern_implementation/concerns/domain_mappers.rb +46 -24
- data/projects/command/src/command_pattern_implementation/concerns/subcommands.rb +4 -0
- data/projects/domain/src/domain_module_extension.rb +14 -10
- data/projects/domain_mapper/src/domain_mapper.rb +23 -5
- data/projects/domain_mapper/src/domain_mapper_lookups.rb +19 -1
- data/projects/manifest/src/foobara/manifest/type.rb +5 -0
- data/projects/manifest/src/foobara/manifest/type_declaration.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a3b99978753271dc5d62b11b9132b0301d3285075c1cf61b0672713e7beb0ae
|
4
|
+
data.tar.gz: c127430a4d7408018e8475d1ebe5311114f8709a04ba448665214605895eb45b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 962b7fa09bafe6bccf89c7d963069eb6207f91c0d7656ba988b87f0cd271e148a8d03d0e86e092c2f536977ef5634a54ca90ca46e334e98448d09be8e1e5fd0d
|
7
|
+
data.tar.gz: 02d17842a63a15dee83b364bde44b3844d59ec796005c04648e65199aa699e5642dada7aa1ca4121df3409a6c778eb4c40e41ecbb1bf39423e6fc78a1f80b515
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
## [0.0.
|
1
|
+
## [0.0.61] - 2025-02-22
|
2
|
+
|
3
|
+
- Add Manifest::Type#custom?
|
4
|
+
|
5
|
+
## [0.0.60] - 2025-02-22
|
6
|
+
|
7
|
+
- Now including domain mappers in the .depends_on call is optional. If you include any of them, you must include all
|
8
|
+
of them. Otherwise, you can include none of them and then no verification of them will be performed.
|
9
|
+
- Introduce a ranking/scoring system of domain mapper matches to help with certain ambiguous situations
|
10
|
+
|
11
|
+
## [0.0.59] - 2025-02-20
|
2
12
|
|
3
13
|
- DomainMapper no longer inherits from Command. Instead, both include CommandPatternImplementation mixin
|
4
14
|
|
@@ -45,13 +45,33 @@ module Foobara
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
module ClassMethods
|
49
|
+
def domain_map_criteria
|
50
|
+
return @domain_map_criteria if @domain_map_criteria
|
51
|
+
|
52
|
+
has_explicit_mapper_deps = depends_on.any? do |c|
|
53
|
+
foobara_lookup_domain_mapper(c)
|
54
|
+
end
|
55
|
+
|
56
|
+
@domain_map_criteria = if has_explicit_mapper_deps
|
57
|
+
->(mapper) { depends_on?(mapper) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
48
62
|
include Concern
|
49
63
|
|
50
64
|
def run_mapped_subcommand!(subcommand_class, unmapped_inputs = {}, to = nil)
|
65
|
+
unless subcommand_class
|
66
|
+
# :nocov:
|
67
|
+
raise ArgumentError, "subcommand_class is required"
|
68
|
+
# :nocov:
|
69
|
+
end
|
70
|
+
|
51
71
|
mapped_something = false
|
52
72
|
no_mapper_found = nil
|
53
73
|
|
54
|
-
criteria =
|
74
|
+
criteria = self.class.domain_map_criteria
|
55
75
|
|
56
76
|
inputs_mapper = self.class.domain.lookup_matching_domain_mapper(
|
57
77
|
from: unmapped_inputs,
|
@@ -88,7 +108,7 @@ module Foobara
|
|
88
108
|
result_mapper = self.class.domain.lookup_matching_domain_mapper(
|
89
109
|
from: result,
|
90
110
|
to:,
|
91
|
-
criteria
|
111
|
+
criteria:,
|
92
112
|
strict: true
|
93
113
|
)
|
94
114
|
end
|
@@ -99,24 +119,26 @@ module Foobara
|
|
99
119
|
end
|
100
120
|
|
101
121
|
unless mapped_something
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
122
|
+
if criteria
|
123
|
+
mapper = self.class.domain.lookup_matching_domain_mapper(
|
124
|
+
from: unmapped_inputs,
|
125
|
+
to: subcommand_class,
|
126
|
+
strict: true
|
127
|
+
)
|
128
|
+
|
129
|
+
if mapper
|
130
|
+
raise ForgotToDependOnDomainMapperError, mapper
|
131
|
+
end
|
132
|
+
|
133
|
+
mapper = self.class.domain.lookup_matching_domain_mapper(
|
134
|
+
from: subcommand_class.result_type,
|
135
|
+
to:,
|
136
|
+
strict: true
|
137
|
+
)
|
138
|
+
|
139
|
+
if mapper
|
140
|
+
raise ForgotToDependOnDomainMapperError, mapper
|
141
|
+
end
|
120
142
|
end
|
121
143
|
|
122
144
|
raise NoDomainMapperFoundError.new(subcommand_class, to)
|
@@ -125,12 +147,12 @@ module Foobara
|
|
125
147
|
result
|
126
148
|
end
|
127
149
|
|
128
|
-
def domain_map(
|
129
|
-
self.class.domain.foobara_domain_map(
|
150
|
+
def domain_map(*, **, &)
|
151
|
+
self.class.domain.foobara_domain_map(*, criteria: self.class.domain_map_criteria, strict: true, **, &)
|
130
152
|
end
|
131
153
|
|
132
|
-
def domain_map!(
|
133
|
-
self.class.domain.foobara_domain_map!(
|
154
|
+
def domain_map!(*, **, &)
|
155
|
+
self.class.domain.foobara_domain_map!(*, criteria: self.class.domain_map_criteria, strict: true, **, &)
|
134
156
|
end
|
135
157
|
end
|
136
158
|
end
|
@@ -79,6 +79,10 @@ module Foobara
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def verify_depends_on!(subcommand_class)
|
82
|
+
unless domain_map_criteria
|
83
|
+
return if subcommand_class < DomainMapper
|
84
|
+
end
|
85
|
+
|
82
86
|
unless depends_on?(subcommand_class)
|
83
87
|
# :nocov:
|
84
88
|
raise SubcommandNotRegistered, "Need to declare #{subcommand_class} on #{self} with .depends_on"
|
@@ -133,7 +133,7 @@ module Foobara
|
|
133
133
|
super
|
134
134
|
end
|
135
135
|
|
136
|
-
def foobara_domain_map(value, to: nil, strict: false, **opts)
|
136
|
+
def foobara_domain_map(value, to: nil, strict: false, criteria: nil, should_raise: false, **opts)
|
137
137
|
invalid_keys = opts.keys - [:from]
|
138
138
|
|
139
139
|
if invalid_keys.any?
|
@@ -144,23 +144,27 @@ module Foobara
|
|
144
144
|
|
145
145
|
from = if opts.key?(:from)
|
146
146
|
opts[:from]
|
147
|
-
|
147
|
+
else
|
148
|
+
try_nil = true
|
148
149
|
value
|
149
150
|
end
|
150
151
|
|
151
|
-
mapper = lookup_matching_domain_mapper(from:, to:, strict:)
|
152
|
-
|
153
|
-
mapper&.map!(value)
|
154
|
-
end
|
152
|
+
mapper = lookup_matching_domain_mapper(from:, to:, criteria:, strict:)
|
155
153
|
|
156
|
-
|
157
|
-
|
154
|
+
if try_nil
|
155
|
+
from = nil
|
156
|
+
mapper = lookup_matching_domain_mapper(from:, to:, criteria:, strict:)
|
157
|
+
end
|
158
158
|
|
159
|
-
|
159
|
+
if mapper
|
160
|
+
mapper.map!(value)
|
161
|
+
elsif should_raise
|
160
162
|
raise Foobara::DomainMapperLookups::NoDomainMapperFoundError.new(from, to, value:)
|
161
163
|
end
|
164
|
+
end
|
162
165
|
|
163
|
-
|
166
|
+
def foobara_domain_map!(value, from: nil, to: nil, criteria: nil, strict: false)
|
167
|
+
foobara_domain_map(value, from:, to:, criteria:, strict:, should_raise: true)
|
164
168
|
end
|
165
169
|
|
166
170
|
def foobara_domain_name
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Foobara
|
2
|
+
# NOTE: If you depend_on a domain mapper in a command, then you need to depend on all domain mappers
|
3
|
+
# that that command uses. Or you can just exclude all of them in which case Foobara won't enforce
|
4
|
+
# explicit depends_on of domain mappers.
|
2
5
|
class DomainMapper
|
3
6
|
include CommandPatternImplementation
|
4
7
|
|
@@ -38,22 +41,37 @@ module Foobara
|
|
38
41
|
end
|
39
42
|
|
40
43
|
def matches?(type_indicator, value)
|
41
|
-
|
44
|
+
match_score(type_indicator, value)&.>(0)
|
45
|
+
end
|
46
|
+
|
47
|
+
def applicable_score(from_value, to_value)
|
48
|
+
[*match_score(from_type, from_value), *match_score(to_type, to_value)].sum
|
49
|
+
end
|
50
|
+
|
51
|
+
def match_score(type_indicator, value)
|
52
|
+
return 1 if type_indicator.nil? || value.nil?
|
53
|
+
return 20 if type_indicator == value
|
42
54
|
|
43
55
|
type = object_to_type(type_indicator)
|
44
56
|
|
45
|
-
return
|
46
|
-
return
|
57
|
+
return 1 if type.nil?
|
58
|
+
return 9 if type == value
|
59
|
+
|
60
|
+
return 5 if type.applicable?(value) && type.process_value(value).success?
|
47
61
|
|
48
62
|
if value.is_a?(Types::Type)
|
49
63
|
if !value.registered? && !type.registered?
|
50
|
-
value.declaration_data == type.declaration_data
|
64
|
+
if value.declaration_data == type.declaration_data
|
65
|
+
8
|
66
|
+
end
|
51
67
|
end
|
52
68
|
else
|
53
69
|
value_type = object_to_type(value)
|
54
70
|
|
55
71
|
if value_type
|
56
|
-
matches?(type, value_type)
|
72
|
+
if matches?(type, value_type)
|
73
|
+
6
|
74
|
+
end
|
57
75
|
end
|
58
76
|
end
|
59
77
|
end
|
@@ -56,7 +56,25 @@ module Foobara
|
|
56
56
|
end
|
57
57
|
|
58
58
|
if candidates.size > 1
|
59
|
-
|
59
|
+
best = []
|
60
|
+
best_score = 0
|
61
|
+
|
62
|
+
candidates.each do |mapper|
|
63
|
+
score = mapper.applicable_score(from, to)
|
64
|
+
|
65
|
+
if score > best_score
|
66
|
+
best = [mapper]
|
67
|
+
best_score = score
|
68
|
+
elsif score == best_score
|
69
|
+
best << mapper
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
if best.size > 1
|
74
|
+
raise AmbiguousDomainMapperError.new(from, to, candidates)
|
75
|
+
else
|
76
|
+
candidates = best
|
77
|
+
end
|
60
78
|
end
|
61
79
|
|
62
80
|
value = candidates.first
|
@@ -80,6 +80,12 @@ module Foobara
|
|
80
80
|
@model = to_type.model?
|
81
81
|
end
|
82
82
|
|
83
|
+
def custom?
|
84
|
+
return @custom if defined?(@custom)
|
85
|
+
|
86
|
+
@custom = to_type.custom?
|
87
|
+
end
|
88
|
+
|
83
89
|
def to_model
|
84
90
|
raise "not an model" unless model?
|
85
91
|
raise "model extension instead of an model" unless relevant_manifest.size == 1
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foobara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.61
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miles Georgi
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-02-
|
10
|
+
date: 2025-02-21 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bigdecimal
|