toys 0.14.7 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@ module Toys
3
3
  ##
4
4
  # **_Defined in the toys-core gem_**
5
5
  #
6
- # This class defines the DSL for a Toys configuration file.
6
+ # This module defines the DSL for a Toys configuration file.
7
7
  #
8
8
  # A Toys configuration defines one or more named tools. It provides syntax
9
9
  # for setting the description, defining flags and arguments, specifying
@@ -25,6 +25,9 @@ module Toys
25
25
  # end
26
26
  # end
27
27
  #
28
+ # The DSL directives `tool`, `desc`, `optional_arg`, and others are defined
29
+ # in this module.
30
+ #
28
31
  # Now you can execute it using:
29
32
  #
30
33
  # toys greet
@@ -81,8 +84,8 @@ module Toys
81
84
  # ### Example
82
85
  #
83
86
  # The following example creates an acceptor named "hex" that is defined
84
- # via a regular expression. It then uses it to validate values passed to
85
- # a flag.
87
+ # via a regular expression. It uses the acceptor to validate values
88
+ # passed to a flag.
86
89
  #
87
90
  # tool "example" do
88
91
  # acceptor "hex", /[0-9a-fA-F]+/, type_desc: "hex numbers"
@@ -151,16 +154,21 @@ module Toys
151
154
  #
152
155
  # A template is an object that generates DSL directives. You can use it
153
156
  # to build "prefabricated" tools, and then instantiate them in your Toys
154
- # files. Generally, a template is a class with an associated `expansion`
155
- # procedure. The class defines parameters for the template expansion,
156
- # and `expansion` includes DSL directives that should be run based on
157
- # those parameters.
158
- #
159
- # Normally, you provide a block and define the template class in that
160
- # block. Most templates will define an `initialize` method that takes any
161
- # arguments passed into the template expansion. The template must also
162
- # provide an `expansion` block showing how to use the template object to
163
- # produce DSL directives.
157
+ # files.
158
+ #
159
+ # A template is an object that defines an `expansion` procedure. This
160
+ # procedure generates the DSL directives implemented by the template. The
161
+ # template object typically also includes attributes that are used to
162
+ # configure the expansion.
163
+ #
164
+ # The simplest way to define a template is to pass a block to the
165
+ # {#template} directive. In the block, define an `initialize` method that
166
+ # accepts any arguments that may be passed to the template when it is
167
+ # instantiated and are used to configure the template. Define
168
+ # `attr_reader`s or other methods to make this configuration accessible
169
+ # from the object. Then define an `on_expand` block that implements the
170
+ # template's expansion. The template object is passed as an object to the
171
+ # `on_expand` block.
164
172
  #
165
173
  # Alternately, you can create a template class separately and pass it
166
174
  # directly. See {Toys::Template} for details on creating a template
@@ -168,7 +176,9 @@ module Toys
168
176
  #
169
177
  # ### Example
170
178
  #
171
- # The following example creates and uses a simple template.
179
+ # The following example creates and uses a simple template. The template
180
+ # defines a tool, with a configurable name, that simply prints out a
181
+ # configurable message.
172
182
  #
173
183
  # template "hello-generator" do
174
184
  # def initialize(name, message)
@@ -176,7 +186,7 @@ module Toys
176
186
  # @message = message
177
187
  # end
178
188
  # attr_reader :name, :message
179
- # expansion do |template|
189
+ # on_expand do |template|
180
190
  # tool template.name do
181
191
  # to_run do
182
192
  # puts template.message
@@ -875,6 +885,12 @@ module Toys
875
885
  # arguments.) Defaults to the empty array.
876
886
  # @param display_name [String] A display name for this flag, used in help
877
887
  # text and error messages.
