dsl_compose 1.1.0 → 1.3.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/CHANGELOG.md +15 -0
- data/lib/dsl_compose/composer.rb +6 -6
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/equal_to_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/format_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/greater_than_or_equal_to_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/greater_than_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/in_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/interpreter.rb +2 -2
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/length_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/less_than_or_equal_to_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/less_than_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/not_in_validation.rb +1 -1
- data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument.rb +1 -1
- data/lib/dsl_compose/dsl/arguments.rb +113 -0
- data/lib/dsl_compose/dsl/dsl_method/interpreter.rb +4 -4
- data/lib/dsl_compose/dsl/dsl_method.rb +3 -73
- data/lib/dsl_compose/dsl/interpreter.rb +20 -0
- data/lib/dsl_compose/dsl.rb +4 -0
- data/lib/dsl_compose/interpreter/execution/arguments.rb +145 -0
- data/lib/dsl_compose/interpreter/execution/method_calls/method_call.rb +2 -104
- data/lib/dsl_compose/interpreter/execution.rb +5 -1
- data/lib/dsl_compose/interpreter.rb +36 -11
- data/lib/dsl_compose/version.rb +1 -1
- data/lib/dsl_compose.rb +15 -12
- metadata +15 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8b82032e4bea7187d0dd4a00528472ce1a5b29d4aea64b94d6090b8d013b47b
|
4
|
+
data.tar.gz: 628dda5efddcfdc2b9de8df09245c5af67c233de24dee7654d7266b193b6ef95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 670c5b83e8d8e3dd986933499d96d92604da968088b31dba613421712beb5ded7c7defec91714a1c23df1a4ba82d55a15a815864376d2ad3970a426232bb42cc
|
7
|
+
data.tar.gz: 48f76cf798a28b60efe4cf1c69d2f21c3594e86de5bbcf674d4a16f68114e76cde998a68c8dfbfbe8860362165bd9af7c37f6be3842e6efbdf9db8568ce72246
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [1.3.0](https://github.com/craigulliott/dsl_compose/compare/v1.2.0...v1.3.0) (2023-06-22)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* adding an executions_by_class method to make processing the configuration more convenient ([#8](https://github.com/craigulliott/dsl_compose/issues/8)) ([313507c](https://github.com/craigulliott/dsl_compose/commit/313507ca572f59c03162a91d58e62500a9464f25))
|
9
|
+
* fixing release please job ([#10](https://github.com/craigulliott/dsl_compose/issues/10)) ([880fa5b](https://github.com/craigulliott/dsl_compose/commit/880fa5b2aceed67aa9ff1e7cf53629af23e31b10))
|
10
|
+
|
11
|
+
## [1.2.0](https://github.com/craigulliott/dsl_compose/compare/v1.1.0...v1.2.0) (2023-06-22)
|
12
|
+
|
13
|
+
|
14
|
+
### Features
|
15
|
+
|
16
|
+
* adding arguments to initial DSL activation method ([bda7cd4](https://github.com/craigulliott/dsl_compose/commit/bda7cd4ef55bcd4bfd2be530b6a28645dee87885))
|
17
|
+
|
3
18
|
## [1.1.0](https://github.com/craigulliott/dsl_compose/compare/v1.0.0...v1.1.0) (2023-06-20)
|
4
19
|
|
5
20
|
|
data/lib/dsl_compose/composer.rb
CHANGED
@@ -10,13 +10,13 @@ module DSLCompose
|
|
10
10
|
|
11
11
|
class MethodAlreadyExistsWithThisDSLNameError < StandardError
|
12
12
|
def message
|
13
|
-
"The define_dsl singleton method already exists for this class."
|
13
|
+
"The `define_dsl` singleton method already exists for this class."
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
class GetDSLExecutionResultsMethodAlreadyExistsError < StandardError
|
18
18
|
def message
|
19
|
-
"The
|
19
|
+
"The `dsls` singleton method already exists for this class."
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -30,11 +30,11 @@ module DSLCompose
|
|
30
30
|
interpreter = DSLCompose::Interpreter.new
|
31
31
|
|
32
32
|
# return a specific DSL which is defined for this class
|
33
|
-
if klass.respond_to? :
|
33
|
+
if klass.respond_to? :dsls
|
34
34
|
raise GetDSLExecutionResultsMethodAlreadyExistsError
|
35
35
|
end
|
36
36
|
|
37
|
-
klass.define_singleton_method :
|
37
|
+
klass.define_singleton_method :dsls do
|
38
38
|
interpreter
|
39
39
|
end
|
40
40
|
|
@@ -56,10 +56,10 @@ module DSLCompose
|
|
56
56
|
end
|
57
57
|
|
58
58
|
# add a singleton method with the name of this new DSL onto our class, this is how our new DSL will be accessed
|
59
|
-
define_singleton_method name do
|
59
|
+
define_singleton_method name do |*args, &block|
|
60
60
|
# when it is called, we process this new dynamic DSL with the interpreter
|
61
61
|
# `self` here is the class in which the dsl is being used, not the class in which the DSL was defined
|
62
|
-
interpreter.execute_dsl self, dsl, &block
|
62
|
+
interpreter.execute_dsl self, dsl, *args, &block
|
63
63
|
end
|
64
64
|
|
65
65
|
end
|
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
module DSLCompose
|
4
4
|
class DSL
|
5
|
-
class
|
5
|
+
class Arguments
|
6
6
|
class Argument
|
7
7
|
# This class is reponsible for parsing and executing argument definitions
|
8
8
|
# within our internal DSL. These argument definitions determine what arguments
|
9
9
|
# will be available on the methods within our new dynamic DSL.
|
10
10
|
#
|
11
|
-
# This class is instantaited by the DSLCompose::DSL::
|
11
|
+
# This class is instantaited by the DSLCompose::DSL::Arguments::Argument class and the
|
12
12
|
# method argument definition part of our internal DSL is evaluated by passing a block
|
13
13
|
# to `instance_eval` on this class.
|
14
14
|
#
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSLCompose
|
4
|
+
class DSL
|
5
|
+
class Arguments
|
6
|
+
class ArgumentDoesNotExistError < StandardError
|
7
|
+
def message
|
8
|
+
"This argument does not exist for this DSLMethod"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ArgumentOrderingError < StandardError
|
13
|
+
def message
|
14
|
+
"Required arguments can not be added after optional ones"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ArgumentAlreadyExistsError < StandardError
|
19
|
+
def message
|
20
|
+
"An argument with this name already exists for this DSL method"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class RequestedOptionalArgumentIsRequiredError < StandardError
|
25
|
+
def message
|
26
|
+
"A specific argument which was expected to be optional was requested, but the argument found was flagged as required"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class RequestedRequiredArgumentIsOptionalError < StandardError
|
31
|
+
def message
|
32
|
+
"A specific argument which was expected to be required was requested, but the argument found was flagged as optional"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
@arguments = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns an array of all this DSLMethods Argument objects.
|
41
|
+
def arguments
|
42
|
+
@arguments.values
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns an array of only the optional Argument objects on this DSLMethod.
|
46
|
+
def optional_arguments
|
47
|
+
arguments.filter(&:optional?)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns an array of only the required Argument objects on this DSLMethod.
|
51
|
+
def required_arguments
|
52
|
+
arguments.filter(&:required?)
|
53
|
+
end
|
54
|
+
|
55
|
+
# returns a specific Argument by it's name, if the Argument does not
|
56
|
+
# exist, then an error is raised
|
57
|
+
def argument name
|
58
|
+
if has_argument? name
|
59
|
+
@arguments[name]
|
60
|
+
else
|
61
|
+
raise ArgumentDoesNotExistError
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# returns a specific optional Argument by it's name, if the Argument does not
|
66
|
+
# exist, or if it is required, then an error is raised
|
67
|
+
def optional_argument name
|
68
|
+
arg = argument name
|
69
|
+
if arg.optional?
|
70
|
+
@arguments[name]
|
71
|
+
else
|
72
|
+
raise RequestedOptionalArgumentIsRequiredError
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# returns a specific required Argument by it's name, if the Argument does not
|
77
|
+
# exist, or if it is optional, then an error is raised
|
78
|
+
def required_argument name
|
79
|
+
arg = argument name
|
80
|
+
if arg.required?
|
81
|
+
@arguments[name]
|
82
|
+
else
|
83
|
+
raise RequestedRequiredArgumentIsOptionalError
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns `true` if an Argument with the provided name exists in this
|
88
|
+
# DSLMethod, otherwise it returns `false`.
|
89
|
+
def has_argument? name
|
90
|
+
@arguments.key? name
|
91
|
+
end
|
92
|
+
|
93
|
+
# Takes a method name, unique flag, required flag, and a block and creates
|
94
|
+
# a new Argument object.
|
95
|
+
#
|
96
|
+
# Argument `name` must be unique within the DSLMethod.
|
97
|
+
# `required` must be a boolean, and determines if this argument will be required
|
98
|
+
# or optional on the method which is exposed in our DSL.
|
99
|
+
def add_argument name, required, type, &block
|
100
|
+
if @arguments.key? name
|
101
|
+
raise ArgumentAlreadyExistsError
|
102
|
+
end
|
103
|
+
|
104
|
+
# required arguments may not come after optional ones
|
105
|
+
if required && optional_arguments.any?
|
106
|
+
raise ArgumentOrderingError
|
107
|
+
end
|
108
|
+
|
109
|
+
@arguments[name] = Argument.new(name, required, type, &block)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -37,9 +37,9 @@ module DSLCompose
|
|
37
37
|
# name must be a symbol
|
38
38
|
# `type` can be either :integer, :boolean, :float, :string or :symbol
|
39
39
|
# `block` contains the argument definition and will be evaluated seperately
|
40
|
-
# by the
|
40
|
+
# by the Argument::Interpreter
|
41
41
|
def optional name, type, &block
|
42
|
-
@dsl_method.add_argument name, false, type, &block
|
42
|
+
@dsl_method.arguments.add_argument name, false, type, &block
|
43
43
|
end
|
44
44
|
|
45
45
|
# adds a new required argument to the DSLMethod
|
@@ -47,9 +47,9 @@ module DSLCompose
|
|
47
47
|
# name must be a symbol
|
48
48
|
# `type` can be either :integer, :boolean, :float, :string or :symbol
|
49
49
|
# `block` contains the argument definition and will be evaluated seperately
|
50
|
-
# by the
|
50
|
+
# by the Argument::Interpreter
|
51
51
|
def requires name, type, &block
|
52
|
-
@dsl_method.add_argument name, true, type, &block
|
52
|
+
@dsl_method.arguments.add_argument name, true, type, &block
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -66,6 +66,8 @@ module DSLCompose
|
|
66
66
|
# An otional description of this DSLMethod, if provided then it must be a string.
|
67
67
|
# The description accepts markdown and is used when generating documentation.
|
68
68
|
attr_reader :description
|
69
|
+
# an object which represents the argument configuration
|
70
|
+
attr_reader :arguments
|
69
71
|
|
70
72
|
# Create a new DSLMethod object with the provided name and class.
|
71
73
|
#
|
@@ -74,7 +76,7 @@ module DSLCompose
|
|
74
76
|
# `required` is a boolean which determines if this DSLMethod must be called at least once within the DSL.
|
75
77
|
# `block` contains the instructions to further configure this DSLMethod
|
76
78
|
def initialize name, unique, required, &block
|
77
|
-
@arguments =
|
79
|
+
@arguments = Arguments.new
|
78
80
|
|
79
81
|
if name.is_a? Symbol
|
80
82
|
|
@@ -122,59 +124,6 @@ module DSLCompose
|
|
122
124
|
@description.nil? == false
|
123
125
|
end
|
124
126
|
|
125
|
-
# Returns an array of all this DSLMethods Argument objects.
|
126
|
-
def arguments
|
127
|
-
@arguments.values
|
128
|
-
end
|
129
|
-
|
130
|
-
# Returns an array of only the optional Argument objects on this DSLMethod.
|
131
|
-
def optional_arguments
|
132
|
-
arguments.filter(&:optional?)
|
133
|
-
end
|
134
|
-
|
135
|
-
# Returns an array of only the required Argument objects on this DSLMethod.
|
136
|
-
def required_arguments
|
137
|
-
arguments.filter(&:required?)
|
138
|
-
end
|
139
|
-
|
140
|
-
# returns a specific Argument by it's name, if the Argument does not
|
141
|
-
# exist, then an error is raised
|
142
|
-
def argument name
|
143
|
-
if has_argument? name
|
144
|
-
@arguments[name]
|
145
|
-
else
|
146
|
-
raise ArgumentDoesNotExistError
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
# returns a specific optional Argument by it's name, if the Argument does not
|
151
|
-
# exist, or if it is required, then an error is raised
|
152
|
-
def optional_argument name
|
153
|
-
arg = argument name
|
154
|
-
if arg.optional?
|
155
|
-
@arguments[name]
|
156
|
-
else
|
157
|
-
raise RequestedOptionalArgumentIsRequiredError
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
# returns a specific required Argument by it's name, if the Argument does not
|
162
|
-
# exist, or if it is optional, then an error is raised
|
163
|
-
def required_argument name
|
164
|
-
arg = argument name
|
165
|
-
if arg.required?
|
166
|
-
@arguments[name]
|
167
|
-
else
|
168
|
-
raise RequestedRequiredArgumentIsOptionalError
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
# Returns `true` if an Argument with the provided name exists in this
|
173
|
-
# DSLMethod, otherwise it returns `false`.
|
174
|
-
def has_argument? name
|
175
|
-
@arguments.key? name
|
176
|
-
end
|
177
|
-
|
178
127
|
# returns true if this DSLMethod is flagged as unique, otherwise returns false.
|
179
128
|
def unique?
|
180
129
|
@unique == true
|
@@ -189,25 +138,6 @@ module DSLCompose
|
|
189
138
|
def optional?
|
190
139
|
@required == false
|
191
140
|
end
|
192
|
-
|
193
|
-
# Takes a method name, unique flag, required flag, and a block and creates
|
194
|
-
# a new Argument object.
|
195
|
-
#
|
196
|
-
# Argument `name` must be unique within the DSLMethod.
|
197
|
-
# `required` must be a boolean, and determines if this argument will be required
|
198
|
-
# or optional on the method which is exposed in our DSL.
|
199
|
-
def add_argument name, required, type, &block
|
200
|
-
if @arguments.key? name
|
201
|
-
raise ArgumentAlreadyExistsError
|
202
|
-
end
|
203
|
-
|
204
|
-
# required arguments may not come after optional ones
|
205
|
-
if required && optional_arguments.any?
|
206
|
-
raise ArgumentOrderingError
|
207
|
-
end
|
208
|
-
|
209
|
-
@arguments[name] = Argument.new(name, required, type, &block)
|
210
|
-
end
|
211
141
|
end
|
212
142
|
end
|
213
143
|
end
|
@@ -47,6 +47,26 @@ module DSLCompose
|
|
47
47
|
def add_unique_method name, required: nil, &block
|
48
48
|
@dsl.add_method name, true, required ? true : false, &block
|
49
49
|
end
|
50
|
+
|
51
|
+
# adds a new optional argument to the DSLMethod
|
52
|
+
#
|
53
|
+
# name must be a symbol
|
54
|
+
# `type` can be either :integer, :boolean, :float, :string or :symbol
|
55
|
+
# `block` contains the argument definition and will be evaluated seperately
|
56
|
+
# by the Argument::Interpreter
|
57
|
+
def optional name, type, &block
|
58
|
+
@dsl.arguments.add_argument name, false, type, &block
|
59
|
+
end
|
60
|
+
|
61
|
+
# adds a new required argument to the DSLMethod
|
62
|
+
#
|
63
|
+
# name must be a symbol
|
64
|
+
# `type` can be either :integer, :boolean, :float, :string or :symbol
|
65
|
+
# `block` contains the argument definition and will be evaluated seperately
|
66
|
+
# by the Argument::Interpreter
|
67
|
+
def requires name, type, &block
|
68
|
+
@dsl.arguments.add_argument name, true, type, &block
|
69
|
+
end
|
50
70
|
end
|
51
71
|
end
|
52
72
|
end
|
data/lib/dsl_compose/dsl.rb
CHANGED
@@ -49,6 +49,8 @@ module DSLCompose
|
|
49
49
|
# An otional description of this DSL, if provided then it must be a string.
|
50
50
|
# The description accepts markdown and is used when generating documentation.
|
51
51
|
attr_reader :description
|
52
|
+
# an object which represents the argument configuration
|
53
|
+
attr_reader :arguments
|
52
54
|
|
53
55
|
# Create a new DSL object with the provided name and class.
|
54
56
|
#
|
@@ -57,6 +59,8 @@ module DSLCompose
|
|
57
59
|
def initialize name, klass
|
58
60
|
@dsl_methods = {}
|
59
61
|
|
62
|
+
@arguments = Arguments.new
|
63
|
+
|
60
64
|
if name.is_a? Symbol
|
61
65
|
@name = name
|
62
66
|
else
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSLCompose
|
4
|
+
class Interpreter
|
5
|
+
class Execution
|
6
|
+
class Arguments
|
7
|
+
class MissingRequiredArgumentsError < StandardError
|
8
|
+
def initialize required_count, provided_count
|
9
|
+
super "This method requires #{required_count} arguments, but only #{required_count} were provided"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TooManyArgumentsError < StandardError
|
14
|
+
def message
|
15
|
+
"Too many arguments provided to this method"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class OptionalArgsShouldBeHashError < StandardError
|
20
|
+
def message
|
21
|
+
"If provided, then the optional arguments must be last, and be represented as a Hash"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class InvalidArgumentTypeError < StandardError
|
26
|
+
def message
|
27
|
+
"The provided argument is the wrong type"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :arguments
|
32
|
+
|
33
|
+
def initialize arguments, *args
|
34
|
+
@arguments = {}
|
35
|
+
|
36
|
+
required_argument_count = arguments.required_arguments.count
|
37
|
+
has_optional_arguments = arguments.optional_arguments.any?
|
38
|
+
|
39
|
+
# the first N args, where N = required_argument_count, are the
|
40
|
+
# provided required arguments
|
41
|
+
required_args = args.slice(0, required_argument_count)
|
42
|
+
# the optional arg which comes next is the hash which represents
|
43
|
+
# all the optional arguments
|
44
|
+
optional_arg = args[required_argument_count]
|
45
|
+
|
46
|
+
# assert that a value is provided for every required argument
|
47
|
+
unless required_argument_count == required_args.count
|
48
|
+
raise MissingRequiredArgumentsError.new required_argument_count, required_args.count
|
49
|
+
end
|
50
|
+
|
51
|
+
# assert that too many arguments have not been provided
|
52
|
+
if args.count > required_argument_count + (has_optional_arguments ? 1 : 0)
|
53
|
+
raise TooManyArgumentsError
|
54
|
+
end
|
55
|
+
|
56
|
+
# asset that, if provided, then the optional argument (always the last one) is a Hash
|
57
|
+
if has_optional_arguments && optional_arg.nil? === false
|
58
|
+
unless optional_arg.is_a? Hash
|
59
|
+
raise OptionalArgsShouldBeHashError
|
60
|
+
end
|
61
|
+
|
62
|
+
# assert the each provided optional argument is valid
|
63
|
+
optional_arg.keys.each do |optional_argument_name|
|
64
|
+
optional_arg_value = optional_arg[optional_argument_name]
|
65
|
+
optional_argument = arguments.optional_argument optional_argument_name
|
66
|
+
|
67
|
+
case optional_argument.type
|
68
|
+
when :integer
|
69
|
+
unless optional_arg_value.is_a? Integer
|
70
|
+
raise InvalidArgumentTypeError
|
71
|
+
end
|
72
|
+
optional_argument.validate_integer! optional_arg_value
|
73
|
+
|
74
|
+
when :symbol
|
75
|
+
unless optional_arg_value.is_a? Symbol
|
76
|
+
raise InvalidArgumentTypeError
|
77
|
+
end
|
78
|
+
optional_argument.validate_symbol! optional_arg_value
|
79
|
+
|
80
|
+
when :string
|
81
|
+
unless optional_arg_value.is_a? String
|
82
|
+
raise InvalidArgumentTypeError
|
83
|
+
end
|
84
|
+
optional_argument.validate_string! optional_arg_value
|
85
|
+
|
86
|
+
when :boolean
|
87
|
+
unless optional_arg_value.is_a?(TrueClass) || optional_arg_value.is_a?(FalseClass)
|
88
|
+
raise InvalidArgumentTypeError
|
89
|
+
end
|
90
|
+
optional_argument.validate_boolean! optional_arg_value
|
91
|
+
|
92
|
+
else
|
93
|
+
raise InvalidArgumentTypeError
|
94
|
+
end
|
95
|
+
|
96
|
+
# the provided value appears valid for this argument, save the value
|
97
|
+
@arguments[optional_argument_name] = optional_arg_value
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
# validate the value provided to each required argument
|
103
|
+
arguments.required_arguments.each_with_index do |required_argument, i|
|
104
|
+
arg = args[i]
|
105
|
+
case required_argument.type
|
106
|
+
when :integer
|
107
|
+
unless arg.is_a? Integer
|
108
|
+
raise InvalidArgumentTypeError
|
109
|
+
end
|
110
|
+
required_argument.validate_integer! arg
|
111
|
+
|
112
|
+
when :symbol
|
113
|
+
unless arg.is_a? Symbol
|
114
|
+
raise InvalidArgumentTypeError
|
115
|
+
end
|
116
|
+
required_argument.validate_symbol! arg
|
117
|
+
|
118
|
+
when :string
|
119
|
+
unless arg.is_a? String
|
120
|
+
raise InvalidArgumentTypeError
|
121
|
+
end
|
122
|
+
required_argument.validate_string! arg
|
123
|
+
|
124
|
+
when :boolean
|
125
|
+
unless arg.is_a?(TrueClass) || arg.is_a?(FalseClass)
|
126
|
+
raise InvalidArgumentTypeError
|
127
|
+
end
|
128
|
+
required_argument.validate_boolean! arg
|
129
|
+
|
130
|
+
else
|
131
|
+
raise InvalidArgumentTypeError
|
132
|
+
end
|
133
|
+
|
134
|
+
# the provided value appears valid for this argument, save the value
|
135
|
+
@arguments[required_argument.name] = arg
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def to_h
|
140
|
+
@arguments
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -34,109 +34,7 @@ module DSLCompose
|
|
34
34
|
|
35
35
|
def initialize dsl_method, *args, &block
|
36
36
|
@dsl_method = dsl_method
|
37
|
-
@arguments =
|
38
|
-
|
39
|
-
required_argument_count = dsl_method.required_arguments.count
|
40
|
-
has_optional_arguments = dsl_method.optional_arguments.any?
|
41
|
-
|
42
|
-
# the first N args, where N = required_argument_count, are the
|
43
|
-
# provided required arguments
|
44
|
-
required_args = args.slice(0, required_argument_count)
|
45
|
-
# the optional arg which comes next is the hash which represents
|
46
|
-
# all the optional arguments
|
47
|
-
optional_arg = args[required_argument_count]
|
48
|
-
|
49
|
-
# assert that a value is provided for every required argument
|
50
|
-
unless required_argument_count == required_args.count
|
51
|
-
raise MissingRequiredArgumentsError.new required_argument_count, required_args.count
|
52
|
-
end
|
53
|
-
|
54
|
-
# assert that too many arguments have not been provided
|
55
|
-
if args.count > required_argument_count + (has_optional_arguments ? 1 : 0)
|
56
|
-
raise TooManyArgumentsError
|
57
|
-
end
|
58
|
-
|
59
|
-
# asset that, if provided, then the optional argument (always the last one) is a Hash
|
60
|
-
if has_optional_arguments && optional_arg.nil? === false
|
61
|
-
unless optional_arg.is_a? Hash
|
62
|
-
raise OptionalArgsShouldBeHashError
|
63
|
-
end
|
64
|
-
|
65
|
-
# assert the each provided optional argument is valid
|
66
|
-
optional_arg.keys.each do |optional_argument_name|
|
67
|
-
optional_arg_value = optional_arg[optional_argument_name]
|
68
|
-
optional_argument = dsl_method.optional_argument optional_argument_name
|
69
|
-
|
70
|
-
case optional_argument.type
|
71
|
-
when :integer
|
72
|
-
unless optional_arg_value.is_a? Integer
|
73
|
-
raise InvalidArgumentTypeError
|
74
|
-
end
|
75
|
-
optional_argument.validate_integer! optional_arg_value
|
76
|
-
|
77
|
-
when :symbol
|
78
|
-
unless optional_arg_value.is_a? Symbol
|
79
|
-
raise InvalidArgumentTypeError
|
80
|
-
end
|
81
|
-
optional_argument.validate_symbol! optional_arg_value
|
82
|
-
|
83
|
-
when :string
|
84
|
-
unless optional_arg_value.is_a? String
|
85
|
-
raise InvalidArgumentTypeError
|
86
|
-
end
|
87
|
-
optional_argument.validate_string! optional_arg_value
|
88
|
-
|
89
|
-
when :boolean
|
90
|
-
unless optional_arg_value.is_a?(TrueClass) || optional_arg_value.is_a?(FalseClass)
|
91
|
-
raise InvalidArgumentTypeError
|
92
|
-
end
|
93
|
-
optional_argument.validate_boolean! optional_arg_value
|
94
|
-
|
95
|
-
else
|
96
|
-
raise InvalidArgumentTypeError
|
97
|
-
end
|
98
|
-
|
99
|
-
# the provided value appears valid for this argument, save the value
|
100
|
-
@arguments[optional_argument_name] = optional_arg_value
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
# validate the value provided to each required argument
|
106
|
-
dsl_method.required_arguments.each_with_index do |required_argument, i|
|
107
|
-
arg = args[i]
|
108
|
-
case required_argument.type
|
109
|
-
when :integer
|
110
|
-
unless arg.is_a? Integer
|
111
|
-
raise InvalidArgumentTypeError
|
112
|
-
end
|
113
|
-
required_argument.validate_integer! arg
|
114
|
-
|
115
|
-
when :symbol
|
116
|
-
unless arg.is_a? Symbol
|
117
|
-
raise InvalidArgumentTypeError
|
118
|
-
end
|
119
|
-
required_argument.validate_symbol! arg
|
120
|
-
|
121
|
-
when :string
|
122
|
-
unless arg.is_a? String
|
123
|
-
raise InvalidArgumentTypeError
|
124
|
-
end
|
125
|
-
required_argument.validate_string! arg
|
126
|
-
|
127
|
-
when :boolean
|
128
|
-
unless arg.is_a?(TrueClass) || arg.is_a?(FalseClass)
|
129
|
-
raise InvalidArgumentTypeError
|
130
|
-
end
|
131
|
-
required_argument.validate_boolean! arg
|
132
|
-
|
133
|
-
else
|
134
|
-
raise InvalidArgumentTypeError
|
135
|
-
end
|
136
|
-
|
137
|
-
# the provided value appears valid for this argument, save the value
|
138
|
-
@arguments[required_argument.name] = arg
|
139
|
-
end
|
37
|
+
@arguments = Arguments.new(dsl_method.arguments, *args)
|
140
38
|
end
|
141
39
|
|
142
40
|
def method_name
|
@@ -145,7 +43,7 @@ module DSLCompose
|
|
145
43
|
|
146
44
|
def to_h
|
147
45
|
{
|
148
|
-
arguments: @arguments
|
46
|
+
arguments: @arguments.to_h
|
149
47
|
}
|
150
48
|
end
|
151
49
|
end
|
@@ -16,12 +16,16 @@ module DSLCompose
|
|
16
16
|
end
|
17
17
|
|
18
18
|
attr_reader :dsl
|
19
|
+
attr_reader :klass
|
19
20
|
attr_reader :method_calls
|
21
|
+
attr_reader :arguments
|
20
22
|
|
21
23
|
# execute/process a dynamically defined DSL
|
22
|
-
def initialize dsl, &block
|
24
|
+
def initialize klass, dsl, *args, &block
|
25
|
+
@klass = klass
|
23
26
|
@dsl = dsl
|
24
27
|
@method_calls = MethodCalls.new
|
28
|
+
@arguments = Arguments.new(dsl.arguments, *args)
|
25
29
|
|
26
30
|
# dynamically process the DSL by calling the provided block
|
27
31
|
# all methods executions will be caught and processed by the method_missing method below
|
@@ -10,32 +10,57 @@ module DSLCompose
|
|
10
10
|
attr_reader :executions
|
11
11
|
|
12
12
|
def initialize
|
13
|
-
@executions =
|
13
|
+
@executions = []
|
14
14
|
end
|
15
15
|
|
16
16
|
# Execute/process a dynamically defined DSL on a class.
|
17
17
|
# `klass` is the class in which the DSL is being used, not
|
18
18
|
# the class in which the DSL was defined.
|
19
|
-
def execute_dsl klass, dsl, &block
|
20
|
-
|
21
|
-
|
22
|
-
@executions[klass] << execution
|
19
|
+
def execute_dsl klass, dsl, *args, &block
|
20
|
+
execution = Execution.new(klass, dsl, *args, &block)
|
21
|
+
@executions << execution
|
23
22
|
execution
|
24
23
|
end
|
25
24
|
|
26
25
|
# Returns an array of all executions for a given class.
|
27
26
|
def class_executions klass
|
28
|
-
@executions
|
27
|
+
@executions.filter { |e| e.klass == klass }
|
29
28
|
end
|
30
29
|
|
31
|
-
|
30
|
+
# Returns an array of all executions for a given class.
|
31
|
+
def dsl_executions dsl_name
|
32
|
+
@executions.filter { |e| e.dsl.name == dsl_name }
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_h dsl_name
|
36
|
+
h = {}
|
37
|
+
dsl_executions(dsl_name).each do |execution|
|
38
|
+
h[execution.klass] ||= {
|
39
|
+
arguments: execution.arguments.to_h,
|
40
|
+
method_calls: {}
|
41
|
+
}
|
42
|
+
execution.method_calls.method_calls.each do |method_call|
|
43
|
+
h[execution.klass][:method_calls][method_call.method_name] ||= []
|
44
|
+
h[execution.klass][:method_calls][method_call.method_name] << method_call.to_h
|
45
|
+
end
|
46
|
+
end
|
47
|
+
h
|
48
|
+
end
|
49
|
+
|
50
|
+
def executions_by_class
|
32
51
|
h = {}
|
33
|
-
|
34
|
-
h[execution.
|
52
|
+
executions.each do |execution|
|
53
|
+
h[execution.klass] ||= {}
|
54
|
+
h[execution.klass][execution.dsl.name] ||= []
|
55
|
+
execution_h = {
|
56
|
+
arguments: execution.arguments.to_h,
|
57
|
+
method_calls: {}
|
58
|
+
}
|
35
59
|
execution.method_calls.method_calls.each do |method_call|
|
36
|
-
|
37
|
-
|
60
|
+
execution_h[:method_calls][method_call.method_name] ||= []
|
61
|
+
execution_h[:method_calls][method_call.method_name] << method_call.to_h
|
38
62
|
end
|
63
|
+
h[execution.klass][execution.dsl.name] << execution_h
|
39
64
|
end
|
40
65
|
h
|
41
66
|
end
|
data/lib/dsl_compose/version.rb
CHANGED
data/lib/dsl_compose.rb
CHANGED
@@ -2,18 +2,20 @@
|
|
2
2
|
|
3
3
|
require "dsl_compose/version"
|
4
4
|
|
5
|
-
require "dsl_compose/dsl/
|
6
|
-
require "dsl_compose/dsl/
|
7
|
-
require "dsl_compose/dsl/
|
8
|
-
require "dsl_compose/dsl/
|
9
|
-
require "dsl_compose/dsl/
|
10
|
-
require "dsl_compose/dsl/
|
11
|
-
require "dsl_compose/dsl/
|
12
|
-
require "dsl_compose/dsl/
|
13
|
-
require "dsl_compose/dsl/
|
14
|
-
|
15
|
-
require "dsl_compose/dsl/
|
16
|
-
require "dsl_compose/dsl/
|
5
|
+
require "dsl_compose/dsl/arguments/argument/equal_to_validation"
|
6
|
+
require "dsl_compose/dsl/arguments/argument/format_validation"
|
7
|
+
require "dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation"
|
8
|
+
require "dsl_compose/dsl/arguments/argument/greater_than_validation"
|
9
|
+
require "dsl_compose/dsl/arguments/argument/in_validation"
|
10
|
+
require "dsl_compose/dsl/arguments/argument/length_validation"
|
11
|
+
require "dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation"
|
12
|
+
require "dsl_compose/dsl/arguments/argument/less_than_validation"
|
13
|
+
require "dsl_compose/dsl/arguments/argument/not_in_validation"
|
14
|
+
|
15
|
+
require "dsl_compose/dsl/arguments/argument/interpreter"
|
16
|
+
require "dsl_compose/dsl/arguments/argument"
|
17
|
+
require "dsl_compose/dsl/arguments"
|
18
|
+
|
17
19
|
require "dsl_compose/dsl/dsl_method/interpreter"
|
18
20
|
require "dsl_compose/dsl/dsl_method"
|
19
21
|
|
@@ -23,6 +25,7 @@ require "dsl_compose/dsl"
|
|
23
25
|
|
24
26
|
require "dsl_compose/interpreter/execution/method_calls/method_call"
|
25
27
|
require "dsl_compose/interpreter/execution/method_calls"
|
28
|
+
require "dsl_compose/interpreter/execution/arguments"
|
26
29
|
require "dsl_compose/interpreter/execution"
|
27
30
|
require "dsl_compose/interpreter"
|
28
31
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dsl_compose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Craig Ulliott
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby gem to add dynamic DSLs to classes. DSLs are added to classes by
|
14
14
|
including the DSLCompose module, and then calling the add_dsl singleton method within
|
@@ -26,23 +26,25 @@ files:
|
|
26
26
|
- lib/dsl_compose.rb
|
27
27
|
- lib/dsl_compose/composer.rb
|
28
28
|
- lib/dsl_compose/dsl.rb
|
29
|
+
- lib/dsl_compose/dsl/arguments.rb
|
30
|
+
- lib/dsl_compose/dsl/arguments/argument.rb
|
31
|
+
- lib/dsl_compose/dsl/arguments/argument/equal_to_validation.rb
|
32
|
+
- lib/dsl_compose/dsl/arguments/argument/format_validation.rb
|
33
|
+
- lib/dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation.rb
|
34
|
+
- lib/dsl_compose/dsl/arguments/argument/greater_than_validation.rb
|
35
|
+
- lib/dsl_compose/dsl/arguments/argument/in_validation.rb
|
36
|
+
- lib/dsl_compose/dsl/arguments/argument/interpreter.rb
|
37
|
+
- lib/dsl_compose/dsl/arguments/argument/length_validation.rb
|
38
|
+
- lib/dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation.rb
|
39
|
+
- lib/dsl_compose/dsl/arguments/argument/less_than_validation.rb
|
40
|
+
- lib/dsl_compose/dsl/arguments/argument/not_in_validation.rb
|
29
41
|
- lib/dsl_compose/dsl/dsl_method.rb
|
30
|
-
- lib/dsl_compose/dsl/dsl_method/argument.rb
|
31
|
-
- lib/dsl_compose/dsl/dsl_method/argument/equal_to_validation.rb
|
32
|
-
- lib/dsl_compose/dsl/dsl_method/argument/format_validation.rb
|
33
|
-
- lib/dsl_compose/dsl/dsl_method/argument/greater_than_or_equal_to_validation.rb
|
34
|
-
- lib/dsl_compose/dsl/dsl_method/argument/greater_than_validation.rb
|
35
|
-
- lib/dsl_compose/dsl/dsl_method/argument/in_validation.rb
|
36
|
-
- lib/dsl_compose/dsl/dsl_method/argument/interpreter.rb
|
37
|
-
- lib/dsl_compose/dsl/dsl_method/argument/length_validation.rb
|
38
|
-
- lib/dsl_compose/dsl/dsl_method/argument/less_than_or_equal_to_validation.rb
|
39
|
-
- lib/dsl_compose/dsl/dsl_method/argument/less_than_validation.rb
|
40
|
-
- lib/dsl_compose/dsl/dsl_method/argument/not_in_validation.rb
|
41
42
|
- lib/dsl_compose/dsl/dsl_method/interpreter.rb
|
42
43
|
- lib/dsl_compose/dsl/interpreter.rb
|
43
44
|
- lib/dsl_compose/dsls.rb
|
44
45
|
- lib/dsl_compose/interpreter.rb
|
45
46
|
- lib/dsl_compose/interpreter/execution.rb
|
47
|
+
- lib/dsl_compose/interpreter/execution/arguments.rb
|
46
48
|
- lib/dsl_compose/interpreter/execution/method_calls.rb
|
47
49
|
- lib/dsl_compose/interpreter/execution/method_calls/method_call.rb
|
48
50
|
- lib/dsl_compose/version.rb
|