dsl_compose 2.1.0 → 2.2.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 +14 -0
- data/README.md +106 -8
- data/lib/dsl_compose/reader/execution_reader.rb +2 -0
- data/lib/dsl_compose/reader.rb +40 -4
- data/lib/dsl_compose/reader_base.rb +64 -0
- data/lib/dsl_compose/version.rb +1 -1
- data/lib/dsl_compose.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 409bc8ce86ea967b4a22f675ea029b609a9bb925d8b35255dd4f0a010049f115
|
4
|
+
data.tar.gz: e8d99aa8be417b6c670978dc5cf4461be8ca65dc4316b27ee840b63d82128738
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a57708bdfb09d3d35cfa3b3e6a76ffa931bcf71c34c14ece5b8737079f6660fefc9596ab5d079cfbf7fed3f733896212b60f81f23a02504dccbcd89a110e01c1
|
7
|
+
data.tar.gz: d87d67e5e6a1f22d49d0b8bb0642f97755f004684d8c0fa7ca1850ba3ce64e46dc016f3ab5fb21edd068e221734d2bae52c09e92f59135f94b0fabd7ac7d3356
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.2.0](https://github.com/craigulliott/dsl_compose/compare/v2.1.1...v2.2.0) (2023-07-27)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* Added a ReaderBase which can be extended to create custom reader classes. Also added dsl_used?, dsl_used_on_ancestors? and dsl_used_on_class_or_ancestors? helper methods to the Reader class ([6507e4a](https://github.com/craigulliott/dsl_compose/commit/6507e4a082c9a0d7e63c580a17bcb8eb2bd940ea))
|
9
|
+
|
10
|
+
## [2.1.1](https://github.com/craigulliott/dsl_compose/compare/v2.1.0...v2.1.1) (2023-07-26)
|
11
|
+
|
12
|
+
|
13
|
+
### Bug Fixes
|
14
|
+
|
15
|
+
* fixed bug where Execution classes were being returned from within the Reader but ExecutionReader classes were expected ([#56](https://github.com/craigulliott/dsl_compose/issues/56)) ([546cdaf](https://github.com/craigulliott/dsl_compose/commit/546cdaf323f3fc3be6ad09a47e5f99c3a59a50e2))
|
16
|
+
|
3
17
|
## [2.1.0](https://github.com/craigulliott/dsl_compose/compare/v2.0.1...v2.1.0) (2023-07-24)
|
4
18
|
|
5
19
|
|
data/README.md
CHANGED
@@ -168,7 +168,7 @@ You can use `import_shared` anywhere within your DSL definition, you can even us
|
|
168
168
|
Child classes can then use your new DSL
|
169
169
|
|
170
170
|
```ruby
|
171
|
-
class Bar
|
171
|
+
class Bar < Foo
|
172
172
|
|
173
173
|
your_dsl :first_dsl_argument, do
|
174
174
|
your_method "first_method_argument", optional_argument: 123
|
@@ -239,7 +239,7 @@ A parser class can be used to process complicated DSLs. In the example below, a
|
|
239
239
|
|
240
240
|
```ruby
|
241
241
|
# create your own parser by creating a new class which extends DSLCompose::Parser
|
242
|
-
MyParser < DSLCompose::Parser
|
242
|
+
class MyParser < DSLCompose::Parser
|
243
243
|
# `for_children_of` will process SomeBaseClass and yield the provided
|
244
244
|
# block once for every class which extends SomeBaseClass.
|
245
245
|
#
|
@@ -312,7 +312,7 @@ MyParser < DSLCompose::Parser
|
|
312
312
|
end
|
313
313
|
```
|
314
314
|
|
315
|
-
In addition to parser classes (or as a useful tool within parser classes) you can access the results of DSL execution
|
315
|
+
In addition to parser classes (or as a useful tool within parser classes) you can access the results of DSL execution with a Reader class.
|
316
316
|
|
317
317
|
```ruby
|
318
318
|
# Create a new Reader object.
|
@@ -339,10 +339,6 @@ reader = DSLCompose::Reader.new MyClass, :my_dsl
|
|
339
339
|
# If no execution of the DSL is found, then nil will be returned
|
340
340
|
execution = reader.last_execution
|
341
341
|
|
342
|
-
# `execution.arguments` returns an ArgumentsReader object which allows access
|
343
|
-
# via dot notation to to any argument values provided to the DSL
|
344
|
-
execution.arguments.my_dsl_argument # returns the value provided for the argument, or nil
|
345
|
-
|
346
342
|
# `execution.method_called?` will return true if the method with the provided
|
347
343
|
# name was called, if a method with this name does exist, but was not called
|
348
344
|
# then false will be returned. If a method with this name does not exist, then
|
@@ -372,7 +368,9 @@ execution.my_dsl_method.each do |arguments|
|
|
372
368
|
end
|
373
369
|
|
374
370
|
# Returns an array of ExecutionReaders to represent each time the DSL was used
|
375
|
-
# on
|
371
|
+
# on the provided class.
|
372
|
+
executions = reader.executions
|
373
|
+
|
376
374
|
# Returns an array of ExecutionReaders to represent each time the DSL was used
|
377
375
|
# on the ancestors of the provided class, but not on the provided class itself.
|
378
376
|
# The executions will be returned in the order they were executed, which is the
|
@@ -386,6 +384,106 @@ executions = reader.ancestor_executions
|
|
386
384
|
# and if the DSL was used more than once on a class then the order they were used.
|
387
385
|
executions = reader.all_executions
|
388
386
|
|
387
|
+
# Returns true if dsl has been executed once or more on the provided class,
|
388
|
+
# otherwise returns false.
|
389
|
+
was_used = reader.dsl_used?
|
390
|
+
|
391
|
+
# Returns true if dsl has been executed once or more on one of the ancestors
|
392
|
+
# of the provided class, otherwise returns false.
|
393
|
+
was_used = reader.dsl_used_on_ancestors?
|
394
|
+
|
395
|
+
# Returns true if dsl has been executed once or more on the provided class or
|
396
|
+
# any of its ancestors, otherwise returns false.
|
397
|
+
was_used = reader.dsl_used_on_class_or_ancestors?
|
398
|
+
|
399
|
+
# `execution.arguments` returns an ArgumentsReader object which allows access
|
400
|
+
# via dot notation to to any argument values provided to the DSL
|
401
|
+
execution.arguments.my_dsl_argument # returns the value provided for the argument, or nil
|
402
|
+
```
|
403
|
+
|
404
|
+
A ReaderBase class is also provided. You can extend this class to create your own Reader objects and provide a much cleaner interface to your specific DSLs.
|
405
|
+
|
406
|
+
```ruby
|
407
|
+
# This is an example DSL for configuring which database and schema should be used
|
408
|
+
# by classes which extend a BaseModel (it's from a hypothetical ORM).
|
409
|
+
class BaseModel
|
410
|
+
# define a DSL which can be used on descendants of this class
|
411
|
+
# to determine which database should be used
|
412
|
+
define_dsl :database_configuration do
|
413
|
+
requires :server_type, :symbol do
|
414
|
+
validate_in [:postgres, :mysql]
|
415
|
+
end
|
416
|
+
requires :server_name, :symbol
|
417
|
+
optional :database_name, :symbol
|
418
|
+
end
|
419
|
+
# define a DSL to set the schema which should be used
|
420
|
+
define_dsl :schema do
|
421
|
+
requires :schema_name, :symbol
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
# A hypothetical model which extends BaseModel and uses this DSL
|
426
|
+
class User < BaseModel
|
427
|
+
# Use the primary postgres server and the default database_name (because
|
428
|
+
# we are not using the optional `database_name: :foo` argument).
|
429
|
+
database_configuration :postgres, :primary
|
430
|
+
# Persist this models data in the `users` schema.
|
431
|
+
schema :users
|
432
|
+
end
|
433
|
+
|
434
|
+
# An example reader which could be created to provide a more concise
|
435
|
+
# interface to this DSL.
|
436
|
+
# Because this DSL Reader is named DatabaseConfigurationDSLReader it
|
437
|
+
# will automatically refer to the dsl named :database_configuration.
|
438
|
+
class DatabaseConfigurationDSLReader < DSLCompose::ReaderBase
|
439
|
+
# The three methods below provide a more concise access to the DSLs
|
440
|
+
# arguments. If the DSL was never used on the provided class, or any
|
441
|
+
# of it's ancestors, then an error will be raised. This error will
|
442
|
+
# be raised because we are using `last_execution!` instead of `last_execution`.
|
443
|
+
def server_type
|
444
|
+
last_execution!.arguments.server_type
|
445
|
+
end
|
446
|
+
|
447
|
+
def server_name
|
448
|
+
last_execution!.arguments.server_name
|
449
|
+
end
|
450
|
+
|
451
|
+
def database_name
|
452
|
+
last_execution!.arguments.database_name
|
453
|
+
end
|
454
|
+
|
455
|
+
# Returns true or false, depending on if the optional database_name
|
456
|
+
# attribute was used when executing the DSL. If the DSL was never
|
457
|
+
# used on the provided class, or any of it's ancestors, then an error will
|
458
|
+
# be raised (because of the bang method).
|
459
|
+
def has_database_name?
|
460
|
+
last_execution!.arguments.database_name != nil
|
461
|
+
end
|
462
|
+
|
463
|
+
# This method is provided as an example of how to reference other DSLs within
|
464
|
+
# your reader.
|
465
|
+
def schema_name
|
466
|
+
last_execution_of_schema&.arguments&.schema_name || :public
|
467
|
+
end
|
468
|
+
|
469
|
+
private
|
470
|
+
|
471
|
+
# This method is used by the schema_name method above, and is included as an
|
472
|
+
# example of how to reference other DSLs within your Reader.
|
473
|
+
def last_execution_of_schema
|
474
|
+
# Note that there is no bang method here (no "!" after last_execution), so it
|
475
|
+
# will return nil if the DSL was not used.
|
476
|
+
@schema_reader ||= DSLCompose::Reader.new(@base_class, :schema).last_execution
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
# Use our DatabaseConfigurationDSLReader when parsing this class to
|
481
|
+
# enjoy a more concise API for accessing our DSL values
|
482
|
+
reader = DatabaseConfigurationDSLReader.new(User)
|
483
|
+
reader.server_type # :postgres
|
484
|
+
reader.has_database_name? # false
|
485
|
+
reader.schema_name # :users
|
486
|
+
|
389
487
|
```
|
390
488
|
|
391
489
|
|
data/lib/dsl_compose/reader.rb
CHANGED
@@ -11,6 +11,9 @@ module DSLCompose
|
|
11
11
|
class DSLNotFound < StandardError
|
12
12
|
end
|
13
13
|
|
14
|
+
class NoDSLExecutionFound < StandardError
|
15
|
+
end
|
16
|
+
|
14
17
|
# given a class and the DSL name, finds and creates a reference to the DSL
|
15
18
|
# and the ancestor class where the DSL was originally defined
|
16
19
|
def initialize klass, dsl_name
|
@@ -42,6 +45,24 @@ module DSLCompose
|
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
48
|
+
# Returns true if dsl has been executed once or more on the provided class,
|
49
|
+
# otherwise returns false.
|
50
|
+
def dsl_used?
|
51
|
+
executions.any?
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns true if dsl has been executed once or more on one of the ancestors
|
55
|
+
# of the provided class, otherwise returns false.
|
56
|
+
def dsl_used_on_ancestors?
|
57
|
+
ancestor_executions.any?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns true if dsl has been executed once or more on the provided class or
|
61
|
+
# any of its ancestors, otherwise returns false.
|
62
|
+
def dsl_used_on_class_or_ancestors?
|
63
|
+
all_executions.any?
|
64
|
+
end
|
65
|
+
|
45
66
|
# Returns an ExecutionReader class which exposes a simple API to access the
|
46
67
|
# arguments, methods and method arguments provided when using this DSL.
|
47
68
|
#
|
@@ -51,13 +72,24 @@ module DSLCompose
|
|
51
72
|
# and look for the last time it was executed on each ancestor.
|
52
73
|
# If no execution of the DSL is found, then nil will be returned
|
53
74
|
def last_execution
|
54
|
-
@dsl_defining_class.dsls.get_last_dsl_execution
|
75
|
+
ExecutionReader.new(@dsl_defining_class.dsls.get_last_dsl_execution(@klass, @dsl_name))
|
76
|
+
end
|
77
|
+
|
78
|
+
# A wrapper for last_execution which raises an error if no execution exists
|
79
|
+
def last_execution!
|
80
|
+
execution = @dsl_defining_class.dsls.get_last_dsl_execution(@klass, @dsl_name)
|
81
|
+
if execution.nil?
|
82
|
+
raise NoDSLExecutionFound, "No execution of the `#{@dsl_name}` dsl was found on `#{@klass}` or any of its ancestors"
|
83
|
+
end
|
84
|
+
ExecutionReader.new execution
|
55
85
|
end
|
56
86
|
|
57
87
|
# Returns an array of ExecutionReaders to represent each time the DSL was used
|
58
88
|
# on the provided class.
|
59
89
|
def executions
|
60
|
-
@dsl_defining_class.dsls.class_dsl_executions
|
90
|
+
@dsl_defining_class.dsls.class_dsl_executions(@klass, @dsl_name, true, false).map do |execution|
|
91
|
+
ExecutionReader.new execution
|
92
|
+
end
|
61
93
|
end
|
62
94
|
|
63
95
|
# Returns an array of ExecutionReaders to represent each time the DSL was used
|
@@ -66,7 +98,9 @@ module DSLCompose
|
|
66
98
|
# earliest ancestor first and if the DSL was used more than once on a class then
|
67
99
|
# the order they were used.
|
68
100
|
def ancestor_executions
|
69
|
-
@dsl_defining_class.dsls.class_dsl_executions
|
101
|
+
@dsl_defining_class.dsls.class_dsl_executions(@klass, @dsl_name, false, true).map do |execution|
|
102
|
+
ExecutionReader.new execution
|
103
|
+
end
|
70
104
|
end
|
71
105
|
|
72
106
|
# Returns an array of ExecutionReaders to represent each time the DSL was used
|
@@ -74,7 +108,9 @@ module DSLCompose
|
|
74
108
|
# be returned in the order they were executed, which is the earliest ancestor first
|
75
109
|
# and if the DSL was used more than once on a class then the order they were used.
|
76
110
|
def all_executions
|
77
|
-
@dsl_defining_class.dsls.class_dsl_executions
|
111
|
+
@dsl_defining_class.dsls.class_dsl_executions(@klass, @dsl_name, true, true).map do |execution|
|
112
|
+
ExecutionReader.new execution
|
113
|
+
end
|
78
114
|
end
|
79
115
|
end
|
80
116
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module DSLCompose
|
2
|
+
# This class provides a skeleton for creating your own DSL readers.
|
3
|
+
#
|
4
|
+
# All classes which extend from this base class must follow a strict naming convention. The class name
|
5
|
+
# must be the camelcased form of the DSL name, followed by the string "DSLReader". For example, a reader
|
6
|
+
# for a DLS named `:foo_bar` must have the class name `FooBarDSLReader`, as seen below
|
7
|
+
#
|
8
|
+
# class FooBarDSLReader < DSLCompose::ReaderBase
|
9
|
+
# # ...
|
10
|
+
# end
|
11
|
+
class ReaderBase
|
12
|
+
attr_reader :base_class
|
13
|
+
attr_reader :dsl_name
|
14
|
+
attr_reader :reader
|
15
|
+
|
16
|
+
def initialize base_class
|
17
|
+
@base_class = base_class
|
18
|
+
# get the DSL name from the class name
|
19
|
+
@dsl_name = dsl_name_from_class_name self.class
|
20
|
+
# create the reader
|
21
|
+
@reader = DSLCompose::Reader.new(base_class, @dsl_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def dsl_name_from_class_name reader_class
|
27
|
+
camelcased = reader_class.name.split("::").last.gsub(/DSLReader\Z/, "")
|
28
|
+
underscored = camelcased.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
29
|
+
underscored.downcase.to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
def dsl_used?
|
33
|
+
@reader.dsl_used?
|
34
|
+
end
|
35
|
+
|
36
|
+
def dsl_used_on_ancestors?
|
37
|
+
@reader.dsl_used_on_ancestors?
|
38
|
+
end
|
39
|
+
|
40
|
+
def dsl_used_on_class_or_ancestors?
|
41
|
+
@reader.dsl_used_on_class_or_ancestors?
|
42
|
+
end
|
43
|
+
|
44
|
+
def last_execution
|
45
|
+
@reader.last_execution
|
46
|
+
end
|
47
|
+
|
48
|
+
def last_execution!
|
49
|
+
@reader.last_execution!
|
50
|
+
end
|
51
|
+
|
52
|
+
def executions
|
53
|
+
@reader.executions
|
54
|
+
end
|
55
|
+
|
56
|
+
def ancestor_executions
|
57
|
+
@reader.ancestor_executions
|
58
|
+
end
|
59
|
+
|
60
|
+
def all_executions
|
61
|
+
@reader.all_executions
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/dsl_compose/version.rb
CHANGED
data/lib/dsl_compose.rb
CHANGED
@@ -32,6 +32,8 @@ require "dsl_compose/reader"
|
|
32
32
|
require "dsl_compose/reader/execution_reader"
|
33
33
|
require "dsl_compose/reader/execution_reader/arguments_reader"
|
34
34
|
|
35
|
+
require "dsl_compose/reader_base"
|
36
|
+
|
35
37
|
require "dsl_compose/interpreter/execution/method_calls/method_call"
|
36
38
|
require "dsl_compose/interpreter/execution/method_calls"
|
37
39
|
require "dsl_compose/interpreter/execution/arguments"
|
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.2.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-07-
|
11
|
+
date: 2023-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: class_spec_helper
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- lib/dsl_compose/reader.rb
|
78
78
|
- lib/dsl_compose/reader/execution_reader.rb
|
79
79
|
- lib/dsl_compose/reader/execution_reader/arguments_reader.rb
|
80
|
+
- lib/dsl_compose/reader_base.rb
|
80
81
|
- lib/dsl_compose/shared_configuration.rb
|
81
82
|
- lib/dsl_compose/version.rb
|
82
83
|
homepage:
|