toys-core 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/LICENSE.md +16 -24
  4. data/README.md +307 -59
  5. data/docs/guide.md +44 -4
  6. data/lib/toys-core.rb +58 -49
  7. data/lib/toys/acceptor.rb +672 -0
  8. data/lib/toys/alias.rb +106 -0
  9. data/lib/toys/arg_parser.rb +624 -0
  10. data/lib/toys/cli.rb +422 -181
  11. data/lib/toys/compat.rb +83 -0
  12. data/lib/toys/completion.rb +442 -0
  13. data/lib/toys/context.rb +354 -0
  14. data/lib/toys/core_version.rb +18 -26
  15. data/lib/toys/dsl/flag.rb +213 -56
  16. data/lib/toys/dsl/flag_group.rb +237 -51
  17. data/lib/toys/dsl/positional_arg.rb +210 -0
  18. data/lib/toys/dsl/tool.rb +968 -317
  19. data/lib/toys/errors.rb +46 -28
  20. data/lib/toys/flag.rb +821 -0
  21. data/lib/toys/flag_group.rb +282 -0
  22. data/lib/toys/input_file.rb +18 -26
  23. data/lib/toys/loader.rb +110 -100
  24. data/lib/toys/middleware.rb +24 -31
  25. data/lib/toys/mixin.rb +90 -59
  26. data/lib/toys/module_lookup.rb +125 -0
  27. data/lib/toys/positional_arg.rb +184 -0
  28. data/lib/toys/source_info.rb +192 -0
  29. data/lib/toys/standard_middleware/add_verbosity_flags.rb +38 -43
  30. data/lib/toys/standard_middleware/handle_usage_errors.rb +39 -40
  31. data/lib/toys/standard_middleware/set_default_descriptions.rb +111 -89
  32. data/lib/toys/standard_middleware/show_help.rb +130 -113
  33. data/lib/toys/standard_middleware/show_root_version.rb +29 -35
  34. data/lib/toys/standard_mixins/exec.rb +116 -78
  35. data/lib/toys/standard_mixins/fileutils.rb +16 -24
  36. data/lib/toys/standard_mixins/gems.rb +29 -30
  37. data/lib/toys/standard_mixins/highline.rb +34 -41
  38. data/lib/toys/standard_mixins/terminal.rb +72 -26
  39. data/lib/toys/template.rb +51 -35
  40. data/lib/toys/tool.rb +1161 -206
  41. data/lib/toys/utils/completion_engine.rb +171 -0
  42. data/lib/toys/utils/exec.rb +279 -182
  43. data/lib/toys/utils/gems.rb +58 -49
  44. data/lib/toys/utils/help_text.rb +117 -111
  45. data/lib/toys/utils/terminal.rb +69 -62
  46. data/lib/toys/wrappable_string.rb +162 -0
  47. metadata +24 -22
  48. data/lib/toys/definition/acceptor.rb +0 -191
  49. data/lib/toys/definition/alias.rb +0 -112
  50. data/lib/toys/definition/arg.rb +0 -140
  51. data/lib/toys/definition/flag.rb +0 -370
  52. data/lib/toys/definition/flag_group.rb +0 -205
  53. data/lib/toys/definition/source_info.rb +0 -190
  54. data/lib/toys/definition/tool.rb +0 -842
  55. data/lib/toys/dsl/arg.rb +0 -132
  56. data/lib/toys/runner.rb +0 -188
  57. data/lib/toys/standard_middleware.rb +0 -47
  58. data/lib/toys/utils/module_lookup.rb +0 -135
  59. data/lib/toys/utils/wrappable_string.rb +0 -165
@@ -1,37 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
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:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
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
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
- Toys::Utils::Gems.activate("highline", "~> 2.0")
33
- require "highline"
34
-
35
24
  module Toys
36
25
  module StandardMixins
37
26
  ##
@@ -68,13 +57,17 @@ module Toys
68
57
  #
69
58
  KEY = ::Object.new.freeze
70
59
 
71
- to_initialize do |*args|
60
+ on_initialize do |*args|
61
+ require "toys/utils/gems"
62
+ Toys::Utils::Gems.activate("highline", "~> 2.0")
63
+ require "highline"
72
64
  self[KEY] = ::HighLine.new(*args)
