dsl_compose 2.12.0 → 2.13.1
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 +14 -0
- data/README.md +10 -0
- data/lib/dsl_compose/dsl/arguments/argument.rb +15 -1
- data/lib/dsl_compose/dsl/arguments.rb +3 -2
- data/lib/dsl_compose/dsl/dsl_method/interpreter.rb +5 -3
- data/lib/dsl_compose/dsl/interpreter.rb +5 -3
- data/lib/dsl_compose/interpreter/execution/arguments.rb +31 -11
- data/lib/dsl_compose/reader.rb +7 -6
- data/lib/dsl_compose/version.rb +1 -1
- data/sig/dsl_compose/dsl/arguments/argument.rbs +2 -1
- data/sig/dsl_compose/dsl/arguments.rbs +1 -1
- data/sig/dsl_compose/dsl/dsl_method/interpreter.rbs +1 -1
- data/sig/dsl_compose/dsl/interpreter.rbs +1 -1
- 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: 117789e8395652f4823ad048b258d2a683b65328d5817788b9d3d3d7bc377c8b
|
4
|
+
data.tar.gz: d4ad4b7a66de0cfd143006e4c9984bef0ce1c29e6e18b86a0621810cb2d11edb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbcf361a908dcd619664f12e50299f80092d5e2f4e8efb4f53320b2d13c3ca30ef334e429fe1a977fb899c0878f2dd26a30d9b067b74da22198eb2372984d2ad
|
7
|
+
data.tar.gz: 9e932a4d10693634bc25532d9d625ad1939f58c975bf90a0f4a0f1714586bdce5dc1650cf48cbfaa0655c56fbaa341fd27731953e4e3fe74fbefd63619fac6ad
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.13.1](https://github.com/craigulliott/dsl_compose/compare/v2.13.0...v2.13.1) (2023-09-05)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* fixed a nil value in error message caused by overwriting method argument ([dd7848b](https://github.com/craigulliott/dsl_compose/commit/dd7848b3861bff6176c8326f6784fb29f1ba2fdd))
|
9
|
+
|
10
|
+
## [2.13.0](https://github.com/craigulliott/dsl_compose/compare/v2.12.0...v2.13.0) (2023-09-04)
|
11
|
+
|
12
|
+
|
13
|
+
### Features
|
14
|
+
|
15
|
+
* optionally mark required arguments as keyword arguments ([9a1c901](https://github.com/craigulliott/dsl_compose/commit/9a1c90169fb36c550b0577034823579062120647))
|
16
|
+
|
3
17
|
## [2.12.0](https://github.com/craigulliott/dsl_compose/compare/v2.11.0...v2.12.0) (2023-09-02)
|
4
18
|
|
5
19
|
|
data/README.md
CHANGED
@@ -114,6 +114,16 @@ class Foo
|
|
114
114
|
validate_greater_than 0
|
115
115
|
end
|
116
116
|
|
117
|
+
# Required arguments for both DSLs and DSL methods are assumed to be standard ruby
|
118
|
+
# arguments by default, but can be declared as keyword arguments by passing `kwarg: true`.
|
119
|
+
# This is useful because sometimes keyword arguments can make your DSL more readable. This
|
120
|
+
# option does not exist for optional arguments, because optional arguments are always kwargs.
|
121
|
+
requires :required_keyword_argument, :symbol, kwarg: true do
|
122
|
+
# You should provide descriptions for your arguments. These descriptions will
|
123
|
+
# be used when generating your documentation. This description supports markdown
|
124
|
+
description "A description of the first argument for this method"
|
125
|
+
end
|
126
|
+
|
117
127
|
# All optional and required arguments can optionally accept an array of values. When using
|
118
128
|
# your final DSL, a single item can be provided but will automatically be converted to an
|
119
129
|
# array of items. All items in the array must be of the expected type.
|
@@ -13,6 +13,9 @@ module DSLCompose
|
|
13
13
|
class InvalidTypeError < StandardError
|
14
14
|
end
|
15
15
|
|
16
|
+
class ImpossibleKwargError < StandardError
|
17
|
+
end
|
18
|
+
|
16
19
|
class InvalidNameError < StandardError
|
17
20
|
end
|
18
21
|
|
@@ -42,6 +45,10 @@ module DSLCompose
|
|
42
45
|
attr_reader :type
|
43
46
|
# if required, then this Argument must be provided when calling its associated DSLMethod.
|
44
47
|
attr_reader :required
|
48
|
+
# If true, then this argument must be provided as a keyword argument, this is only appropriate for
|
49
|
+
# required arguments, as optional arguments are always passed as keywork arguments.
|
50
|
+
# arguments.
|
51
|
+
attr_reader :kwarg
|
45
52
|
# If true, then this argument accepts an array of values. It will also accept a single value,
|
46
53
|
# but that single value will be automatically converted to an array
|
47
54
|
attr_reader :array
|
@@ -71,9 +78,10 @@ module DSLCompose
|
|
71
78
|
# `name` must be a symbol.
|
72
79
|
# `required` is a boolean which determines if this Attribute must be provided when
|
73
80
|
# calling its associated DSLMethod.
|
81
|
+
# `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
|
74
82
|
# `type` can be either :integer, :boolean, :float, :string or :symbol
|
75
83
|
# `block` contains the instructions to further configure this Attribute
|
76
|
-
def initialize name, required, type, array: false, &block
|
84
|
+
def initialize name, required, kwarg, type, array: false, &block
|
77
85
|
if name.is_a? Symbol
|
78
86
|
|
79
87
|
if RESERVED_ARGUMENT_NAMES.include? name
|
@@ -93,6 +101,12 @@ module DSLCompose
|
|
93
101
|
|
94
102
|
@required = required ? true : false
|
95
103
|
|
104
|
+
if @required == false && kwarg == true
|
105
|
+
raise ImpossibleKwargError, "Optional arguments must always be provided as keyword arguments. The argument `#{name}` can not be both required: false and kwarg: true."
|
106
|
+
end
|
107
|
+
|
108
|
+
@kwarg = kwarg ? true : false
|
109
|
+
|
96
110
|
@array = array ? true : false
|
97
111
|
|
98
112
|
# If a block was provided, then we evaluate it using a seperate
|
@@ -85,8 +85,9 @@ module DSLCompose
|
|
85
85
|
#
|
86
86
|
# Argument `name` must be unique within the DSLMethod.
|
87
87
|
# `required` must be a boolean, and determines if this argument will be required
|
88
|
+
# `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
|
88
89
|
# or optional on the method which is exposed in our DSL.
|
89
|
-
def add_argument name, required, type, array: false, &block
|
90
|
+
def add_argument name, required, kwarg, type, array: false, &block
|
90
91
|
if @arguments.key? name
|
91
92
|
raise ArgumentAlreadyExistsError, "An argument with the name `#{name}` already exists for this DSL method"
|
92
93
|
end
|
@@ -96,7 +97,7 @@ module DSLCompose
|
|
96
97
|
raise ArgumentOrderingError, "Required arguments can not be added after optional ones"
|
97
98
|
end
|
98
99
|
|
99
|
-
@arguments[name] = Argument.new(name, required, type, array: array, &block)
|
100
|
+
@arguments[name] = Argument.new(name, required, kwarg, type, array: array, &block)
|
100
101
|
end
|
101
102
|
end
|
102
103
|
end
|
@@ -39,17 +39,19 @@ module DSLCompose
|
|
39
39
|
# `block` contains the argument definition and will be evaluated seperately
|
40
40
|
# by the Argument::Interpreter
|
41
41
|
def optional name, type, array: false, &block
|
42
|
-
@dsl_method.arguments.add_argument name, false, type, array: array, &block
|
42
|
+
@dsl_method.arguments.add_argument name, false, false, type, array: array, &block
|
43
43
|
end
|
44
44
|
|
45
45
|
# adds a new required argument to the DSLMethod
|
46
46
|
#
|
47
47
|
# name must be a symbol
|
48
|
+
# `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
|
49
|
+
# `array` is a boolean which determines if this argument will accept an array of the given type or a single item
|
48
50
|
# `type` can be either :integer, :boolean, :float, :string or :symbol
|
49
51
|
# `block` contains the argument definition and will be evaluated seperately
|
50
52
|
# by the Argument::Interpreter
|
51
|
-
def requires name, type, array: false, &block
|
52
|
-
@dsl_method.arguments.add_argument name, true, type, array: array, &block
|
53
|
+
def requires name, type, kwarg: false, array: false, &block
|
54
|
+
@dsl_method.arguments.add_argument name, true, kwarg, type, array: array, &block
|
53
55
|
end
|
54
56
|
|
55
57
|
# executes the shared configuration block with the given name within the
|
@@ -66,17 +66,19 @@ module DSLCompose
|
|
66
66
|
# `block` contains the argument definition and will be evaluated seperately
|
67
67
|
# by the Argument::Interpreter
|
68
68
|
def optional name, type, array: false, &block
|
69
|
-
@dsl.arguments.add_argument name, false, type, array: array, &block
|
69
|
+
@dsl.arguments.add_argument name, false, false, type, array: array, &block
|
70
70
|
end
|
71
71
|
|
72
72
|
# adds a new required argument to the DSLMethod
|
73
73
|
#
|
74
74
|
# name must be a symbol
|
75
|
+
# `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
|
76
|
+
# `array` is a boolean which determines if this argument will accept an array of the given type or a single item
|
75
77
|
# `type` can be either :integer, :boolean, :float, :string, :symbol, :class or :object
|
76
78
|
# `block` contains the argument definition and will be evaluated seperately
|
77
79
|
# by the Argument::Interpreter
|
78
|
-
def requires name, type, array: false, &block
|
79
|
-
@dsl.arguments.add_argument name, true, type, array: array, &block
|
80
|
+
def requires name, type, kwarg: false, array: false, &block
|
81
|
+
@dsl.arguments.add_argument name, true, kwarg, type, array: array, &block
|
80
82
|
end
|
81
83
|
|
82
84
|
# executes the shared configuration block with the given name within the
|
@@ -25,18 +25,38 @@ module DSLCompose
|
|
25
25
|
@arguments = {}
|
26
26
|
|
27
27
|
required_argument_count = arguments.required_arguments.count
|
28
|
+
required_non_kwarg_argument_count = arguments.required_arguments.count { |a| !a.kwarg }
|
28
29
|
has_optional_arguments = arguments.optional_arguments.any?
|
29
30
|
|
30
|
-
# the first N args, where N =
|
31
|
+
# the first N args, where N = required_non_kwarg_argument_count, are the
|
31
32
|
# provided required arguments
|
32
|
-
required_args = args.slice(0,
|
33
|
-
|
34
|
-
# all the
|
35
|
-
|
33
|
+
required_args = args.slice(0, required_non_kwarg_argument_count)
|
34
|
+
|
35
|
+
# the final argument is the object which contains all the keyword args (these keyword
|
36
|
+
# args could be optional or required)
|
37
|
+
all_kwargs = args[required_non_kwarg_argument_count]
|
38
|
+
|
39
|
+
# process all the required arguments which are kwargs
|
40
|
+
required_kwargs = arguments.required_arguments.filter { |a| a.kwarg }
|
41
|
+
required_kwargs.each do |required_kwarg|
|
42
|
+
if all_kwargs.key? required_kwarg.name
|
43
|
+
# add the keyword argument to the required args
|
44
|
+
required_args << all_kwargs[required_kwarg.name]
|
45
|
+
# delete the required kwarg from the kwargs hash, so that we are
|
46
|
+
# left with only the optional args
|
47
|
+
all_kwargs.delete required_kwarg.name
|
48
|
+
else
|
49
|
+
raise MissingRequiredArgumentsError, "The required kwarg `#{required_kwarg.name}` was not provided"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# at this point, all_kwargs should be a hash which only represents
|
54
|
+
# the optional arguments
|
55
|
+
optional_arg = all_kwargs
|
36
56
|
|
37
57
|
# assert that a value is provided for every required argument
|
38
58
|
unless required_argument_count == required_args.count
|
39
|
-
raise MissingRequiredArgumentsError, "This requires #{
|
59
|
+
raise MissingRequiredArgumentsError, "This requires #{required_non_kwarg_argument_count} arguments, but only #{required_args.count} were provided"
|
40
60
|
end
|
41
61
|
|
42
62
|
# assert that too many arguments have not been provided
|
@@ -61,7 +81,7 @@ module DSLCompose
|
|
61
81
|
end
|
62
82
|
|
63
83
|
# asset that, if provided, then the optional argument (always the last one) is a Hash
|
64
|
-
if has_optional_arguments && optional_arg.nil?
|
84
|
+
if has_optional_arguments && !optional_arg.nil?
|
65
85
|
unless optional_arg.is_a? Hash
|
66
86
|
raise OptionalArgumentsShouldBeHashError, "If provided, then the optional arguments must be last, and be represented as a Hash"
|
67
87
|
end
|
@@ -165,13 +185,13 @@ module DSLCompose
|
|
165
185
|
# to the corresponding class, logic which doesn't happen here in case the class doesnt
|
166
186
|
# exist yet)
|
167
187
|
required_arg_value = if required_argument.type == :class
|
168
|
-
if
|
169
|
-
|
188
|
+
if required_args[i].is_a?(Array)
|
189
|
+
required_args[i].map { |v| ClassCoerce.new v }
|
170
190
|
else
|
171
|
-
ClassCoerce.new
|
191
|
+
ClassCoerce.new required_args[i]
|
172
192
|
end
|
173
193
|
else
|
174
|
-
|
194
|
+
required_args[i]
|
175
195
|
end
|
176
196
|
|
177
197
|
if required_arg_value.is_a?(Array) && !required_argument.array
|
data/lib/dsl_compose/reader.rb
CHANGED
@@ -24,24 +24,25 @@ module DSLCompose
|
|
24
24
|
# Move up through this classes ancestors until we find the class which defined
|
25
25
|
# the DSL with the provided name. When we reach the top of the ancestor chain we
|
26
26
|
# exit the loop.
|
27
|
-
|
27
|
+
k = klass
|
28
|
+
while k
|
28
29
|
# if we find a DSL with this name, then store a reference to the DSL and the
|
29
30
|
# ancestor class where it was defined
|
30
|
-
if DSLs.class_dsl_exists?(
|
31
|
-
@dsl = DSLs.class_dsl(
|
32
|
-
@dsl_defining_class =
|
31
|
+
if DSLs.class_dsl_exists?(k, dsl_name)
|
32
|
+
@dsl = DSLs.class_dsl(k, dsl_name)
|
33
|
+
@dsl_defining_class = k
|
33
34
|
# stop once we find the DSL
|
34
35
|
break
|
35
36
|
end
|
36
37
|
|
37
38
|
# the DSL was not found here, so traverse up the provided classes hierachy
|
38
39
|
# and keep looking for where this DSL was initially defined
|
39
|
-
|
40
|
+
k = k.superclass
|
40
41
|
end
|
41
42
|
|
42
43
|
# if no DSL was found, then raise an error
|
43
44
|
if @dsl.nil? && @dsl_defining_class.nil?
|
44
|
-
raise DSLNotFound, "No DSL named `#{dsl_name}` was found for class `#{klass}`"
|
45
|
+
raise DSLNotFound, "No DSL named `#{dsl_name}` was found for class `#{@klass}`"
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|
data/lib/dsl_compose/version.rb
CHANGED
@@ -9,6 +9,7 @@ module DSLCompose
|
|
9
9
|
attr_reader name: Symbol
|
10
10
|
attr_reader type: argument_type
|
11
11
|
attr_reader required: bool
|
12
|
+
attr_reader kwarg: bool
|
12
13
|
attr_reader array: bool
|
13
14
|
attr_reader description: String
|
14
15
|
|
@@ -27,7 +28,7 @@ module DSLCompose
|
|
27
28
|
attr_reader length_validation: LengthValidation
|
28
29
|
attr_reader is_a_validation: IsAValidation
|
29
30
|
|
30
|
-
def initialize: (Symbol name, bool required, argument_type `type`, ?array: bool) -> void
|
31
|
+
def initialize: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool) -> void
|
31
32
|
def set_description: (String description) -> void
|
32
33
|
def has_description?: () -> bool
|
33
34
|
def required?: -> bool
|
@@ -12,7 +12,7 @@ module DSLCompose
|
|
12
12
|
def optional_argument: (Symbol name) -> Argument
|
13
13
|
def required_argument: (Symbol name) -> Argument
|
14
14
|
def has_argument?: (Symbol name) -> bool
|
15
|
-
def add_argument: (Symbol name, bool required, argument_type `type`, ?array: bool) -> Argument
|
15
|
+
def add_argument: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool) -> Argument
|
16
16
|
|
17
17
|
class ArgumentDoesNotExistError < StandardError
|
18
18
|
end
|
@@ -11,7 +11,7 @@ module DSLCompose
|
|
11
11
|
private
|
12
12
|
def description: (String description) -> void
|
13
13
|
def optional: (Symbol name, argument_type `type`, ?array: bool) -> void
|
14
|
-
def requires: (Symbol name, argument_type `type`, ?array: bool) -> void
|
14
|
+
def requires: (Symbol name, argument_type `type`, ?kwarg: bool, ?array: bool) -> void
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -14,7 +14,7 @@ module DSLCompose
|
|
14
14
|
def add_method: (Symbol name, ?required: nil) -> void
|
15
15
|
def add_unique_method: (Symbol name, ?required: nil) -> void
|
16
16
|
def optional: (Symbol name, argument_type `type`, ?array: bool) -> void
|
17
|
-
def requires: (Symbol name, argument_type `type`, ?array: bool) -> void
|
17
|
+
def requires: (Symbol name, argument_type `type`, ?kwarg: bool, ?array: bool) -> void
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
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: 2.
|
4
|
+
version: 2.13.1
|
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-09-
|
11
|
+
date: 2023-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: class_spec_helper
|