dsl_compose 2.14.3 → 2.15.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddbe8b1e65763bba6eb8893aae605c7a3767c2d14f5aa5e120340cca933c6b1b
4
- data.tar.gz: bdec4caaf6784bb0721fbd00593b0112d79f9fbf9c807f97bb89c3c713341053
3
+ metadata.gz: ae01b58f13f59318a89b06b444bd0dc0a17487e66d03a7701cb605673774f75a
4
+ data.tar.gz: 2feeab8f8494a6dea3ee59c52903a21c84cde2da623f406aea9530581146d124
5
5
  SHA512:
6
- metadata.gz: 81c959506de138f0d4598d152d5d9b66756e0018bb0cee870fc749a49cbdcca6132c4252b7cb0c38308c517ead07102fe644ac12301aff743d3054e32efff404
7
- data.tar.gz: 4f02a341c854c005c2212b6387b40f5ce805fe1c5aabf277d69ce91b0d85e34cb003c805d6fad3681b33964c5cc8c6952216d2152b57165ade6e793db242ad4e
6
+ metadata.gz: 6d1b476aef66fcaf034b3e7775a91233b69f30dc46c1dfc6d2891596ed859d0a9219e69c7bfec5ede49179d56a0fa2e59f31398b5b95504eb8ebd72c6f9a4d01
7
+ data.tar.gz: 565b63fb9b5e24f6d778e74f477b7aea4cd6619bfb39aa5ae62a9651daffd5b54e06ceaa8cef3378c111b508babe89d55d02af768c0692f24e4be9c68ad23845
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.15.1](https://github.com/craigulliott/dsl_compose/compare/v2.15.0...v2.15.1) (2023-10-03)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * sorting classes by ancestry chain (i.e. ancestors before descendants) in the parser ([4e7dd6f](https://github.com/craigulliott/dsl_compose/commit/4e7dd6fd302c50ee3147f76f59a52089fb6f39ee))
9
+
10
+ ## [2.15.0](https://github.com/craigulliott/dsl_compose/compare/v2.14.3...v2.15.0) (2023-10-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * added option to skip certain provided classes within dsl parsers ([c2be111](https://github.com/craigulliott/dsl_compose/commit/c2be111289f4ca0b84b95e641c18bdbd784b5b6f))
16
+ * adding default values for dsl arguments ([b89bd69](https://github.com/craigulliott/dsl_compose/commit/b89bd697eb6598f5f723a28533bd3e67e4ab9207))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * passing classes to skip to the parser as class names (strings) instead of the actual classes. This prevents this library holding a reference to those classes and preventing garbage collection of the classes when they are dynamically created/destroyed within a test suite. ([74b332a](https://github.com/craigulliott/dsl_compose/commit/74b332ab99b7cf96bb8468a06634ee217cd5c58b))
22
+
3
23
  ## [2.14.3](https://github.com/craigulliott/dsl_compose/compare/v2.14.2...v2.14.3) (2023-09-27)
4
24
 
5
25
 
data/README.md CHANGED
@@ -106,8 +106,9 @@ class Foo
106
106
 
107
107
  # You can also add optional arguments to your DSL methods. All optional
108
108
  # arguments must be added after required ones. An error will be raised if
109
- # you define a required argument after an optional one.
110
- optional :optional_argument, :integer do
109
+ # you define a required argument after an optional one. Optional arguments can
110
+ # have an default value, if a default is not provided then nil will be assumed.
111
+ optional :optional_argument, :integer, default: 123 do
111
112
  description "A description of an optional argument"
112
113
 
113
114
  # You can add validation to your arguments. A full list is provided later in this document
@@ -281,6 +282,9 @@ class MyParser < DSLCompose::Parser
281
282
  # If you only want to process classes at the end of the class hierarchy (classes
282
283
  # which extend the provided base class, but do not have their own children) then
283
284
  # use `for_final_children_of` instead of `for_children_of`
285
+ #
286
+ # Both `for_children_of` and `for_final_children_of` accept an optional parameter
287
+ # named skip_classes which accepts an array of class names which should be skipped.
284
288
  for_children_of SomeBaseClass do |child_class:|
285
289
  add_documentation <<~DESCRIPTION
286
290
  You can optionally provide a description of anything specific that your parser
@@ -367,7 +371,7 @@ In addition to parser classes (or as a useful tool within parser classes) you ca
367
371
  # simple API to access the arguments, methods and method arguments which
368
372
  # were provided when using a DSL.
369
373
  #
370
- # In the example below, MyClass is a class, or descendent of a class which
374
+ # In the example below, MyClass is a class, or descendant of a class which
371
375
  # had a DSL defined on it with the name :my_dsl.
372
376
  #
373
377
  # An error will be raised if a DSL with the provided name was never defined
@@ -52,6 +52,8 @@ module DSLCompose
52
52
  # If true, then this argument accepts an array of values. It will also accept a single value,
53
53
  # but that single value will be automatically converted to an array
54
54
  attr_reader :array
55
+ # The default value for optional arguments, if one is not provided then nil will be assumed.
56
+ attr_reader :default
55
57
  # An otional description of this Attribute, if provided then it must be a string.
56
58
  # The description accepts markdown and is used when generating documentation.
57
59
  attr_reader :description
@@ -81,7 +83,7 @@ module DSLCompose
81
83
  # `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
82
84
  # `type` can be either :integer, :boolean, :float, :string or :symbol
83
85
  # `block` contains the instructions to further configure this Attribute
84
- def initialize name, required, kwarg, type, array: false, &block
86
+ def initialize name, required, kwarg, type, array: false, default: nil, &block
85
87
  if name.is_a? Symbol
86
88
 
87
89
  if RESERVED_ARGUMENT_NAMES.include? name
@@ -109,6 +111,13 @@ module DSLCompose
109
111
 
110
112
  @array = array ? true : false
111
113
 
114
+ unless default.nil?
115
+ if @required
116
+ raise ImpossibleKwargError, "The argument `#{name}` is required, so can not be given a default value."
117
+ end
118
+ @default = default
119
+ end
120
+
112
121
  # If a block was provided, then we evaluate it using a seperate
113
122
  # interpreter class. We do this because the interpreter class contains
114
123
  # no other methods or variables, if it was evaluated in the context of
@@ -85,9 +85,11 @@ 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
+ # `array` is a boolean which determines if this argument will accept an array of the given type or a single item
89
+ # `default` contains the default value, if one is not provided then nil will be assumed (it is only available for optional arguments)
88
90
  # `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
89
91
  # or optional on the method which is exposed in our DSL.
90
- def add_argument name, required, kwarg, type, array: false, &block
92
+ def add_argument name, required, kwarg, type, array: false, default: nil, &block
91
93
  if @arguments.key? name
92
94
  raise ArgumentAlreadyExistsError, "An argument with the name `#{name}` already exists for this DSL method"
93
95
  end
@@ -97,7 +99,7 @@ module DSLCompose
97
99
  raise ArgumentOrderingError, "Required arguments can not be added after optional ones"
98
100
  end
99
101
 
100
- @arguments[name] = Argument.new(name, required, kwarg, type, array: array, &block)
102
+ @arguments[name] = Argument.new(name, required, kwarg, type, array: array, default: default, &block)
101
103
  end
102
104
  end
103
105
  end
@@ -63,10 +63,12 @@ module DSLCompose
63
63
  #
64
64
  # name must be a symbol
65
65
  # `type` can be either :integer, :boolean, :float, :string, :symbol, :class or :object
66
+ # `array` is a boolean which determines if this argument will accept an array of the given type or a single item
67
+ # `default` contains the default value, if one is not provided then nil will be assumed
66
68
  # `block` contains the argument definition and will be evaluated seperately
67
69
  # by the Argument::Interpreter
68
- def optional name, type, array: false, &block
69
- @dsl.arguments.add_argument name, false, false, type, array: array, &block
70
+ def optional name, type, array: false, default: nil, &block
71
+ @dsl.arguments.add_argument name, false, false, type, array: array, default: default, &block
70
72
  end
71
73
 
72
74
  # adds a new required argument to the DSLMethod
@@ -69,17 +69,17 @@ module DSLCompose
69
69
  raise TooManyArgumentsError, "Too many arguments provided"
70
70
  end
71
71
 
72
- # Assume all optonal arguments are nil (except booleans, which default to false).
72
+ # Assume all optonal arguments are their defaults (except booleans, which default to false).
73
73
  # If actual values were provided, then they will be set further below.
74
74
  if arguments.optional_arguments.any?
75
75
  arguments.optional_arguments.each do |optional_argument|
76
76
  # assume it is nil
77
- @arguments[optional_argument.name] = nil
77
+ @arguments[optional_argument.name] = optional_argument.default
78
78
  # unless the argument is an array or a boolean, in which case it defaults
79
79
  # to an empty array or false
80
80
  if optional_argument.array
81
81
  @arguments[optional_argument.name] = [].freeze
82
- elsif optional_argument.type == :boolean
82
+ elsif optional_argument.type == :boolean && optional_argument.default.nil?
83
83
  @arguments[optional_argument.name] = false
84
84
  end
85
85
  end
@@ -82,7 +82,7 @@ module DSLCompose
82
82
  def get_last_dsl_execution klass, dsl_name
83
83
  # note that this method does not need to do any special sorting, the required
84
84
  # order for getting the most recent execution is already guaranteed because
85
- # parent classes in ruby always have to be evaluated before their descendents
85
+ # parent classes in ruby always have to be evaluated before their descendants
86
86
  class_dsl_executions(klass, dsl_name, true, true).last
87
87
  end
88
88
 
@@ -3,27 +3,44 @@
3
3
  module DSLCompose
4
4
  class Parser
5
5
  class ForChildrenOfParser
6
- class Descendents
7
- def initialize base_class, final_children_only
6
+ class Descendants
7
+ def initialize base_class, final_children_only, skip_classes = []
8
8
  @base_class = base_class
9
9
  @final_children_only = final_children_only
10
+ @skip_classes = skip_classes
10
11
  end
11
12
 
12
13
  def classes
13
14
  # all objects which extend the provided base class
14
15
  extending_classes = subclasses @base_class
15
16
 
16
- # sort the results, classes are ordered first by the depth of their namespace, and second
17
- # by the presence of decendents and finally by their name
17
+ # sort the results
18
+ #
19
+ # classes are ordered first by name
18
20
  extending_classes.sort_by! do |child_class|
19
- "#{child_class.name.split("::").count}_#{has_descendents(child_class) ? 0 : 1}_#{child_class.name}"
21
+ "#{child_class.name.split("::").count}_#{has_descendants(child_class) ? 0 : 1}_#{child_class.name}"
22
+ end
23
+ # then by ansestory chain (i.e. ancestors before descendants)
24
+ extending_classes.sort do |a, b|
25
+ if a < b
26
+ 1
27
+ elsif a > b
28
+ -1
29
+ else
30
+ 0
31
+ end
32
+ end
33
+
34
+ # reject any classes which we are skipping
35
+ extending_classes.reject! do |child_class|
36
+ @skip_classes.include? child_class.name
20
37
  end
21
38
 
22
39
  # if this is not a final child, but we are processing final children only, then skip it
23
40
  if @final_children_only
24
- # reject any classes which have descendents
41
+ # reject any classes which have descendants
25
42
  extending_classes.reject! do |child_class|
26
- has_descendents child_class
43
+ has_descendants child_class
27
44
  end
28
45
  end
29
46
 
@@ -39,7 +56,7 @@ module DSLCompose
39
56
  }.flatten
40
57
  end
41
58
 
42
- def has_descendents base_class
59
+ def has_descendants base_class
43
60
  base_class.subclasses.count { |subclass| class_is_still_defined? subclass } > 0
44
61
  end
45
62
 
@@ -35,7 +35,7 @@ module DSLCompose
35
35
  # parser.for_children_of BaseClass do |child_class:|
36
36
  # # this will yield for ChildClass and GrandchildClass
37
37
  # and
38
- def initialize base_class, final_children_only, &block
38
+ def initialize base_class, final_children_only, skip_classes = [], &block
39
39
  # assert the provided class has the DSLCompose::Composer module installed
40
40
  unless base_class.respond_to? :dsls
41
41
  raise ClassDoesNotUseDSLComposeError, base_class
@@ -56,8 +56,8 @@ module DSLCompose
56
56
  end
57
57
  end
58
58
 
59
- # yeild the block for all descendents of the provided base_class
60
- Descendents.new(base_class, final_children_only).classes.each do |child_class|
59
+ # yeild the block for all descendants of the provided base_class
60
+ Descendants.new(base_class, final_children_only, skip_classes).classes.each do |child_class|
61
61
  # determine which arguments to send to the block
62
62
  args = {}
63
63
  if BlockArguments.accepts_argument?(:child_class, &block)
@@ -30,27 +30,28 @@ module DSLCompose
30
30
  # If `final_children_only` is true, then this will cause the parser to only return
31
31
  # classes which are at the end of their class hierachy (meaning they dont have any
32
32
  # children of their own)
33
- def self.for_children_of base_class, final_children_only: false, rerun: false, &block
33
+ def self.for_children_of base_class, final_children_only: false, skip_classes: [], rerun: false, &block
34
34
  unless rerun
35
35
  @runs ||= []
36
36
  @runs << {
37
37
  base_class: base_class,
38
38
  final_children_only: final_children_only,
39
+ skip_classes: skip_classes,
39
40
  block: block
40
41
  }
41
42
  end
42
43
 
43
44
  # we parse the provided block in the context of the ForChildrenOfParser class
44
45
  # to help make this code more readable, and to limit polluting the current namespace
45
- ForChildrenOfParser.new(base_class, final_children_only, &block)
46
+ ForChildrenOfParser.new(base_class, final_children_only, skip_classes, &block)
46
47
  end
47
48
 
48
49
  # this is a wrapper for the `for_children_of` method, but it provides a value
49
50
  # of true for the `final_children_only` argument. This will cause the parser to only
50
51
  # return classes which are at the end of the class hierachy (meaning they dont have
51
52
  # any children of their own)
52
- def self.for_final_children_of base_class, &block
53
- for_children_of base_class, final_children_only: true, &block
53
+ def self.for_final_children_of base_class, skip_classes: [], &block
54
+ for_children_of base_class, final_children_only: true, skip_classes: skip_classes, &block
54
55
  end
55
56
 
56
57
  # this method is used to rerun the parser, this is most useful from within a test suite
@@ -61,7 +62,8 @@ module DSLCompose
61
62
  base_class = run[:base_class]
62
63
  block = run[:block]
63
64
  final_children_only = run[:final_children_only]
64
- for_children_of base_class, rerun: true, final_children_only: final_children_only, &block
65
+ skip_classes = run[:skip_classes]
66
+ for_children_of base_class, rerun: true, final_children_only: final_children_only, skip_classes: skip_classes, &block
65
67
  end
66
68
  end
67
69
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DSLCompose
4
- VERSION = "2.14.3"
4
+ VERSION = "2.15.1"
5
5
  end
data/lib/dsl_compose.rb CHANGED
@@ -42,7 +42,7 @@ require "dsl_compose/interpreter"
42
42
 
43
43
  require "dsl_compose/parser/for_children_of_parser/for_dsl_parser/for_method_parser"
44
44
  require "dsl_compose/parser/for_children_of_parser/for_dsl_parser"
45
- require "dsl_compose/parser/for_children_of_parser/descendents"
45
+ require "dsl_compose/parser/for_children_of_parser/descendants"
46
46
  require "dsl_compose/parser/for_children_of_parser"
47
47
  require "dsl_compose/parser/block_arguments"
48
48
  require "dsl_compose/parser"
@@ -11,6 +11,7 @@ module DSLCompose
11
11
  attr_reader required: bool
12
12
  attr_reader kwarg: bool
13
13
  attr_reader array: bool
14
+ attr_reader default: untyped
14
15
  attr_reader description: String
15
16
 
16
17
  attr_reader greater_than_validation: GreaterThanValidation
@@ -28,7 +29,7 @@ module DSLCompose
28
29
  attr_reader length_validation: LengthValidation
29
30
  attr_reader is_a_validation: IsAValidation
30
31
 
31
- def initialize: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool) -> void
32
+ def initialize: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool, ?default: untyped) -> void
32
33
  def set_description: (String description) -> void