73
65
  self[KEY].use_color = $stdout.tty?
74
66
  end
75
67
 
76
68
  ##
77
- # Returns a tool-wide highline instance
69
+ # A tool-wide [HighLine](https://www.rubydoc.info/gems/highline/HighLine)
70
+ # instance
78
71
  # @return [::HighLine]
79
72
  #
80
73
  def highline
@@ -82,84 +75,84 @@ module Toys
82
75
  end
83
76
 
84
77
  ##
85
- # @see https://www.rubydoc.info/gems/highline/HighLine:agree HighLine#agree
78
+ # Calls [HighLine#agree](https://www.rubydoc.info/gems/highline/HighLine:agree)
86
79
  #
87
80
  def agree(*args, &block)
88
81
  highline.agree(*args, &block)
89
82
  end
90
83
 
91
84
  ##
92
- # @see https://www.rubydoc.info/gems/highline/HighLine:ask HighLine#ask
85
+ # Calls [HighLine#ask](https://www.rubydoc.info/gems/highline/HighLine:ask)
93
86
  #
94
87
  def ask(*args, &block)
95
88
  highline.ask(*args, &block)
96
89
  end
97
90
 
98
91
  ##
99
- # @see https://www.rubydoc.info/gems/highline/HighLine:choose HighLine#choose
92
+ # Calls [HighLine#choose](https://www.rubydoc.info/gems/highline/HighLine:choose)
100
93
  #
101
94
  def choose(*args, &block)
102
95
  highline.choose(*args, &block)
103
96
  end
104
97
 
105
98
  ##
106
- # @see https://www.rubydoc.info/gems/highline/HighLine:list HighLine#list
99
+ # Calls [HighLine#list](https://www.rubydoc.info/gems/highline/HighLine:list)
107
100
  #
108
101
  def list(*args, &block)
109
102
  highline.list(*args, &block)
110
103
  end
111
104
 
112
105
  ##
113
- # @see https://www.rubydoc.info/gems/highline/HighLine:say HighLine#say
106
+ # Calls [HighLine#say](https://www.rubydoc.info/gems/highline/HighLine:say)
114
107
  #
115
108
  def say(*args, &block)
116
109
  highline.say(*args, &block)
117
110
  end
118
111
 
119
112
  ##
120
- # @see https://www.rubydoc.info/gems/highline/HighLine:indent HighLine#indent
113
+ # Calls [HighLine#indent](https://www.rubydoc.info/gems/highline/HighLine:indent)
121
114
  #
122
115
  def indent(*args, &block)
123
116
  highline.indent(*args, &block)
124
117
  end
125
118
 
126
119
  ##
127
- # @see https://www.rubydoc.info/gems/highline/HighLine:newline HighLine#newline
120
+ # Calls [HighLine#newline](https://www.rubydoc.info/gems/highline/HighLine:newline)
128
121
  #
129
122
  def newline
130
123
  highline.newline
131
124
  end
132
125
 
133
126
  ##
134
- # @see https://www.rubydoc.info/gems/highline/HighLine:puts HighLine#puts
127
+ # Calls [HighLine#puts](https://www.rubydoc.info/gems/highline/HighLine:puts)
135
128
  #
136
129
  def puts(*args)
137
130
  highline.puts(*args)
138
131
  end
139
132
 
140
133
  ##
141
- # @see https://www.rubydoc.info/gems/highline/HighLine:color HighLine#color
134
+ # Calls [HighLine#color](https://www.rubydoc.info/gems/highline/HighLine:color)
142
135
  #
143
136
  def color(*args)
144
137
  highline.color(*args)
145
138
  end
146
139
 
147
140
  ##
148
- # @see https://www.rubydoc.info/gems/highline/HighLine:color_code HighLine#color_code
141
+ # Calls [HighLine#color_code](https://www.rubydoc.info/gems/highline/HighLine:color_code)
149
142
  #
150
143
  def color_code(*args)
151
144
  highline.color_code(*args)
152
145
  end
153
146
 
154
147
  ##
