dsl_factory 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9110073c0a21c89089537a09c4f21394b30fffa76aeaec2291c9918d58051479
4
+ data.tar.gz: 06d23515ae9d3a03da213d7e6642ffe19cb7deba898e05526af11131070e644b
5
+ SHA512:
6
+ metadata.gz: 37b94876fd1631ab2247da8688cf5d8ded60282bcd204bec006a3017d7e843015b926aceb4a9237a0c85dc9fdfaa4641a3256709e23950dae1f4fc5103f926f3
7
+ data.tar.gz: 2844d3bd1abd55906099d5a309276a8dfd180e10a7bfe6b48422c1a931f26cb79cdf8ac1b593e355e4851cfe809f6288463f183da8f029cf072b8aad0f7c1c16
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2022-03-01
4
+
5
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+ gemspec
4
+ gem "rake", "~> 13.0"
5
+ gem "minitest", "~> 5.0"
6
+ gem "pry"
data/Gemfile.lock ADDED
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dsl_factory (0.1.0)
5
+ activesupport (>= 5.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (7.0.2.2)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 1.6, < 2)
13
+ minitest (>= 5.1)
14
+ tzinfo (~> 2.0)
15
+ coderay (1.1.3)
16
+ concurrent-ruby (1.1.9)
17
+ i18n (1.10.0)
18
+ concurrent-ruby (~> 1.0)
19
+ method_source (1.0.0)
20
+ minitest (5.15.0)
21
+ pry (0.14.1)
22
+ coderay (~> 1.1)
23
+ method_source (~> 1.0)
24
+ rake (13.0.6)
25
+ tzinfo (2.0.4)
26
+ concurrent-ruby (~> 1.0)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ dsl_factory!
33
+ minitest (~> 5.0)
34
+ pry
35
+ rake (~> 13.0)
36
+
37
+ BUNDLED WITH
38
+ 2.1.4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Tom Rothe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # DSL Factory
2
+
3
+ A small DSL to generate DSLs.
4
+ Define DSLs quickly and avoid the [boilerplate to write getters and setters](https://gist.github.com/motine/28da503ba0075e9d64d3f3b1faab9014). Oh, and it does validation too.
5
+
6
+ ## Example
7
+
8
+ ```ruby
9
+ # add this to your Gemfile: gem 'dsl_factory'
10
+
11
+ # define the DSL
12
+ LakeDsl = DslFactory.define_dsl do
13
+ string :lake_name
14
+ numeric :max_depth
15
+ array :fishes, String
16
+ end
17
+
18
+ # use it in any class
19
+ class LakeSuperior
20
+ extend LakeDsl
21
+
22
+ lake_name 'Lake Superior'
23
+ max_depth 406
24
+ fish 'trout'
25
+ fish 'northern pike'
26
+ end
27
+
28
+ # and you can access the values
29
+ LakeSuperior.lake_name # => "Lake Superior"
30
+ LakeSuperior.fishes # => ["trout", "northern pike"]
31
+ ```
32
+
33
+ This gem came about during my time at [Netskin GmbH](https://www.netskin.com). Check it out, we do great (Rails) work there.
34
+
35
+ # Usage
36
+
37
+ ## Definition
38
+
39
+ **Basic Types**
40
+
41
+ ```ruby
42
+ # the following data types are available
43
+ # if a value is given which does not fit the type a `DslFactory::ValidationError` is raised
44
+ LakeDsl = DslFactory.define_dsl do
45
+ string :lake_name
46
+ symbol :group
47
+ numeric :max_depth
48
+ boolean :protected_habitat
49
+ callable :current_temperature_handler
50
+ any :continent # does not validate the given contents later
51
+ end
52
+
53
+ # now we can use the definition
54
+ class LakeSuperior
55
+ extend LakeDsl
56
+
57
+ lake_name 'Lake Superior'
58
+ group :great_lakes
59
+ max_depth 406
60
+ protected_habitat true
61
+ current_temperature_handler ->() { self.temperature = FetchService.receive_temperature } # the proc is only saved, DslFactory will not call it
62
+ continent Continent::NorthAmerica
63
+ end
64
+ ```
65
+
66
+ **Arrays**
67
+
68
+ ```ruby
69
+ BookDsl = DslFactory.define_dsl do
70
+ array :authors # we must use the plural!
71
+ array :publishers, String # validates that the item is of the given (Ruby) class
72
+ # see below for nested DSLs
73
+ end
74
+
75
+ class SuperBook
76
+ extend BookDsl
77
+ authors ['Manfred', 'Dieter'] # we can use the plural form to set the whole array
78
+ author 'Heinz' # or the singular form to add an item
79
+
80
+ publisher 'abc'
81
+ end
82
+
83
+ SuperBook.authors # => ['Manfred', 'Dieter', 'Heinz']
84
+ SuperBook.publishers # => ['abc']
85
+ ```
86
+
87
+ **Hashes**
88
+
89
+ ```ruby
90
+ GeographyDsl = DslFactory.define_dsl do
91
+ hash :capital_for_countries # we must use the plural!
92
+ hash :country_sizes, String, Numeric # validate key and value (key must be of String class, value of Symbol)
93
+ # see below for nested DSLs
94
+ end
95
+
96
+ class World
97
+ extend GeographyDsl
98
+ capital_for_country 'Berlin', 'Germany' # here we use the signular
99
+ capital_for_country 'Copenhagen', 'Denmark'
100
+
101
+ country_size 'Germany', 357_022
102
+ end
103
+
104
+ SmartyPants.capital_for_countries # => { 'Berlin' => 'Germany', 'Copenhagen' => 'Denmark'}
105
+ SmartyPants.country_sizes # => { 'Germany' => 357022 }
106
+ ```
107
+
108
+ **Nested DSLs**
109
+ ```ruby
110
+ PersonDsl = DslFactory.define_dsl do
111
+ array :parents do
112
+ string :name
113
+ numeric :age
114
+ end
115
+
116
+ hash :citizenships, String do # validate key as String
117
+ symbol :status
118
+ any :expiry
119
+ end
120
+ end
121
+
122
+ class Sabine
123
+ extend PersonDsl
124
+ # note that nested DSLs can only be used via the singular form
125
+
126
+ parent do
127
+ name 'Karla'
128
+ age 88
129
+ end
130
+
131
+ citizenship 'Germany' do
132
+ status :revoked
133
+ expiry Time.new(2000)
134
+ end
135
+ end
136
+
137
+ Sabine.parents.first.name # => 'Karla'
138
+ Sabine.citizenships['Germany'].status # => :revoked
139
+ ```
140
+
141
+ **Callbacks**
142
+
143
+ Sometimes we might want to do something when the DSL method is called.
144
+ This can be achived via callbacks.
145
+
146
+ ```ruby
147
+ ButtonDsl = DslFactory.define_dsl do
148
+ # all types outlined above support callbacks
149
+ any :trigger, callback: ->(value) { puts "#{value} was triggered" }
150
+ any :snicker, callback: ->(value) { arg1, arg2 = value; puts "snicker: #{arg1} & #{arg2}" } # we can pass arguments via the value
151
+ any :clicker, callback: ->(value) { self.do_the_click }
152
+
153
+ # for arrays the callback always receives an array (even if it was used in singular form)
154
+ # for hashes the callback receives two arguments: key, value
155
+ end
156
+
157
+ class Sabine
158
+ extend ButtonDsl
159
+ # if we want to call a method of the class, we need to define it before the first usage of the DSL method
160
+ def self.do_the_click
161
+ puts 'Click!'
162
+ end
163
+
164
+ trigger 'abc' # -> abc was triggered
165
+ snicker ['haha', 'hihi'] # -> snicker: haha & hihi
166
+ clicker nil # make sure to alway pass a value, -> Click!
167
+ end
168
+ ```
169
+
170
+ ## Use of the definition
171
+
172
+ Usually we **extend a class** like so:
173
+
174
+ ```ruby
175
+ class LakeSuperior
176
+ extend LakeDsl
177
+ lake_name 'Lake Superior'
178
+ end
179
+
180
+ LakeSuperior.lake_name # => 'Lake Superior'
181
+ ```
182
+
183
+ However we can also the **DSL in a variable**:
184
+
185
+ ```ruby
186
+ @config = Module.new.extend(LakeDsl)
187
+ @config.lake_name 'Müritz'
188
+ @config.lake_name # => 'Müritz'
189
+
190
+ # or with the configuration pattern
191
+ @config = Module.new.extend(LakeDsl).tap do |c|
192
+ c.lake_name 'Summter See'
193
+ end
194
+ @config.lake_name # => 'Summter See'
195
+
196
+ # or even without any prefix
197
+ @config = Module.new.extend(LakeDsl)
198
+ @config.instance_exec do
199
+ lake_name 'Mühlenbecker See'
200
+ end
201
+ @config.lake_name # => 'Mühlenbecker See'
202
+
203
+ ```
204
+
205
+ # Development
206
+
207
+ ```bash
208
+ docker run --rm -ti -v (pwd):/app -w /app ruby:2.7 bash
209
+ bundle install
210
+ rake test # run the tests
211
+ pry # require_relative 'lib/dsl_factory.rb'
212
+
213
+ # to release a new version, update the version number in `version.rb`, then run
214
+ bundle exec rake release
215
+ ```
216
+
217
+ ## License
218
+
219
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
220
+
221
+ # Alternatives
222
+
223
+ _Download counts are from 01.03.2022._
224
+
225
+ - [dslh](https://github.com/kumogata/dslh) (178.000 downloads)
226
+ Allows to define a Hash as a DSL.
227
+ - [dsl_maker](https://rubygems.org/gems/dsl_maker) (80.700 downloads)
228
+ allows defining DSLs with structs.
229
+ - [genki-dsl_accessor](https://rubygems.org/gems/genki-dsl_accessor) (5.600 downloads)
230
+ allows defining hybrid accessors for class.
231
+ - [configuration_dsl](https://rubygems.org/gems/configuration_dsl) (4.100 downloads)
232
+ nice way to define configuration DSLs. quite outdated.
233
+ - [blockenspiel](https://github.com/dazuma/blockenspiel) (2.869.000 downloads)
234
+ allows to nicely define configuration blocks. does not facilitate assigning variables.
235
+ - [dsl_accessors](https://rubygems.org/gems/dsl_accessors) (3.700 downloads)
236
+ provides helpers to facilitate variable setting via DSL. exactly what we need, but unfortunately quite outdated.
237
+ - [open_dsl](https://rubygems.org/gems/open_dsl) (17.000 downloads)
238
+ dynamically defines OpenStructs to collect data for DSLs. really nice idea and quite close to what we need. unfortunately a little outdated.
239
+ - [alki-dsl](https://rubygems.org/gems/alki-dsl) (12.900 downloads)
240
+ allows to define DSL methods nicely. does not assist in variable getting/setting.
241
+
242
+ **Honerable Mentions**
243
+
244
+ - [cleanroom](https://rubygems.org/gems/cleanroom) (5.560.000 downloads)
245
+ allows to safely define DSLs. does not really facilitate the data assignments.
246
+ - [dsl_block](https://rubygems.org/gems/dsl_block) 4.900 downloads)
247
+ allows you to use classes to define blocks with commands. does not really facilitate setting/getting variables.
248
+ - [declarative](https://rubygems.org/gems/declarative) (110.990.000 downloads)
249
+ define declarative schemas.
250
+ - [dslkit](https://rubygems.org/gems/dslkit) (54.500 downloads)
251
+ allows defining DSL to be read from files (maybe). documentation hard to find. outdated.
252
+ - [dsltasks](https://rubygems.org/gems/dsltasks) (4.100 downloads)
253
+ allows to define hierarchical DSLs. does not facilitate variable assignments.
254
+ - [opendsl](https://rubygems.org/gems/opendsl) (8.800 downloads)
255
+ allows to simply define DSLs. does not help assigning variables. outdated.
256
+
257
+ **Not Applicable**
258
+
259
+ - [dsl](https://rubygems.org/gems/dsl) defines delegators. i am not sure when this is useful.
260
+ - [dsl_eval](https://rubygems.org/gems/dsl_eval) only defines an alias for instance_eval.
261
+ - [instant_dsl](https://rubygems.org/gems/instant_dsl) could not find repo/docs. quite outdated.
262
+ - [dsl_companion](https://rubygems.org/gems/dsl_companion) no documentation.
263
+ - [def_dsl](https://rubygems.org/gems/def_dsl) no documentation.
264
+ - [dslr](https://rubygems.org/gems/dslr) no documentation.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ end
11
+
12
+ task default: :test
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/dsl_factory/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "dsl_factory"
7
+ spec.version = DslFactory::VERSION
8
+ spec.authors = ["Tom Rothe"]
9
+ spec.email = ["info@tomrothe.de"]
10
+
11
+ spec.summary = "A small DSL to generate DSLs"
12
+ spec.description = "Define DSLs quickly and avoid the boilerplate write getters and setters. Oh, and it does validation too."
13
+ spec.homepage = "https://github.com/motine/dsl_factory"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+ spec.metadata["changelog_uri"] = 'https://github.com/motine/dsl_factory/blob/master/CHANGELOG.md'
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
25
+ end
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_dependency "activesupport", ">= 5.0"
29
+
30
+ # For more information and examples about making a new gem, checkout our
31
+ # guide at: https://bundler.io/guides/creating_gem.html
32
+ end
@@ -0,0 +1,120 @@
1
+ class DslFactory::Generator
2
+ attr_reader :definition
3
+
4
+ def initialize
5
+ @definition = Module.new do
6
+ def get_dsl_value(name)
7
+ @dsl_values ||= {}
8
+ @dsl_values[name]
9
+ end
10
+
11
+ def set_dsl_value(name, value, &block)
12
+ @dsl_values ||= {}
13
+ @dsl_values[name] = value
14
+ end
15
+ end
16
+ end
17
+
18
+ # for more information & examples, please see README.md
19
+ #
20
+ # if a `callback` is given it will be called when the extended class uses this attribute (after setting the value).
21
+ # the callback block will be called with the value as first parameter (if you need multiple parameter pass a list).
22
+ # for examples, please see `README.md``.
23
+ #
24
+ # if a validation is given the block will be called with the value as first parameter.
25
+ # if the block returns false a `DslFactory::ValidationError` will be raised.
26
+ def any(name, callback: nil, validation: nil)
27
+ @definition.define_method(name) do |value = :not_given, &block|
28
+ return get_dsl_value(name) if value == :not_given
29
+ raise DslFactory::ValidationError, "#{name} is not valid" if validation && !validation.call(value)
30
+ set_dsl_value(name, value)
31
+ self.instance_exec(value, &callback) if callback
32
+ end
33
+ end
34
+
35
+ # for more information & examples, please see README.md
36
+ def string(name, **kwargs)
37
+ any(name, validation: ->(value) { value.is_a?(String) }, **kwargs)
38
+ end
39
+
40
+ # for more information & examples, please see README.md
41
+ def symbol(name, **kwargs)
42
+ any(name, validation: ->(value) { value.is_a?(Symbol) }, **kwargs)
43
+ end
44
+
45
+ # for more information & examples, please see README.md
46
+ def numeric(name, **kwargs)
47
+ any(name, validation: ->(value) { value.is_a?(Numeric) }, **kwargs)
48
+ end
49
+
50
+ # for more information & examples, please see README.md
51
+ def boolean(name, **kwargs)
52
+ any(name, validation: ->(value) { value.is_a?(TrueClass) || value.is_a?(FalseClass) }, **kwargs)
53
+ end
54
+
55
+ # for more information & examples, please see README.md
56
+ def callable(name, **kwargs)
57
+ any(name, validation: ->(value) { value.respond_to?(:call) }, **kwargs)
58
+ end
59
+
60
+ # for more information & examples, please see README.md
61
+ def array(plural_name, item_class=nil, callback: nil, &definition_block)
62
+ singular_name = build_singular_name!(plural_name)
63
+ raise DslFactory::DefinitionError, "#{plural_name} item_class can not given at the same time as a block" if item_class && definition_block
64
+
65
+ any(plural_name, callback: callback, validation: ->(value) { value.is_a?(Array) && (item_class.nil? || value.all? { |item| item.is_a?(item_class) }) })
66
+
67
+ @definition.define_method(singular_name) do |value = :not_given, &block|
68
+ old_value = get_dsl_value(plural_name)
69
+ return old_value if value == :not_given && !block
70
+
71
+ if block # we deal with a sub-DSL
72
+ value_object = Class.new
73
+ value_object.extend(DslFactory.define_dsl(&definition_block))
74
+ value_object.instance_eval(&block)
75
+ value = value_object
76
+ end
77
+ raise DslFactory::ValidationError, "#{singular_name} is not valid" if item_class && !value.is_a?(item_class)
78
+ new_value = old_value || []
79
+ new_value << value
80
+ set_dsl_value(plural_name, new_value)
81
+ self.instance_exec([value], &callback) if callback # wrap the item in a list
82
+ end
83
+ end
84
+
85
+ # for more information & examples, please see README.md
86
+ def hash(plural_name, key_class=nil, value_class=nil, callback: nil, &definition_block)
87
+ singular_name = build_singular_name!(plural_name)
88
+ raise DslFactory::DefinitionError, "#{plural_name} value_class can not given at the same time as a block" if value_class && definition_block
89
+
90
+ @definition.define_method(plural_name) do |value = nil|
91
+ raise DslFactory::DefinitionError, "hashes do not support setting values with the plural form, please use #{singular_name} to define items" if value
92
+ get_dsl_value(plural_name)
93
+ end
94
+
95
+ @definition.define_method(singular_name) do |key, value = nil, &block|
96
+ raise DslFactory::ValidationError, "value can not be given at the same time as a block for a hash" if value && block
97
+
98
+ if block # we deal with a sub-DSL
99
+ value_object = Class.new
100
+ value_object.extend(DslFactory.define_dsl(&definition_block))
101
+ value_object.instance_eval(&block)
102
+ value = value_object
103
+ end
104
+ raise DslFactory::ValidationError, "#{singular_name}'s key is not a #{key_class}" if key_class && !key.is_a?(key_class)
105
+ raise DslFactory::ValidationError, "#{singular_name}'s value is not a #{value_class}" if value_class && !value.is_a?(value_class)
106
+ new_value = get_dsl_value(plural_name) || {}
107
+ new_value[key] = value
108
+ set_dsl_value(plural_name, new_value)
109
+ self.instance_exec(key, value, &callback) if callback
110
+ end
111
+ end
112
+
113
+ protected
114
+
115
+ def build_singular_name!(plural_name)
116
+ singular_name = ActiveSupport::Inflector.singularize(plural_name).to_sym
117
+ raise DslFactory::DefinitionError, "can not singularize #{plural_name}, please make sure to provide the plural form and that ActiveSupport::Inflector can singularize" if singular_name == plural_name
118
+ singular_name
119
+ end
120
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DslFactory
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "dsl_factory/version"
2
+ require_relative "dsl_factory/generator"
3
+
4
+ require 'active_support/inflector'
5
+
6
+ module DslFactory
7
+ class DefinitionError < StandardError; end
8
+ class ValidationError < StandardError; end
9
+
10
+ def define_dsl(&block)
11
+ generator = DslFactory::Generator.new
12
+ generator.instance_eval(&block)
13
+ return generator.definition
14
+ end
15
+
16
+ module_function :define_dsl
17
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dsl_factory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tom Rothe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ description: Define DSLs quickly and avoid the boilerplate write getters and setters.
28
+ Oh, and it does validation too.
29
+ email:
30
+ - info@tomrothe.de
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - CHANGELOG.md
37
+ - Gemfile
38
+ - Gemfile.lock
39
+ - LICENSE.txt
40
+ - README.md
41
+ - Rakefile
42
+ - dsl_factory.gemspec
43
+ - lib/dsl_factory.rb
44
+ - lib/dsl_factory/generator.rb
45
+ - lib/dsl_factory/version.rb
46
+ homepage: https://github.com/motine/dsl_factory
47
+ licenses:
48
+ - MIT
49
+ metadata:
50
+ homepage_uri: https://github.com/motine/dsl_factory
51
+ source_code_uri: https://github.com/motine/dsl_factory
52
+ changelog_uri: https://github.com/motine/dsl_factory/blob/master/CHANGELOG.md
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.5.0
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.2.15
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: A small DSL to generate DSLs
72
+ test_files: []