33
34
  def has_description?: () -> bool
34
35
  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, bool kwarg, argument_type `type`, ?array: bool) -> Argument
15
+ def add_argument: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool, ?default: untyped) -> Argument
16
16
 
17
17
  class ArgumentDoesNotExistError < StandardError
18
18
  end
@@ -13,7 +13,7 @@ module DSLCompose
13
13
  def title: (String title) -> void
14
14
  def add_method: (Symbol name, ?required: nil) -> void
15
15
  def add_unique_method: (Symbol name, ?required: nil) -> void
16
- def optional: (Symbol name, argument_type `type`, ?array: bool) -> void
16
+ def optional: (Symbol name, argument_type `type`, ?array: bool, ?default: untyped) -> void
17
17
  def requires: (Symbol name, argument_type `type`, ?kwarg: bool, ?array: bool) -> void
18
18
  end
19
19
  end
@@ -2,15 +2,16 @@
2
2
  module DSLCompose
3
3
  class Parser
4
4
  class ForChildrenOfParser
5
- class Descendents
5
+ class Descendants
6
6
  @base_class: singleton(Object)
7
+ @skip_classes: Array[String]
7
8
  @final_children_only: bool
8
9
 
9
- def initialize: (singleton(Object) base_class, bool final_children_only) -> void
10
+ def initialize: (singleton(Object) base_class, bool final_children_only, ?Array[String] skip_classes) -> void
10
11
  def classes: -> Array[singleton(Object)]