155
- # @see https://www.rubydoc.info/gems/highline/HighLine:uncolor HighLine#uncolor
148
+ # Calls [HighLine#uncolor](https://www.rubydoc.info/gems/highline/HighLine:uncolor)
156
149
  #
157
150
  def uncolor(*args)
158
151
  highline.uncolor(*args)
159
152
  end
160
153
 
161
154
  ##
162
- # @see https://www.rubydoc.info/gems/highline/HighLine:new_scope HighLine#new_scope
155
+ # Calls [HighLine#new_scope](https://www.rubydoc.info/gems/highline/HighLine:new_scope)
163
156
  #
164
157
  def new_scope
165
158
  highline.new_scope
@@ -1,32 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
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:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
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
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  module Toys
@@ -64,12 +56,13 @@ module Toys
64
56
  #
65
57
  KEY = ::Object.new.freeze
66
58
 
67
- to_initialize do |opts = {}|
59
+ on_initialize do |opts = {}|
60
+ require "toys/utils/terminal"
68
61
  self[KEY] = Utils::Terminal.new(opts)
69
62
  end
70
63
 
71
64
  ##
72
- # Returns a tool-wide terminal instance
65
+ # A tool-wide terminal instance
73
66
  # @return [Toys::Utils::Terminal]
74
67
  #
75
68
  def terminal
@@ -77,37 +70,90 @@ module Toys
77
70
  end
78
71
 
79
72
  ##
73
+ # Write a line, appending a newline if one is not already present.
74
+ #
80
75
  # @see Toys::Utils::Terminal#puts
81
76
  #
77
+ # @param str [String] The line to write
78
+ # @param styles [Symbol,String,Array<Integer>...] Styles to apply to the
79
+ # entire line.
80
+ # @return [self]
81
+ #
82
82
  def puts(str = "", *styles)
83
83
  terminal.puts(str, *styles)
84
+ self
84
85
  end
85
86
  alias say puts
86
87
 
87
88
  ##
89
+ # Write a partial line without appending a newline.
90
+ #
88
91
  # @see Toys::Utils::Terminal#write
89
92
  #
93
+ # @param str [String] The line to write
94
+ # @param styles [Symbol,String,Array<Integer>...] Styles to apply to the
95
+ # partial line.
96
+ # @return [self]
97
+ #
90
98
  def write(str = "", *styles)
91
99
  terminal.write(str, *styles)
100
+ self
92
101
  end
93
102
 
94
103
  ##
104
+ # Ask a question and get a response.
105
+ #
95
106
  # @see Toys::Utils::Terminal#ask
96
107
  #
108
+ # @param prompt [String] Required prompt string.
109
+ # @param styles [Symbol,String,Array<Integer>...] Styles to apply to the
110
+ # prompt.
111
+ # @param default [String,nil] Default value, or `nil` for no default.
112
+ # Uses `nil` if not specified.
113
+ # @param trailing_text [:default,String,nil] Trailing text appended to
114
+ # the prompt, `nil` for none, or `:default` to show the default.
115
+ # @return [String]
116
+ #
97
117
  def ask(prompt, *styles, default: nil, trailing_text: :default)
98
118
  terminal.ask(prompt, *styles, default: default, trailing_text: trailing_text)
99
119
  end
100
120
 
101
121
  ##
122
+ # Confirm with the user.
123
+ #
102
124
  # @see Toys::Utils::Terminal#confirm
103
125
  #
126
+ # @param prompt [String] Prompt string. Defaults to `"Proceed?"`.
127
+ # @param styles [Symbol,String,Array<Integer>...] Styles to apply to the
128
+ # prompt.
129
+ # @param default [Boolean,nil] Default value, or `nil` for no default.
130
+ # Uses `nil` if not specified.
131
+ # @return [Boolean]
132
+ #
104
133
  def confirm(prompt = "Proceed?", *styles, default: nil)
105
134
  terminal.confirm(prompt, *styles, default: default)
106
135
  end
107
136
 
108
137
  ##
138
+ # Display a spinner during a task. You should provide a block that
139
+ # performs the long-running task. While the block is executing, a
140
+ # spinner will be displayed.
141
+ #
109
142
  # @see Toys::Utils::Terminal#spinner
110
143
  #