888
+ # @param add_method [true,false,nil] Whether to add a method for this
889
+ # flag. If omitted or set to nil, uses the default behavior, which
890
+ # adds the method if the key is a symbol representing a legal method
891
+ # name that starts with a letter and does not override any public
892
+ # method in the Ruby Object class or collide with any method directly
893
+ # defined in the tool class.
878
894
  # @param block [Proc] Configures the flag. See {Toys::DSL::Flag} for the
879
895
  # directives that can be called in this block.
880
896
  # @return [self]
@@ -883,7 +899,7 @@ module Toys
883
899
  accept: nil, default: nil, handler: nil,
884
900
  complete_flags: nil, complete_values: nil,
885
901
  report_collisions: true, group: nil,
886
- desc: nil, long_desc: nil, display_name: nil,
902
+ desc: nil, long_desc: nil, display_name: nil, add_method: nil,
887
903
  &block)
888
904
  # Source available in the toys-core gem
889
905
  end
@@ -936,6 +952,12 @@ module Toys
936
952
  # a description of the allowed formats. (But note that this param
937
953
  # takes an Array of description lines, rather than a series of
938
954
  # arguments.) Defaults to the empty array.
955
+ # @param add_method [true,false,nil] Whether to add a method for this
956
+ # argument. If omitted or set to nil, uses the default behavior,
957
+ # which adds the method if the key is a symbol representing a legal
958
+ # method name that starts with a letter and does not override any
959
+ # public method in the Ruby Object class or collide with any method
960
+ # directly defined in the tool class.
939
961
  # @param block [Proc] Configures the positional argument. See
940
962
  # {Toys::DSL::PositionalArg} for the directives that can be called in
941
963
  # this block.
@@ -943,7 +965,7 @@ module Toys
943
965
  #
944
966
  def required_arg(key,
945
967
  accept: nil, complete: nil, display_name: nil,
946
- desc: nil, long_desc: nil,
968
+ desc: nil, long_desc: nil, add_method: nil,
947
969
  &block)
948
970
  # Source available in the toys-core gem
949
971
  end
@@ -1002,6 +1024,12 @@ module Toys
1002
1024
  # a description of the allowed formats. (But note that this param
1003
1025
  # takes an Array of description lines, rather than a series of
1004
1026
  # arguments.) Defaults to the empty array.
1027
+ # @param add_method [true,false,nil] Whether to add a method for this
1028
+ # argument. If omitted or set to nil, uses the default behavior,
1029
+ # which adds the method if the key is a symbol representing a legal
1030
+ # method name that starts with a letter and does not override any
1031
+ # public method in the Ruby Object class or collide with any method
1032
+ # directly defined in the tool class.
1005
1033
  # @param block [Proc] Configures the positional argument. See
1006
1034
  # {Toys::DSL::PositionalArg} for the directives that can be called in
1007
1035
  # this block.
@@ -1009,7 +1037,7 @@ module Toys
1009
1037
  #
1010
1038
  def optional_arg(key,
1011
1039
  default: nil, accept: nil, complete: nil, display_name: nil,
1012
- desc: nil, long_desc: nil,
1040
+ desc: nil, long_desc: nil, add_method: nil,
1013
1041
  &block)
1014
1042
  # Source available in the toys-core gem
1015
1043
  end
@@ -1068,6 +1096,12 @@ module Toys
1068
1096
  # a description of the allowed formats. (But note that this param
1069
1097
  # takes an Array of description lines, rather than a series of
1070
1098
  # arguments.) Defaults to the empty array.
1099
+ # @param add_method [true,false,nil] Whether to add a method for these
1100
+ # arguments. If omitted or set to nil, uses the default behavior,
1101
+ # which adds the method if the key is a symbol representing a legal
1102
+ # method name that starts with a letter and does not override any
1103
+ # public method in the Ruby Object class or collide with any method
1104
+ # directly defined in the tool class.
1071
1105
  # @param block [Proc] Configures the positional argument. See
1072
1106
  # {Toys::DSL::PositionalArg} for the directives that can be called in
1073
1107
  # this block.
