dsl_maker 0.0.3 → 0.0.4
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/Changes +6 -0
- data/README.md +37 -11
- data/Rakefile +6 -1
- data/dsl_maker.gemspec +1 -0
- data/lib/dsl/maker/version.rb +1 -1
- data/lib/dsl/maker.rb +12 -0
- data/spec/error_spec.rb +25 -0
- data/spec/helper_spec.rb +63 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff32adb37883c0c6466af73eac18c78e0315cffd
|
4
|
+
data.tar.gz: ebaaa08053e1c7d1a3066c3a3ec18cebf685a10b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 237aef00aa5afa13e8d5cd39a72ee339e43de1988426305f1af0183b15a242d971de0a3398bae3a5817f1a2cc9f96a8c64fb36888b6617571b5f7c656757c8f6
|
7
|
+
data.tar.gz: 3274e9f900246bac32bc9dbec107e2120544d8241a4109857b79ae4a2d33ec147dd69a832d00392a351a95af015f4f3756110641a6855e3ebe2f98b5c3d05247
|
data/Changes
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
Revision history for DSL::Maker (ordered by revision number).
|
2
2
|
|
3
|
+
0.0.4 Jul 29 2015
|
4
|
+
- Added add_helper() to allow the user to define new helper methods for use
|
5
|
+
within the DSL.
|
6
|
+
- Added missing documentation in README for new features in 0.0.3
|
7
|
+
- Added TODO list in documentation
|
8
|
+
|
3
9
|
0.0.3 Jul 28 2015
|
4
10
|
- Added entrypoint() that returns the DSL implementing an entrypoint
|
5
11
|
- Several refactorings to improve maintainability:
|
data/README.md
CHANGED
@@ -9,7 +9,6 @@
|
|
9
9
|
[](https://codecov.io/github/robkinyon/ruby-dsl-maker)
|
10
10
|
[](http://inch-ci.org/github/robkinyon/ruby-dsl-maker)
|
11
11
|
|
12
|
-
|
13
12
|
Writing single-level Ruby-like DSLs is really easy. Ruby practically builds them
|
14
13
|
for you with a little meta-programming. [Docile](https://github.com/ms-ati/docile)
|
15
14
|
makes it ridiculously easy and there are nearly a dozen other modules to do so.
|
@@ -55,9 +54,6 @@ class PizzaBuilder
|
|
55
54
|
Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce)
|
56
55
|
end
|
57
56
|
end
|
58
|
-
|
59
|
-
PizzaBuilder.new.cheese.pepperoni.sauce(:extra).build
|
60
|
-
#=> #<Pizza:0x00001009dc398 @cheese=true, @pepperoni=true, @bacon=false, @sauce=:extra>
|
61
57
|
```
|
62
58
|
|
63
59
|
But, this doesn't actually implement the DSL. That is left for another snippet:
|
@@ -85,7 +81,14 @@ class PizzaBuilder < DSL::Maker
|
|
85
81
|
end
|
86
82
|
end
|
87
83
|
|
88
|
-
pizza = PizzaBuilder.parse_dsl(
|
84
|
+
pizza = PizzaBuilder.parse_dsl("
|
85
|
+
pizza {
|
86
|
+
cheese yes
|
87
|
+
pepperoni Yes
|
88
|
+
bacon On
|
89
|
+
sauce 'extra'
|
90
|
+
}
|
91
|
+
")
|
89
92
|
```
|
90
93
|
|
91
94
|
Now, you accept the strings (possibly from `IO.read()`) and magically get the
|
@@ -132,7 +135,7 @@ john_smith = FamilyTree.parse_dsl("
|
|
132
135
|
")
|
133
136
|
```
|
134
137
|
|
135
|
-
|
138
|
+
Pretty easy. We can even refactor that a bit and end up with:
|
136
139
|
|
137
140
|
```ruby
|
138
141
|
class FamilyTree < DSL::Maker
|
@@ -268,7 +271,7 @@ you get back an `Array` with everything in the right order.
|
|
268
271
|
|
269
272
|
### Class Methods
|
270
273
|
|
271
|
-
DSL::Maker provides
|
274
|
+
DSL::Maker provides seven class methods - five for constructing your DSL and two
|
272
275
|
for parsing your DSL.
|
273
276
|
|
274
277
|
* `add_entrypoint(Symbol, Hash={}, Block)`
|
@@ -278,6 +281,13 @@ level of your DSL. `add_entrypoint()` will create the right class methods for
|
|
278
281
|
Docile to use when `parse_dsl()` is called. It will also invoke `generate_dsl()`
|
279
282
|
with the Hash you give it to create the parsing.
|
280
283
|
|
284
|
+
* `entrypoint(Symbol)`
|
285
|
+
|
286
|
+
This returns the DSL defined by a previous call to `add_entrypoint()`.
|
287
|
+
|
288
|
+
This is primarily useful if you want to take a DSL class and use it within another
|
289
|
+
DSL class.
|
290
|
+
|
281
291
|
* `generate_dsl(Hash={}, Block)`
|
282
292
|
|
283
293
|
This is used in defining your DSL to describe the innards - the guts that actually
|
@@ -290,14 +300,21 @@ This is normally called by `generate_dsl()` to actually construct the DSL elemen
|
|
290
300
|
It is provided for you so that you can create recursive DSL definitions. Look at
|
291
301
|
the tests in `spec/multi_level_spec.rb` for an example of this.
|
292
302
|
|
303
|
+
* `add_helper(Symbol, Block)`
|
304
|
+
|
305
|
+
This is used to create helper methods (similar to `default`, described below) that
|
306
|
+
are used within the DSL.
|
307
|
+
|
308
|
+
This creates global helpers that are available at every level of your DSLs.
|
309
|
+
|
293
310
|
* `parse_dsl(String)` / `execute_dsl(&block)`
|
294
311
|
|
295
312
|
You call this on your DSL class when you're ready to invoke your DSL. It will
|
296
|
-
return whatever the block provided `add_entrypoint()` returns.
|
313
|
+
return whatever the block provided to `add_entrypoint()` returns.
|
297
314
|
|
298
315
|
In the case of multiple DSL entrypoints (for example, a normal Chef recipe),
|
299
|
-
these methods will return an array with all the return values in the order
|
300
|
-
|
316
|
+
these methods will return an array with all the return values in the order they
|
317
|
+
were encountered.
|
301
318
|
|
302
319
|
### Coercions
|
303
320
|
|
@@ -313,18 +330,27 @@ You will be able to add your own coercions in a forthcoming version of DSL::Make
|
|
313
330
|
|
314
331
|
There is one pre-defined helper.
|
315
332
|
|
316
|
-
* `default(String, Array, Integer=0)`
|
333
|
+
* `default(String, Array, Integer=0)`
|
317
334
|
|
318
335
|
This takes a method name and the args provided to the block. It then ensures that
|
319
336
|
the method defaults to the value in the args at the optional third argument.
|
320
337
|
|
338
|
+
You can add additional helpers using `add_helper()` described above.
|
339
|
+
|
321
340
|
## Installation
|
322
341
|
|
323
342
|
``` bash
|
324
343
|
$ gem install dsl_maker
|
325
344
|
```
|
326
345
|
|
346
|
+
## TODO
|
347
|
+
|
348
|
+
* Add support for Arrays
|
349
|
+
* Add additional coercions (e.g., Number)
|
350
|
+
* Allow you to add your own coercions
|
351
|
+
|
327
352
|
## Links
|
353
|
+
|
328
354
|
* [Source](https://github.com/robkinyon/ruby-dsl-maker)
|
329
355
|
* [Documentation](http://rubydoc.info/gems/ruby-dsl-maker)
|
330
356
|
* [Bug Tracker](https://github.com/robkinyon/ruby-dsl-maker/issues)
|
data/Rakefile
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'rake/clean'
|
2
2
|
require 'bundler/gem_tasks'
|
3
|
+
require 'rubygems/tasks'
|
3
4
|
require 'rspec/core/rake_task'
|
4
5
|
|
5
6
|
# This is used by the Yardoc stuff in docile's Rakefile. We're not there yet.
|
6
|
-
|
7
|
+
require File.expand_path('on_what', File.dirname(__FILE__))
|
7
8
|
|
8
9
|
# Default task for `rake` is to run rspec
|
9
10
|
task :default => [:spec]
|
@@ -14,6 +15,10 @@ RSpec::Core::RakeTask.new
|
|
14
15
|
# Configure `rake clobber` to delete all generated files
|
15
16
|
CLOBBER.include('pkg', 'doc', 'coverage', '*.gem')
|
16
17
|
|
18
|
+
# Add the gem tasks:
|
19
|
+
# :build, :console, :install, :release
|
20
|
+
Gem::Tasks.new
|
21
|
+
|
17
22
|
if !on_travis? && !on_jruby? && !on_1_8?
|
18
23
|
require 'github/markup'
|
19
24
|
require 'redcarpet'
|
data/dsl_maker.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_development_dependency 'rake', '~> 10'
|
26
26
|
s.add_development_dependency 'rspec', '~> 3.0.0', '>= 3.0.0'
|
27
27
|
s.add_development_dependency 'simplecov', '~> 0'
|
28
|
+
s.add_development_dependency 'rubygems-tasks', '~> 0'
|
28
29
|
|
29
30
|
# To limit needed compatibility with versions of dependencies, only configure
|
30
31
|
# yard doc generation when *not* on Travis, JRuby, or 1.8
|
data/lib/dsl/maker/version.rb
CHANGED
data/lib/dsl/maker.rb
CHANGED
@@ -253,4 +253,16 @@ class DSL::Maker
|
|
253
253
|
|
254
254
|
return @entrypoints[name.to_sym]
|
255
255
|
end
|
256
|
+
|
257
|
+
def self.add_helper(name, &block)
|
258
|
+
raise "Block required for add_helper" unless block_given?
|
259
|
+
|
260
|
+
if DSL::Maker::Base.new.respond_to? name.to_sym
|
261
|
+
raise "'#{name.to_s}' is already a helper"
|
262
|
+
end
|
263
|
+
|
264
|
+
DSL::Maker::Base.class_eval do
|
265
|
+
define_method(name.to_sym, &block)
|
266
|
+
end
|
267
|
+
end
|
256
268
|
end
|
data/spec/error_spec.rb
CHANGED
@@ -61,4 +61,29 @@ describe "DSL::Maker validation" do
|
|
61
61
|
dsl_class.entrypoint(:x)
|
62
62
|
}.to raise_error("'x' is not an entrypoint")
|
63
63
|
end
|
64
|
+
|
65
|
+
it "rejects a helper without a block" do
|
66
|
+
dsl_class = Class.new(DSL::Maker)
|
67
|
+
|
68
|
+
expect {
|
69
|
+
dsl_class.add_helper(:x)
|
70
|
+
}.to raise_error('Block required for add_helper')
|
71
|
+
end
|
72
|
+
|
73
|
+
it "rejects the helper name default" do
|
74
|
+
dsl_class = Class.new(DSL::Maker)
|
75
|
+
|
76
|
+
expect {
|
77
|
+
dsl_class.add_helper(:default) {}
|
78
|
+
}.to raise_error("'default' is already a helper")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "rejects a helper name already in use" do
|
82
|
+
dsl_class = Class.new(DSL::Maker)
|
83
|
+
dsl_class.add_helper(:x) {}
|
84
|
+
|
85
|
+
expect {
|
86
|
+
dsl_class.add_helper(:x) {}
|
87
|
+
}.to raise_error("'x' is already a helper")
|
88
|
+
end
|
64
89
|
end
|
data/spec/helper_spec.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# This uses a DSL that also provides a set of useful helpers.
|
2
|
+
#
|
3
|
+
describe "A DSL with helpers" do
|
4
|
+
$Car = Struct.new(:maker, :wheel)
|
5
|
+
$Wheel = Struct.new(:maker, :size)
|
6
|
+
|
7
|
+
it "can add a helper that's useful" do
|
8
|
+
dsl_class = Class.new(DSL::Maker) do
|
9
|
+
add_entrypoint(:car, {
|
10
|
+
:maker => String,
|
11
|
+
}) do
|
12
|
+
$Car.new(maker)
|
13
|
+
end
|
14
|
+
|
15
|
+
add_helper(:transform) do |name|
|
16
|
+
name.upcase
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
car = dsl_class.parse_dsl("
|
21
|
+
car {
|
22
|
+
maker transform('Honda')
|
23
|
+
}
|
24
|
+
")
|
25
|
+
expect(car).to be_instance_of($Car)
|
26
|
+
expect(car.maker).to eq('HONDA')
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO: There is a wart here. We cannot call add_helper() twice in our tests
|
30
|
+
# for the same name even in different specs. The specs should be able to reset
|
31
|
+
# the class, but I'm not sure how.
|
32
|
+
it "adds the helper to every level" do
|
33
|
+
dsl_class = Class.new(DSL::Maker) do
|
34
|
+
add_entrypoint(:car, {
|
35
|
+
:maker => String,
|
36
|
+
:wheel => generate_dsl({
|
37
|
+
:maker => String,
|
38
|
+
}) do
|
39
|
+
$Wheel.new(maker)
|
40
|
+
end
|
41
|
+
}) do
|
42
|
+
$Car.new(maker, wheel)
|
43
|
+
end
|
44
|
+
|
45
|
+
add_helper(:transform2) do |name|
|
46
|
+
name.upcase
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
car = dsl_class.parse_dsl("
|
51
|
+
car {
|
52
|
+
maker 'Honda'
|
53
|
+
wheel {
|
54
|
+
maker transform2('goodyear')
|
55
|
+
}
|
56
|
+
}
|
57
|
+
")
|
58
|
+
expect(car).to be_instance_of($Car)
|
59
|
+
expect(car.maker).to eq('Honda')
|
60
|
+
expect(car.wheel).to be_instance_of($Wheel)
|
61
|
+
expect(car.wheel.maker).to eq('GOODYEAR')
|
62
|
+
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dsl_maker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Kinyon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docile
|
@@ -78,6 +78,20 @@ dependencies:
|
|
78
78
|
- - "~>"
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rubygems-tasks
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
81
95
|
- !ruby/object:Gem::Dependency
|
82
96
|
name: yard
|
83
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,6 +157,7 @@ files:
|
|
143
157
|
- spec/args_spec.rb
|
144
158
|
- spec/class_as_subdsl_spec.rb
|
145
159
|
- spec/error_spec.rb
|
160
|
+
- spec/helper_spec.rb
|
146
161
|
- spec/multi_level_spec.rb
|
147
162
|
- spec/multiple_invocation_spec.rb
|
148
163
|
- spec/single_level_spec.rb
|