144
+ # @param leading_text [String] Optional leading string to display to the
145
+ # left of the spinner. Default is the empty string.
146
+ # @param frame_length [Float] Length of a single frame, in seconds.
147
+ # Defaults to {Toys::Utils::Terminal::DEFAULT_SPINNER_FRAME_LENGTH}.
148
+ # @param frames [Array<String>] An array of frames. Defaults to
149
+ # {Toys::Utils::Terminal::DEFAULT_SPINNER_FRAMES}.
150
+ # @param style [Symbol,Array<Symbol>] A terminal style or array of styles
151
+ # to apply to all frames in the spinner. Defaults to empty,
152
+ # @param final_text [String] Optional final string to display when the
153
+ # spinner is complete. Default is the empty string. A common practice
154
+ # is to set this to newline.
155
+ # @return [Object] The return value of the block.
156
+ #
111
157
  def spinner(leading_text: "", final_text: "",
112
158
  frame_length: nil, frames: nil, style: nil, &block)
113
159
  terminal.spinner(leading_text: leading_text, final_text: final_text,
@@ -1,32 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
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:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
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
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  module Toys
@@ -48,8 +40,8 @@ module Toys
48
40
  # {Toys::DSL::Tool#expand} method are passed to your constructor, and your
49
41
  # template object is passed to any block given to {Toys::DSL::Tool#expand}.
50
42
  #
51
- # Next, in your template class, call the `to_expand` method, which is defined
52
- # in {Toys::Template::ClassMethods#to_expand}. Pass this a block which
43
+ # Next, in your template class, call the `on_expand` method, which is defined
44
+ # in {Toys::Template::ClassMethods#on_expand}. Pass this a block which
53
45
  # defines the implementation of the template. Effectively, the contents of
54
46
  # this block are "inserted" into the user's configuration. The template
55
47
  # object is passed to the block so you have access to the template options.
@@ -76,7 +68,7 @@ module Toys
76
68
  # attr_accessor :name
77
69
  #
78
70
  # # The following block is inserted when the template is expanded.
79
- # to_expand do |template|
71
+ # on_expand do |template|
80
72
  # desc "Prints a greeting to #{template.name}"
81
73
  # tool "templated-greeting" do
82
74
  # to_run do
@@ -99,11 +91,25 @@ module Toys
99
91
  # And it will create a tool called "templated-greeting".
100
92
  #
101
93
  module Template
94
+ ##
95
+ # Create a template class with the given block.
96
+ #
97
+ # @param block [Proc] Defines the template class.
98
+ # @return [Class]
99
+ #
100
+ def self.create(&block)
101
+ template_class = ::Class.new do
102
+ include ::Toys::Template
103
+ end
104
+ template_class.class_eval(&block) if block
105
+ template_class
106
+ end
107
+
102
108
  ## @private
103
109
  def self.included(mod)
104
- return if mod.respond_to?(:to_expand)
110
+ return if mod.respond_to?(:on_expand)
105
111
  mod.extend(ClassMethods)
106
- mod.include(Tool::Keys)
112
+ mod.include(Context::Key)
107
113
  end
108
114
 
109
115
  ##
@@ -111,17 +117,27 @@ module Toys
111
117
  #
112
118
  module ClassMethods
113
119
  ##
114
- # Provide the block that implements the template.
120
+ # Define how to expand this template. The given block is passed the
121
+ # template object, and is evaluated in the tool class. It should invoke
122
+ # directives to create tools and other objects.
115
123
  #
116
- def to_expand(&block)
117
- self.expander = block
124
+ # @param block [Proc] The expansion of this template.
125
+ # @return [self]
126
+ #
127
+ def on_expand(&block)
128
+ self.expansion = block
129
+ self
118
130
  end
131
+ alias to_expand on_expand
119
132
 
120
133
  ##
121
- # You may alternately set the expander block using this accessor.
122
- # @return [Proc]
134
+ # The template expansion proc. This proc is passed the template object,
135
+ # and is evaluted in the tool class. It should invoke directives to
136
+ # create tools and other objects.
137
+ #
138
+ # @return [Proc] The expansion of this template.
123
139
  #
124
- attr_accessor :expander
140
+ attr_accessor :expansion
125
141
  end
126
142
  end
127
143
  end