toys-core 0.7.0 → 0.8.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.
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