@@ -1075,14 +1109,14 @@ module Toys
1075
1109
  #
1076
1110
  def remaining_args(key,
1077
1111
  default: [], accept: nil, complete: nil, display_name: nil,
1078
- desc: nil, long_desc: nil,
1112
+ desc: nil, long_desc: nil, add_method: nil,
1079
1113
  &block)
1080
1114
  # Source available in the toys-core gem
1081
1115
  end
1082
1116
  alias remaining remaining_args
1083
1117
 
1084
1118
  ##
1085
- # Set a option values statically and create a helper method.
1119
+ # Set option values statically and create helper methods.
1086
1120
  #
1087
1121
  # If any given key is a symbol representing a valid method name, then a
1088
1122
  # helper method is automatically added to retrieve the value. Otherwise,
@@ -1115,7 +1149,7 @@ module Toys
1115
1149
  end
1116
1150
 
1117
1151
  ##
1118
- # Set a option values statically without creating helper methods.
1152
+ # Set option values statically without creating helper methods.
1119
1153
  #
1120
1154
  # ### Example
1121
1155
  #
@@ -1180,6 +1214,15 @@ module Toys
1180
1214
  # This directive is mutually exclusive with any of the directives that
1181
1215
  # declare arguments or flags.
1182
1216
  #
1217
+ # ### Example
1218
+ #
1219
+ # tool "mytool" do
1220
+ # disable_argument_parsing
1221
+ # def run
1222
+ # puts "Arguments passed: #{args}"
1223
+ # end
1224
+ # end
1225
+ #
1183
1226
  # @return [self]
1184
1227
  #
1185
1228
  def disable_argument_parsing
@@ -1249,27 +1292,53 @@ module Toys
1249
1292
  end
1250
1293
 
1251
1294
  ##
1252
- # Specify how to run this tool. Typically you do this by defining a
1253
- # method namd `run`. Alternatively, however, you can pass a block to the
1254
- # `to_run` method.
1295
+ # Specify how to run this tool.
1255
1296
  #
1256
- # You may want to do this if your method needs access to local variables
1257
- # in the lexical scope. However, it is often more convenient to use
1258
- # {#static} to set the value in the context.)
1297
+ # Typically the entrypoint for a tool is a method named `run`. However,
1298
+ # you can change this by passing a different method name, as a symbol, to
1299
+ # {#to_run}.
1259
1300
  #
1260
- # ### Example
1301
+ # You can also alternatively pass a block to {#to_run}. You might do this
1302
+ # if your method needs access to local variables in the lexical scope.
1303
+ # However, it is often more convenient to use {#static} to set those
1304
+ # values in the context.
1305
+ #
1306
+ # ### Examples
1307
+ #
1308
+ # # Set a different method name as the entrypoint:
1261
1309
  #
1262
1310
  # tool "foo" do
1263
- # cur_time = Time.new
1311
+ # to_run :foo
1312
+ # def foo
1313
+ # puts "The fool tool ran!"
1314
+ # end
1315
+ # end
1316
+ #
1317
+ # # Use a block to retain access to the enclosing lexical scope from
1318
+ # # the run method:
1319
+ #
1320
+ # tool "foo" do
1321
+ # cur_time = Time.now
1264
1322
  # to_run do
1265
1323
  # puts "The time at tool definition was #{cur_time}"
1266
1324
  # end
1267
1325
  # end
1268
1326
  #
1269
- # @param block [Proc] The run method.
1327
+ # # But the following is approximately equivalent:
1328
+ #
1329
+ # tool "foo" do
1330
+ # static :cur_time, Time.now
1331
+ # def run
1332
+ # puts "The time at tool definition was #{cur_time}"
1333
+ # end
1334
+ # end
1335
+ #
1336
+ # @param handler [Proc,Symbol,nil] The run handler as a method name
1337
+ # symbol or a proc, or nil to explicitly set as non-runnable.
1338
+ # @param block [Proc] The run handler as a block.
1270
1339
  # @return [self]
