toys-core 0.3.6 → 0.3.7
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/CHANGELOG.md +13 -0
- data/lib/toys-core.rb +20 -5
- data/lib/toys/cli.rb +39 -32
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/{tool → definition}/acceptor.rb +21 -15
- data/lib/toys/{utils/line_output.rb → definition/alias.rb} +47 -59
- data/lib/toys/{tool/arg_definition.rb → definition/arg.rb} +17 -7
- data/lib/toys/{tool/flag_definition.rb → definition/flag.rb} +19 -9
- data/lib/toys/definition/tool.rb +574 -0
- data/lib/toys/dsl/arg.rb +118 -0
- data/lib/toys/dsl/flag.rb +132 -0
- data/lib/toys/dsl/tool.rb +521 -0
- data/lib/toys/errors.rb +2 -2
- data/lib/toys/helpers.rb +3 -3
- data/lib/toys/helpers/exec.rb +31 -25
- data/lib/toys/helpers/fileutils.rb +8 -2
- data/lib/toys/helpers/highline.rb +8 -1
- data/lib/toys/{alias.rb → helpers/terminal.rb} +44 -53
- data/lib/toys/input_file.rb +61 -0
- data/lib/toys/loader.rb +87 -77
- data/lib/toys/middleware.rb +3 -3
- data/lib/toys/middleware/add_verbosity_flags.rb +22 -20
- data/lib/toys/middleware/base.rb +53 -5
- data/lib/toys/middleware/handle_usage_errors.rb +9 -12
- data/lib/toys/middleware/set_default_descriptions.rb +6 -7
- data/lib/toys/middleware/show_help.rb +71 -67
- data/lib/toys/middleware/show_root_version.rb +9 -9
- data/lib/toys/runner.rb +157 -0
- data/lib/toys/template.rb +4 -3
- data/lib/toys/templates.rb +2 -2
- data/lib/toys/templates/clean.rb +2 -2
- data/lib/toys/templates/gem_build.rb +5 -5
- data/lib/toys/templates/minitest.rb +2 -2
- data/lib/toys/templates/rubocop.rb +2 -2
- data/lib/toys/templates/yardoc.rb +2 -2
- data/lib/toys/tool.rb +168 -625
- data/lib/toys/utils/exec.rb +19 -18
- data/lib/toys/utils/gems.rb +140 -0
- data/lib/toys/utils/help_text.rb +25 -20
- data/lib/toys/utils/terminal.rb +412 -0
- data/lib/toys/utils/wrappable_string.rb +3 -1
- metadata +15 -24
- data/lib/toys/config_dsl.rb +0 -699
- data/lib/toys/context.rb +0 -290
- data/lib/toys/helpers/spinner.rb +0 -142
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f7ff775c645d4bbd1906fab469307dcf06852e83d9fa02aba978fd0db53af21
|
4
|
+
data.tar.gz: 408ffcc9b47eff78b05228d811e2a32932a56eebe8e64381a5a96ce1c0e22caf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4969720705d06c492e7083dbd5d139b71ef3f3e260980acca8ec33771b4ee06b90e8138c341984681ff53a747fcdb256fffcbe412d30d64c9a0b32a82b0975ac
|
7
|
+
data.tar.gz: 4db5eed3cc44658511b14d017a3afac43daafc397e3094c1955ae08a95b60886673cfa2196b269a06b9c534f4614300573bf33cc2b43a39981c2bd4500c19cd6
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.3.7 / 2018-05-30
|
4
|
+
|
5
|
+
* CHANGED: Execution runs in the same scope as the DSL, which lets us use normal methods instead of helper-blocks.
|
6
|
+
* CHANGED: Renamed "script" to "run", and allow setting of runnable by defining a "run" method
|
7
|
+
* CHANGED: Set up a constant scope for each config file, to make constant lookup make sense.
|
8
|
+
* CHANGED: Removed run_toys and dropped EXIT_ON_NONZERO_STATUS key in favor of using cli directly.
|
9
|
+
* CHANGED: Renamed definition_path to source_path
|
10
|
+
* CHANGED: LineOutput util changed to a simple Terminal util, and folded spinner into it.
|
11
|
+
* CHANGED: Removed spinner helper and added terminal helper.
|
12
|
+
* CHANGED: Organized DSL and definition classes
|
13
|
+
* ADDED: Helper modules scoped to the tool hierarchy
|
14
|
+
* ADDED: Utility that installs and activates third-party gems.
|
15
|
+
|
3
16
|
### 0.3.6 / 2018-05-21
|
4
17
|
|
5
18
|
* CHANGED: Renamed show_version middleware to show_root_version.
|
data/lib/toys-core.rb
CHANGED
@@ -27,8 +27,6 @@
|
|
27
27
|
# POSSIBILITY OF SUCH DAMAGE.
|
28
28
|
;
|
29
29
|
|
30
|
-
gem "highline", "~> 1.7"
|
31
|
-
|
32
30
|
##
|
33
31
|
# Toys is a Ruby library and command line tool that lets you build your own
|
34
32
|
# command line suite of tools (with commands and subcommands) using a Ruby DSL.
|
@@ -40,17 +38,34 @@ module Toys
|
|
40
38
|
# Namespace for common utility classes.
|
41
39
|
#
|
42
40
|
module Utils; end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Namespace for object definition classes.
|
44
|
+
#
|
45
|
+
module Definition; end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Namespace for DSL classes.
|
49
|
+
#
|
50
|
+
module DSL; end
|
43
51
|
end
|
44
52
|
|
45
|
-
require "toys/alias"
|
46
53
|
require "toys/cli"
|
47
|
-
require "toys/config_dsl"
|
48
|
-
require "toys/context"
|
49
54
|
require "toys/core_version"
|
55
|
+
require "toys/definition/acceptor"
|
56
|
+
require "toys/definition/alias"
|
57
|
+
require "toys/definition/arg"
|
58
|
+
require "toys/definition/flag"
|
59
|
+
require "toys/definition/tool"
|
60
|
+
require "toys/dsl/arg"
|
61
|
+
require "toys/dsl/flag"
|
62
|
+
require "toys/dsl/tool"
|
50
63
|
require "toys/errors"
|
51
64
|
require "toys/helpers"
|
65
|
+
require "toys/input_file"
|
52
66
|
require "toys/loader"
|
53
67
|
require "toys/middleware"
|
68
|
+
require "toys/runner"
|
54
69
|
require "toys/template"
|
55
70
|
require "toys/templates"
|
56
71
|
require "toys/tool"
|
data/lib/toys/cli.rb
CHANGED
@@ -28,9 +28,8 @@
|
|
28
28
|
;
|
29
29
|
|
30
30
|
require "logger"
|
31
|
-
require "highline"
|
32
31
|
|
33
|
-
require "toys/utils/
|
32
|
+
require "toys/utils/terminal"
|
34
33
|
|
35
34
|
module Toys
|
36
35
|
##
|
@@ -99,7 +98,7 @@ module Toys
|
|
99
98
|
@loader = Loader.new(
|
100
99
|
index_file_name: index_file_name,
|
101
100
|
preload_file_name: preload_file_name,
|
102
|
-
middleware_stack: middleware_stack
|
101
|
+
middleware_stack: @middleware_stack
|
103
102
|
)
|
104
103
|
@error_handler = error_handler || DefaultErrorHandler.new
|
105
104
|
end
|
@@ -209,10 +208,15 @@ module Toys
|
|
209
208
|
# @return [Integer] The resulting status code
|
210
209
|
#
|
211
210
|
def run(*args, verbosity: 0)
|
212
|
-
|
211
|
+
tool_definition, remaining = ContextualError.capture("Error finding tool definition") do
|
213
212
|
@loader.lookup(args.flatten)
|
214
213
|
end
|
215
|
-
|
214
|
+
ContextualError.capture_path(
|
215
|
+
"Error during tool execution!", tool_definition.source_path,
|
216
|
+
tool_name: tool_definition.full_name, tool_args: remaining
|
217
|
+
) do
|
218
|
+
Runner.new(self, tool_definition).run(remaining, verbosity: verbosity)
|
219
|
+
end
|
216
220
|
rescue ContextualError => e
|
217
221
|
@error_handler.call(e)
|
218
222
|
end
|
@@ -247,16 +251,20 @@ module Toys
|
|
247
251
|
##
|
248
252
|
# Create an error handler.
|
249
253
|
#
|
250
|
-
# @param [IO
|
254
|
+
# @param [IO] output Where to write errors. Default is `$stderr`.
|
251
255
|
#
|
252
|
-
def initialize(
|
253
|
-
@
|
256
|
+
def initialize(output = $stderr)
|
257
|
+
@terminal = Utils::Terminal.new(output: output)
|
254
258
|
end
|
255
259
|
|
256
|
-
##
|
260
|
+
##
|
261
|
+
# The error handler routine. Prints out the error message and backtrace.
|
262
|
+
#
|
263
|
+
# @param [Exception] error The error that occurred.
|
264
|
+
#
|
257
265
|
def call(error)
|
258
|
-
@
|
259
|
-
@
|
266
|
+
@terminal.puts(cause_string(error.cause))
|
267
|
+
@terminal.puts(context_string(error), :bold)
|
260
268
|
-1
|
261
269
|
end
|
262
270
|
|
@@ -315,13 +323,14 @@ module Toys
|
|
315
323
|
end
|
316
324
|
|
317
325
|
##
|
318
|
-
# Returns a default logger that logs to
|
326
|
+
# Returns a default logger that logs to `$stderr`.
|
319
327
|
#
|
320
328
|
# @param [IO] stream Stream to write to. Defaults to `$stderr`.
|
321
329
|
# @return [Logger]
|
322
330
|
#
|
323
331
|
def default_logger(stream = $stderr)
|
324
332
|
logger = ::Logger.new(stream)
|
333
|
+
terminal = Utils::Terminal.new(output: stream)
|
325
334
|
logger.formatter = proc do |severity, time, _progname, msg|
|
326
335
|
msg_str =
|
327
336
|
case msg
|
@@ -332,7 +341,7 @@ module Toys
|
|
332
341
|
else
|
333
342
|
msg.inspect
|
334
343
|
end
|
335
|
-
format_log(
|
344
|
+
format_log(terminal, time, severity, msg_str)
|
336
345
|
end
|
337
346
|
logger.level = ::Logger::WARN
|
338
347
|
logger
|
@@ -340,27 +349,25 @@ module Toys
|
|
340
349
|
|
341
350
|
private
|
342
351
|
|
343
|
-
def format_log(
|
352
|
+
def format_log(terminal, time, severity, msg)
|
344
353
|
timestr = time.strftime("%Y-%m-%d %H:%M:%S")
|
345
354
|
header = format("[%s %5s]", timestr, severity)
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
end
|
363
|
-
"#{header} #{msg}\n"
|
355
|
+
styled_header =
|
356
|
+
case severity
|
357
|
+
when "FATAL"
|
358
|
+
terminal.apply_styles(header, :bright_magenta, :bold, :underline)
|
359
|
+
when "ERROR"
|
360
|
+
terminal.apply_styles(header, :bright_red, :bold)
|
361
|
+
when "WARN"
|
362
|
+
terminal.apply_styles(header, :bright_yellow)
|
363
|
+
when "INFO"
|
364
|
+
terminal.apply_styles(header, :bright_cyan)
|
365
|
+
when "DEBUG"
|
366
|
+
terminal.apply_styles(header, :white)
|
367
|
+
else
|
368
|
+
header
|
369
|
+
end
|
370
|
+
"#{styled_header} #{msg}\n"
|
364
371
|
end
|
365
372
|
end
|
366
373
|
end
|
data/lib/toys/core_version.rb
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
;
|
29
29
|
|
30
30
|
module Toys
|
31
|
-
|
31
|
+
module Definition
|
32
32
|
##
|
33
33
|
# An Acceptor validates and converts arguments. It is designed to be
|
34
34
|
# compatible with the OptionParser accept mechanism.
|
@@ -47,16 +47,19 @@ module Toys
|
|
47
47
|
##
|
48
48
|
# Create a base acceptor.
|
49
49
|
#
|
50
|
-
# The
|
51
|
-
# arguments). You may subclass this object and
|
50
|
+
# The base acceptor does not do any validation (i.e. it accepts all
|
51
|
+
# arguments). You may subclass this object and override the {#match}
|
52
52
|
# method to change this behavior.
|
53
53
|
#
|
54
|
-
# The
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
54
|
+
# The base acceptor lets you provide a converter as a proc. The proc
|
55
|
+
# should take one or more arguments, the first of which is the entire
|
56
|
+
# argument string, and the others of which are any additional values
|
57
|
+
# returned from validation. The converter should return the final
|
58
|
+
# converted value of the argument.
|
59
|
+
#
|
60
|
+
# The converter may be provided either as a proc in the `converter`
|
61
|
+
# parameter, or as a block. If neither is provided, the base acceptor
|
62
|
+
# performs no conversion and uses the argument string.
|
60
63
|
#
|
61
64
|
# @param [String] name A visible name for the acceptor, shown in help.
|
62
65
|
# @param [Proc] converter A converter function. May also be given as a
|
@@ -105,7 +108,8 @@ module Toys
|
|
105
108
|
end
|
106
109
|
|
107
110
|
##
|
108
|
-
# Convert the given input.
|
111
|
+
# Convert the given input. Uses the converter provided to this object's
|
112
|
+
# constructor. Subclasses may also override this method.
|
109
113
|
#
|
110
114
|
# @param [String] str Original argument string
|
111
115
|
# @param [Object...] extra Zero or more additional arguments comprising
|
@@ -123,10 +127,11 @@ module Toys
|
|
123
127
|
#
|
124
128
|
class PatternAcceptor < Acceptor
|
125
129
|
##
|
126
|
-
# Create
|
130
|
+
# Create a pattern acceptor.
|
127
131
|
#
|
128
132
|
# You must provide a regular expression as a validator. You may also
|
129
|
-
# provide a converter.
|
133
|
+
# provide a converter proc. See {Toys::Definition::Acceptor} for details
|
134
|
+
# on the converter.
|
130
135
|
#
|
131
136
|
# @param [String] name A visible name for the acceptor, shown in help.
|
132
137
|
# @param [Regexp] regex Regular expression defining value values.
|
@@ -140,7 +145,7 @@ module Toys
|
|
140
145
|
end
|
141
146
|
|
142
147
|
##
|
143
|
-
# Overrides match to
|
148
|
+
# Overrides {Toys::Definition::Acceptor#match} to use the given regex.
|
144
149
|
#
|
145
150
|
def match(str)
|
146
151
|
@regex.match(str)
|
@@ -173,14 +178,15 @@ module Toys
|
|
173
178
|
end
|
174
179
|
|
175
180
|
##
|
176
|
-
# Overrides match to find the value.
|
181
|
+
# Overrides {Toys::Definition::Acceptor#match} to find the value.
|
177
182
|
#
|
178
183
|
def match(str)
|
179
184
|
@values.find { |s, _e| s == str }
|
180
185
|
end
|
181
186
|
|
182
187
|
##
|
183
|
-
# Overrides convert to return the original
|
188
|
+
# Overrides {Toys::Definition::Acceptor#convert} to return the original
|
189
|
+
# element.
|
184
190
|
#
|
185
191
|
def convert(_str, elem)
|
186
192
|
elem
|
@@ -27,95 +27,83 @@
|
|
27
27
|
# POSSIBILITY OF SUCH DAMAGE.
|
28
28
|
;
|
29
29
|
|
30
|
-
require "highline"
|
31
|
-
|
32
30
|
module Toys
|
33
|
-
module
|
31
|
+
module Definition
|
34
32
|
##
|
35
|
-
#
|
33
|
+
# An alias is a name that refers to another name.
|
36
34
|
#
|
37
|
-
class
|
35
|
+
class Alias
|
38
36
|
##
|
39
|
-
# Create a
|
37
|
+
# Create a new alias.
|
40
38
|
#
|
41
|
-
# @param [
|
39
|
+
# @param [Array<String>] full_name The name of the alias.
|
40
|
+
# @param [String,Array<String>] target The name of the target. May either
|
41
|
+
# be a local reference (a single string) or a global reference (an
|
42
|
+
# array of strings)
|
42
43
|
#
|
43
|
-
def initialize(
|
44
|
-
@
|
45
|
-
|
46
|
-
|
47
|
-
if styled.nil?
|
48
|
-
sink.respond_to?(:tty?) && sink.tty?
|
44
|
+
def initialize(loader, full_name, target, priority)
|
45
|
+
@target_name =
|
46
|
+
if target.is_a?(::String)
|
47
|
+
full_name[0..-2] + [target]
|
49
48
|
else
|
50
|
-
|
49
|
+
target.dup
|
51
50
|
end
|
52
|
-
@
|
51
|
+
@target_name.freeze
|
52
|
+
@full_name = full_name.dup.freeze
|
53
|
+
@priority = priority
|
54
|
+
@tool_class = DSL::Tool.new_class(@full_name, priority, loader)
|
53
55
|
end
|
54
56
|
|
55
57
|
##
|
56
|
-
#
|
57
|
-
# @return [
|
58
|
+
# Return the tool class.
|
59
|
+
# @return [Class]
|
58
60
|
#
|
59
|
-
attr_reader :
|
61
|
+
attr_reader :tool_class
|
60
62
|
|
61
63
|
##
|
62
|
-
#
|
63
|
-
#
|
64
|
+
# Return the name of the tool as an array of strings.
|
65
|
+
# This array may not be modified.
|
66
|
+
# @return [Array<String>]
|
64
67
|
#
|
65
|
-
|
68
|
+
attr_reader :full_name
|
66
69
|
|
67
70
|
##
|
68
|
-
#
|
69
|
-
# @return [Integer
|
71
|
+
# Return the priority of this alias.
|
72
|
+
# @return [Integer]
|
70
73
|
#
|
71
|
-
attr_reader :
|
74
|
+
attr_reader :priority
|
72
75
|
|
73
76
|
##
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# @
|
77
|
-
# @param [Symbol...] styles Styles to apply to the entire line.
|
77
|
+
# Return the name of the target as an array of strings.
|
78
|
+
# This array may not be modified.
|
79
|
+
# @return [Array<String>]
|
78
80
|
#
|
79
|
-
|
80
|
-
str = @buffer + apply_styles(str, styles)
|
81
|
-
@buffer = ""
|
82
|
-
case sink
|
83
|
-
when ::Logger
|
84
|
-
sink.log(log_level, str)
|
85
|
-
when ::IO
|
86
|
-
sink.puts(str)
|
87
|
-
sink.flush
|
88
|
-
end
|
89
|
-
self
|
90
|
-
end
|
81
|
+
attr_reader :target_name
|
91
82
|
|
92
83
|
##
|
93
|
-
#
|
84
|
+
# Returns the local name of this tool.
|
85
|
+
# @return [String]
|
94
86
|
#
|
95
|
-
def
|
96
|
-
|
87
|
+
def simple_name
|
88
|
+
full_name.last
|
97
89
|
end
|
98
90
|
|
99
91
|
##
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
# @param [String] str The line to write
|
104
|
-
# @param [Symbol...] styles Styles to apply to the partial line.
|
92
|
+
# Returns a displayable name of this tool, generally the full name
|
93
|
+
# delimited by spaces.
|
94
|
+
# @return [String]
|
105
95
|
#
|
106
|
-
def
|
107
|
-
|
108
|
-
self
|
96
|
+
def display_name
|
97
|
+
full_name.join(" ")
|
109
98
|
end
|
110
99
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
end
|
100
|
+
##
|
101
|
+
# Returns a displayable name of the target, generally the full name
|
102
|
+
# delimited by spaces.
|
103
|
+
# @return [String]
|
104
|
+
#
|
105
|
+
def display_target
|
106
|
+
target_name.join(" ")
|
119
107
|
end
|
120
108
|
end
|
121
109
|
end
|