11
12
 
12
13
  private
13
- def has_descendents: (singleton(Object) base_class) -> bool
14
+ def has_descendants: (singleton(Object) base_class) -> bool
14
15
  end
15
16
  end
16
17
  end
@@ -5,7 +5,7 @@ module DSLCompose
5
5
  @base_class: singleton(Object)
6
6
  @child_class: singleton(Object)
7
7
 
8
- def initialize: (singleton(Object) base_class, bool final_children_only) -> void
8
+ def initialize: (singleton(Object) base_class, bool final_children_only, ?Array[String] skip_classes) -> void
9
9
 
10
10
  # overriding this method because steep doesn't
11
11
  # correctly infer that a block is being passed to this method
@@ -4,7 +4,8 @@ module DSLCompose
4
4
  self.@runs: untyped
5
5
 
6
6
  def initialize: -> void
7
- def self.for_children_of: (singleton(Object) base_class, ?final_children_only: bool, ?rerun: bool) -> void
7
+ def self.for_children_of: (singleton(Object) base_class, ?final_children_only: bool, ?skip_classes: Array[String], ?rerun: bool) -> void
8
+ def self.for_final_children_of: (singleton(Object) base_class, ?skip_classes: Array[String]) -> void
8
9
 
9
10
  class NotInitializable < StandardError