1271
1340
  #
1272
- def to_run(&block)
1341
+ def to_run(handler = nil, &block)
1273
1342
  # Source available in the toys-core gem
1274
1343
  end
1275
1344
  alias on_run to_run
@@ -1277,9 +1346,12 @@ module Toys
1277
1346
  ##
1278
1347
  # Specify how to handle interrupts.
1279
1348
  #
1280
- # You may pass a block to be called, or the name of a method to call. In
1281
- # either case, the block or method should take one argument, the
1282
- # Interrupt exception that was raised.
1349
+ # You can provide either a block to be called, a Proc to be called, or
1350
+ # the name of a method to be called. In each case, the block, Proc, or
1351
+ # method can optionally take one argument, the Interrupt exception that
1352
+ # was raised.
1353
+ #
1354
+ # Note: this is equivalent to `on_signal("SIGINT")`.
1283
1355
  #
1284
1356
  # ### Example
1285
1357
  #
@@ -1287,7 +1359,7 @@ module Toys
1287
1359
  # def run
1288
1360
  # sleep 10
1289
1361
  # end
1290
- # on_interrupt do |e|
1362
+ # on_interrupt do
1291
1363
  # puts "I was interrupted."
1292
1364
  # end
1293
1365
  # end
@@ -1301,18 +1373,47 @@ module Toys
1301
1373
  # Source available in the toys-core gem
1302
1374
  end
1303
1375
 
1376
+ ##
1377
+ # Specify how to handle the given signal.
1378
+ #
1379
+ # You can provide either a block to be called, a Proc to be called, or
1380
+ # the name of a method to be called. In each case, the block, Proc, or
1381
+ # method can optionally take one argument, the SignalException that was
1382
+ # raised.
1383
+ #
1384
+ # ### Example
1385
+ #
1386
+ # tool "foo" do
1387
+ # def run
1388
+ # sleep 10
1389
+ # end
1390
+ # on_signal("QUIT") do |e|
1391
+ # puts "Signal caught: #{e.signm}."
1392
+ # end
1393
+ # end
1394
+ #
1395
+ # @param signal [Integer,String,Symbol] The signal name or number
1396
+ # @param handler [Proc,Symbol,nil] The signal callback proc or method
1397
+ # name. Pass nil to disable signal handling.
1398
+ # @param block [Proc] The signal callback as a block.
1399
+ # @return [self]
1400
+ #
1401
+ def on_signal(signal, handler = nil, &block)
1402
+ # Source available in the toys-core gem
1403
+ end
1404
+
1304
1405
  ##
1305
1406
  # Specify how to handle usage errors.
1306
1407
  #
1307
- # You may pass a block to be called, or the name of a method to call. In
1308
- # either case, the block or method should take one argument, the array of
1309
- # usage errors reported.
1408
+ # You can provide either a block to be called, a Proc to be called, or
1409
+ # the name of a method to be called. In each case, the block, Proc, or
1410
+ # method can optionally take one argument, the array of usage errors
1411
+ # reported.
1310
1412
  #
1311
1413
  # ### Example
1312
1414
  #
1313
- # This tool runs even if a usage error is encountered. You can find info
1314
- # on the errors from {Toys::Context::Key::USAGE_ERRORS},
1315
- # {Toys::Context::Key::UNMATCHED_ARGS}, and similar keys.
1415
+ # This tool runs even if a usage error is encountered, by setting the
1416
+ # `run` method as the usage error handler.
1316
1417
  #
1317
1418
  # tool "foo" do
1318
1419
  # def run
@@ -1334,7 +1435,7 @@ module Toys
1334
1435
  # Specify that the given module should be mixed into this tool, and its
1335
1436
  # methods made available when running the tool.
1336
1437
  #
1337
- # You may provide either a module, the string name of a mixin that you
1438
+ # You can provide either a module, the string name of a mixin that you
1338
1439
  # have defined in this tool or one of its ancestors, or the symbol name
1339
1440
  # of a well-known mixin.
1340
1441
  #
@@ -1365,7 +1466,7 @@ module Toys
1365
1466
  ##
1366
1467
  # Determine if the given module/mixin has already been included.
1367
1468
  #
1368
- # You may provide either a module, the string name of a mixin that you
1469
+ # You can provide either a module, the string name of a mixin that you
1369
1470
  # have defined in this tool or one of its ancestors, or the symbol name
1370
1471
  # of a well-known mixin.
1371
1472
  #
@@ -339,7 +339,7 @@ module Toys
339
339
  # Source available in the toys-core gem
340
340
  end
341
341
 
342
- @git_cache_mutex = ::Monitor.new
342
+ @git_cache_mutex = ::Mutex.new
343
343
  @default_git_cache = nil
344
344
 
345
345
  ##
@@ -21,8 +21,9 @@ module Toys
21
21
  # Generally, a middleware is a class that implements one or more of the
22
22
  # methods defined in this module: {Toys::Middleware#config}, and
23
23
  # {Toys::Middleware#run}. This module provides default implementations that
24
- # do nothing, but using them is not required. Middleware objects need respond
25
- # only to methods they care about.
24
+ # do nothing, but it is not required to include this module, or even to
25
+ # define both methods. Middleware objects need respond only to methods they
26
+ # care about.
26
27
  #
27
28
  module Middleware
28
29
  ##
@@ -221,7 +221,7 @@ module Toys
221
221
  # has a parent, the parent is queried. If that parent also does not have
222
222
  # a value for the field, it may query its parent in turn, and so forth.
223
223
  # * If we encounter a root settings with no parent, and still no value is
224
- # set for the field, the default is returned.
224
+ # set for the field, the default for the *original* setting is returned.
225
225
  #
226
226
  # Example:
227
227
  #
@@ -5,6 +5,21 @@ module Toys
5
5
  #
6
6
  # Ensures that a bundle is installed and set up when this tool is run.
7
7
  #
8
+ # This is the normal recommended way to use [bundler](https://bundler.io)
9
+ # with Toys. Including this mixin in a tool will cause Toys to ensure that
10
+ # the bundle is installed and available during tool execution. For example:
11
+ #
12
+ # tool "run-rails" do
13
+ # include :bundler
14
+ # def run
15
+ # # Note: no "bundle exec" required because Toys has already
16
+ # # installed and loaded the bundle.
17
+ # exec "rails s"
18
+ # end
19
+ # end
20
+ #
21
+ # ### Customization
22
+ #
8
23
  # The following parameters can be passed when including this mixin:
9
24
  #
10
25
  # * `:static` (Boolean) If `true`, installs the bundle immediately, when
@@ -39,7 +54,7 @@ module Toys
39
54
  # Defaults to {Toys::Utils::Gems::DEFAULT_GEMFILE_NAMES}.
40
55
  #
41
56
  # * `:toys_gemfile_names` (Array\<String\>) File names that are
42
- # recognized as Gemfiles when wearching in Toys directories.
57
+ # recognized as Gemfiles when searching in Toys directories.
43
58
  # Defaults to {DEFAULT_TOYS_GEMFILE_NAMES}.
44
59
  #
45
60
  # * `:on_missing` (Symbol) What to do if a needed gem is not installed.
@@ -3,10 +3,10 @@ module Toys
3
3
  ##
4
4
  # **_Defined in the toys-core gem_**
5
5
  #
6
- # A set of helper methods for invoking subcommands. Provides shortcuts for
7
- # common cases such as invoking Ruby in a subprocess or capturing output
8
- # in a string. Also provides an interface for controlling a spawned
9
- # process's streams.
6
+ # The `:exec` mixin provides set of helper methods for executing processes
7
+ # and subcommands. It provides shortcuts for common cases such as invoking
8
+ # a Ruby script in a subprocess or capturing output in a string. It also
9
+ # provides an interface for controlling a spawned process's streams.
10
10
  #