10
11
  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.14.3
4
+ version: 2.15.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-27 00:00:00.000000000 Z
11
+ date: 2023-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: class_spec_helper
@@ -70,7 +70,7 @@ files:
70
70
  - lib/dsl_compose/parser.rb
71
71
  - lib/dsl_compose/parser/block_arguments.rb
72
72
  - lib/dsl_compose/parser/for_children_of_parser.rb
73
- - lib/dsl_compose/parser/for_children_of_parser/descendents.rb
73
+ - lib/dsl_compose/parser/for_children_of_parser/descendants.rb
74
74
  - lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser.rb
75
75
  - lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser/for_method_parser.rb
76
76
  - lib/dsl_compose/reader.rb
@@ -112,7 +112,7 @@ files:
112
112
  - sig/dsl_compose/parser.rbs
113
113
  - sig/dsl_compose/parser/block_arguments.rbs
114
114
  - sig/dsl_compose/parser/for_children_of_parser.rbs
115
- - sig/dsl_compose/parser/for_children_of_parser/descendents.rbs
115
+ - sig/dsl_compose/parser/for_children_of_parser/descendants.rbs
116
116
  - sig/dsl_compose/parser/for_children_of_parser/for_dsl_parser.rbs
117
117
  - sig/dsl_compose/parser/for_children_of_parser/for_dsl_parser/for_method_parser.rbs
118
118
  - sig/dsl_compose/reader.rbs