11
11
  # You can make these methods available to your tool by including the
12
12
  # following directive in your tool configuration:
@@ -16,6 +16,25 @@ module Toys
16
16
  # This is a frontend for {Toys::Utils::Exec}. More information is
17
17
  # available in that class's documentation.
18
18
  #
19
+ # ### Mixin overview
20
+ #
21
+ # The mixin provides a number of methods for spawning processes. The most
22
+ # basic are {#exec} and {#exec_proc}. The {#exec} method spawns an
23
+ # operating system process specified by an executable and a set of
24
+ # arguments. The {#exec_proc} method takes a `Proc` and forks a Ruby
25
+ # process. Both of these can be heavily configured with stream handling,
26
+ # result handling, and numerous other options described below. The mixin
27
+ # also provides convenience methods for common cases such as spawning a
28
+ # Ruby process, spawning a shell script, or capturing output.
29
+ #
30
+ # The mixin also stores default configuration that it applies to processes
31
+ # it spawns. You can change these defaults by calling {#configure_exec}.
32
+ #
33
+ # Underlying the mixin is a service object of type {Toys::Utils::Exec}.
34
+ # Normally you would use the mixin methods to access this functionality,
35
+ # but you can also retrieve the service object itself by calling
36
+ # {Toys::Context#get} with the key {Toys::StandardMixins::Exec::KEY}.
37
+ #
19
38
  # ### Controlling processes
20
39
  #
21
40
  # A process can be started in the *foreground* or the *background*. If you
@@ -24,7 +43,7 @@ module Toys
24
43
  # If you start a background process, its streams will be redirected to null
25
44
  # by default, and control will be returned to you immediately.
26
45
  #
27
- # When a process is running, you can control it using a
46
+ # While a process is running, you can control it using a
28
47
  # {Toys::Utils::Exec::Controller} object. Use a controller to interact with
29
48
  # the process's input and output streams, send it signals, or wait for it
30
49
  # to complete.
@@ -44,7 +63,7 @@ module Toys
44
63
  # When running a process in the background, the controller is returned from
45
64
  # the method that starts the process:
46
65
  #
47
- # controller = exec_service.exec(["git", "init"], background: true)
66
+ # controller = exec(["git", "init"], background: true)
48
67
  #
49
68
  # ### Stream handling
50
69
  #
@@ -10,11 +10,24 @@ module Toys
10
10
  # tool DSL itself, so you can also ensure a gem is present when defining a
11
11
  # tool.
12
12
  #
13
- # You may make these methods available to your tool by including the
14
- # following directive in your tool configuration:
13
+ # ### Usage
14
+ #
15
+ # Make these methods available to your tool by including this mixin in your
16
+ # tool:
15
17
  #
16
18
  # include :gems
17
19
  #
20
+ # You can then call the mixin method {#gem} to ensure that a gem is
21
+ # installed and in the load path. For example:
22
+ #
23
+ # tool "my_tool" do
24
+ # include :gems
25
+ # gem "nokogiri", "~> 1.15"
26
+ # def run
27
+ # # Do stuff with Nokogiri
28
+ # end
29
+ # end
30
+ #
18
31
  # If you pass additional options to the include directive, those are used
19
32
  # to initialize settings for the gem install process. For example:
20
33
  #
@@ -34,7 +47,8 @@ module Toys
34
47
  end
35
48
 
36
49
  ##
37
- # Activate the given gem.
50
+ # Activate the given gem. If it is not present, attempt to install it (or
51
+ # inform the user to update the bundle).
38
52
  #
39
53
  # @param name [String] Name of the gem
40
54
  # @param requirements [String...] Version requirements