toys-core 0.3.11 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +7 -16
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/definition/tool.rb +1 -1
- data/lib/toys/dsl/tool.rb +5 -13
- data/lib/toys/input_file.rb +20 -12
- data/lib/toys/mixin.rb +35 -12
- data/lib/toys/runner.rb +1 -1
- data/lib/toys/standard_mixins/gems.rb +88 -0
- data/lib/toys/standard_mixins/highline.rb +1 -1
- data/lib/toys/standard_mixins/terminal.rb +1 -1
- data/lib/toys/tool.rb +0 -11
- data/lib/toys/utils/gems.rb +59 -42
- data/lib/toys/utils/terminal.rb +19 -7
- metadata +21 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95766b26892b0fab477c7f05a8eddf8aa0f30a9e98075b41881791ca1d446389
|
4
|
+
data.tar.gz: 03af27a0411ed093f1b0b27edb4aafd2562cc3b92f9176dfdd10e26be090d8f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc6e36460d0849a153a4fe8ac376bfc120f93e19f2931bfc892dbf0fda67af82e4aa0bd73c138e9950c5559fca8cc1bc6f056195bdaad5f935e7203a48cf3411
|
7
|
+
data.tar.gz: 458da8a2896163512994018fbce12ee6392ae69e63383b232d9c86577bdd02a5069bbbda52c79786d7d2e09f880ccea7bca2b0845979ef12c73a545a68303c28
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.4.0 / 2018-07-03
|
4
|
+
|
5
|
+
Now declaring this alpha quality. Backward-incompatible changes are still
|
6
|
+
possible from this point, but I'll try to avoid them.
|
7
|
+
|
8
|
+
* CHANGED: Utils::Terminal#confirm default is now unset by default
|
9
|
+
* CHANGED: Moved gem install/activation methods into a mixin
|
10
|
+
* IMPROVED: Toys::Utils::Gems can suppress the confirmation prompt
|
11
|
+
* IMPROVED: Magic comments are now honored in toys files.
|
12
|
+
* IMPROVED: Utils::Gems installation is now much faster.
|
13
|
+
* FIXED: Utils::Gems didn't reset the specifications on Ruby 2.3.
|
14
|
+
|
3
15
|
### 0.3.11 / 2018-07-02
|
4
16
|
|
5
17
|
* CHANGED: Require Ruby 2.3 or later
|
data/README.md
CHANGED
@@ -1,26 +1,15 @@
|
|
1
1
|
# Toys
|
2
2
|
|
3
|
-
Toys is a command line
|
4
|
-
|
5
|
-
|
6
|
-
for software developers, IT specialists, and other power users who want to
|
7
|
-
write and organize scripts to automate their workflows.
|
3
|
+
Toys is a configurable command line tool. Write commands in config files using
|
4
|
+
a simple DSL, and Toys will provide the command line binary and take care of
|
5
|
+
all the details such as argument parsing, online help, and error reporting.
|
8
6
|
|
9
7
|
Toys-Core is the command line tool framework underlying Toys. It can be used
|
10
|
-
to create command line binaries using the internal Toys APIs.
|
8
|
+
to create your own command line binaries using the internal Toys APIs.
|
11
9
|
|
12
|
-
To get started
|
10
|
+
To get started with toys-core, see the
|
13
11
|
[Getting Started Guide](https://www.rubydoc.info/gems/toys-core/file/docs/getting-started.md)
|
14
12
|
|
15
|
-
## Contributing
|
16
|
-
|
17
|
-
While we appreciate contributions, please note that this software is currently
|
18
|
-
highly experimental, and the code is evolving very rapidly. Please contact the
|
19
|
-
author before embarking on a major pull request. More detailed contribution
|
20
|
-
guidelines will be provided when the software stabilizes further.
|
21
|
-
|
22
|
-
The source can be found on Github at https://github.com/dazuma/toys
|
23
|
-
|
24
13
|
## License
|
25
14
|
|
26
15
|
Copyright 2018 Daniel Azuma
|
@@ -28,3 +17,5 @@ Copyright 2018 Daniel Azuma
|
|
28
17
|
This software is licensed under the 3-clause BSD license.
|
29
18
|
|
30
19
|
See the LICENSE.md file for more information.
|
20
|
+
|
21
|
+
The source can be found on Github at https://github.com/dazuma/toys
|
data/lib/toys/core_version.rb
CHANGED
data/lib/toys/definition/tool.rb
CHANGED
@@ -666,7 +666,7 @@ module Toys
|
|
666
666
|
unless @definition_finished
|
667
667
|
ContextualError.capture("Error installing tool middleware!", tool_name: full_name) do
|
668
668
|
config_proc = proc {}
|
669
|
-
middleware_stack.
|
669
|
+
middleware_stack.reverse_each do |middleware|
|
670
670
|
config_proc = make_config_proc(middleware, loader, config_proc)
|
671
671
|
end
|
672
672
|
config_proc.call
|
data/lib/toys/dsl/tool.rb
CHANGED
@@ -590,23 +590,15 @@ module Toys
|
|
590
590
|
if mod.nil?
|
591
591
|
raise ToolDefinitionError, "Module not found: #{name.inspect}"
|
592
592
|
end
|
593
|
-
if mod.respond_to?(:
|
594
|
-
cur_tool.add_initializer(mod.
|
593
|
+
if mod.respond_to?(:initialization_callback) && mod.initialization_callback
|
594
|
+
cur_tool.add_initializer(mod.initialization_callback, *args)
|
595
|
+
end
|
596
|
+
if mod.respond_to?(:inclusion_callback) && mod.inclusion_callback
|
597
|
+
class_exec(*args, &mod.inclusion_callback)
|
595
598
|
end
|
596
599
|
super(mod)
|
597
600
|
end
|
598
601
|
|
599
|
-
##
|
600
|
-
# Activate the given gem. If it is not present, attempt to install it (or
|
601
|
-
# inform the user to update the bundle).
|
602
|
-
#
|
603
|
-
# @param [String] name Name of the gem
|
604
|
-
# @param [String...] requirements Version requirements
|
605
|
-
#
|
606
|
-
def gem(name, *requirements)
|
607
|
-
(@__gems ||= Utils::Gems.new).activate(name, *requirements)
|
608
|
-
end
|
609
|
-
|
610
602
|
## @private
|
611
603
|
def self.new_class(words, priority, loader)
|
612
604
|
tool_class = ::Class.new(::Toys::Tool)
|
data/lib/toys/input_file.rb
CHANGED
@@ -48,20 +48,28 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
|
|
48
48
|
end
|
49
49
|
basename = ::File.basename(path).tr(".-", "_").gsub(/\W/, "")
|
50
50
|
name = "M#{namespace.object_id}_#{basename}"
|
51
|
-
|
52
|
-
str
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
str = build_eval_string(name, ::IO.read(path))
|
52
|
+
if str
|
53
|
+
const_set(name, namespace)
|
54
|
+
::Toys::DSL::Tool.prepare(tool_class, remaining_words, path) do
|
55
|
+
::Toys::ContextualError.capture_path("Error while loading Toys config!", path) do
|
56
|
+
# rubocop:disable Security/Eval
|
57
|
+
eval(str, __binding, path, 0)
|
58
|
+
# rubocop:enable Security/Eval
|
56
59
|
end
|
57
60
|
end
|
58
|
-
STR
|
59
|
-
::Toys::DSL::Tool.prepare(tool_class, remaining_words, path) do
|
60
|
-
::Toys::ContextualError.capture_path("Error while loading Toys config!", path) do
|
61
|
-
# rubocop:disable Security/Eval
|
62
|
-
eval(str, __binding, path, 0)
|
63
|
-
# rubocop:enable Security/Eval
|
64
|
-
end
|
65
61
|
end
|
66
62
|
end
|
63
|
+
|
64
|
+
## @private
|
65
|
+
def self.build_eval_string(module_name, string)
|
66
|
+
index = string.index(/^\s*[^#\s]/)
|
67
|
+
return nil if index.nil?
|
68
|
+
"#{string[0, index]}\n" \
|
69
|
+
"module #{module_name}\n" \
|
70
|
+
"@tool_class.class_eval do\n" \
|
71
|
+
"#{string[index..-1]}\n" \
|
72
|
+
"end\n" \
|
73
|
+
"end\n"
|
74
|
+
end
|
67
75
|
end
|
data/lib/toys/mixin.rb
CHANGED
@@ -43,12 +43,20 @@ module Toys
|
|
43
43
|
# To create a mixin, define a module, and include this module. Then define
|
44
44
|
# the methods you want to be available.
|
45
45
|
#
|
46
|
-
# If you want to perform some initialization specific to the mixin,
|
47
|
-
# `to_initialize` block
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
46
|
+
# If you want to perform some initialization specific to the mixin, you can
|
47
|
+
# provide a `to_initialize` block and/or a `to_include` block.
|
48
|
+
#
|
49
|
+
# The `to_initialize` block is called when the tool itself is instantiated.
|
50
|
+
# It has access to tool methods such as {Toys::Tool#option}, and can perform
|
51
|
+
# setup for the tool execution itself, often involving initializing some
|
52
|
+
# persistent state and storing it in the tool using {Toys::Tool#set}. The
|
53
|
+
# `to_initialize` block is passed any extra arguments that were provided to
|
54
|
+
# the `include` directive.
|
55
|
+
#
|
56
|
+
# The `to_include` block is called in the context of your tool class when
|
57
|
+
# your mixin is included. It is also passed any extra arguments that were
|
58
|
+
# provided to the `include` directive. It can be used to issue directives
|
59
|
+
# or define methods on the DSL, specific to the mixin.
|
52
60
|
#
|
53
61
|
# ## Example
|
54
62
|
#
|
@@ -95,25 +103,40 @@ module Toys
|
|
95
103
|
## @private
|
96
104
|
def self.included(mod)
|
97
105
|
return if mod.respond_to?(:to_initialize)
|
98
|
-
mod.extend(
|
106
|
+
mod.extend(ModuleMethods)
|
99
107
|
end
|
100
108
|
|
101
109
|
##
|
102
|
-
#
|
110
|
+
# Methods that will be added to a mixin module object.
|
103
111
|
#
|
104
|
-
module
|
112
|
+
module ModuleMethods
|
105
113
|
##
|
106
|
-
# Provide
|
114
|
+
# Provide a block that initializes this mixin when the tool is
|
115
|
+
# constructed.
|
107
116
|
#
|
108
117
|
def to_initialize(&block)
|
109
|
-
self.
|
118
|
+
self.initialization_callback = block
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# Provide a block that modifies the tool class when the mixin is
|
123
|
+
# included.
|
124
|
+
#
|
125
|
+
def to_include(&block)
|
126
|
+
self.inclusion_callback = block
|
110
127
|
end
|
111
128
|
|
112
129
|
##
|
113
130
|
# You may alternately set the initializer block using this accessor.
|
114
131
|
# @return [Proc]
|
115
132
|
#
|
116
|
-
attr_accessor :
|
133
|
+
attr_accessor :initialization_callback
|
134
|
+
|
135
|
+
##
|
136
|
+
# You may alternately set the inclusion block using this accessor.
|
137
|
+
# @return [Proc]
|
138
|
+
#
|
139
|
+
attr_accessor :inclusion_callback
|
117
140
|
end
|
118
141
|
end
|
119
142
|
end
|
data/lib/toys/runner.rb
CHANGED
@@ -161,7 +161,7 @@ module Toys
|
|
161
161
|
tool.exit(-1)
|
162
162
|
end
|
163
163
|
end
|
164
|
-
@tool_definition.middleware_stack.
|
164
|
+
@tool_definition.middleware_stack.reverse_each do |middleware|
|
165
165
|
executor = make_executor(middleware, tool, executor)
|
166
166
|
end
|
167
167
|
catch(:result) do
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Daniel Azuma
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
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.
|
30
|
+
;
|
31
|
+
|
32
|
+
module Toys
|
33
|
+
module StandardMixins
|
34
|
+
##
|
35
|
+
# Provides methods for installing and activating third-party gems. When
|
36
|
+
# this mixin is included, it provides a `gem` method that has the same
|
37
|
+
# effect as {Toys::Utils::Gems#activate}, so you can ensure a gem is
|
38
|
+
# present when running a tool. A `gem` directive is likewise added to the
|
39
|
+
# tool DSL itself, so you can also ensure a gem is present when defining a
|
40
|
+
# tool.
|
41
|
+
#
|
42
|
+
# You may make these methods available to your tool by including the
|
43
|
+
# following directive in your tool configuration:
|
44
|
+
#
|
45
|
+
# include :gems
|
46
|
+
#
|
47
|
+
# If you pass additional options to the include directive, those are used
|
48
|
+
# to initialize settings for the gem install process. For example:
|
49
|
+
#
|
50
|
+
# include :gems, output: $stdout, default_confirm: false
|
51
|
+
#
|
52
|
+
# This is a frontend for {Toys::Utils::Gems}. More information is
|
53
|
+
# available in that class's documentation.
|
54
|
+
#
|
55
|
+
module Gems
|
56
|
+
include Mixin
|
57
|
+
|
58
|
+
to_include do |opts = {}|
|
59
|
+
@__gems = Utils::Gems.new(opts)
|
60
|
+
|
61
|
+
def self.gems
|
62
|
+
@__gems
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.gem(name, *requirements)
|
66
|
+
gems.activate(name, *requirements)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Returns a tool-wide instance of {Toys::Utils::Gems}.
|
72
|
+
#
|
73
|
+
def gems
|
74
|
+
self.class.gems
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Activate the given gem.
|
79
|
+
#
|
80
|
+
# @param [String] name Name of the gem
|
81
|
+
# @param [String...] requirements Version requirements
|
82
|
+
#
|
83
|
+
def gem(name, *requirements)
|
84
|
+
self.class.gems.activate(name, *requirements)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/toys/tool.rb
CHANGED
@@ -259,17 +259,6 @@ module Toys
|
|
259
259
|
end
|
260
260
|
end
|
261
261
|
|
262
|
-
##
|
263
|
-
# Activate the given gem. If it is not present, attempt to install it (or
|
264
|
-
# inform the user to update the bundle).
|
265
|
-
#
|
266
|
-
# @param [String] name Name of the gem
|
267
|
-
# @param [String...] requirements Version requirements
|
268
|
-
#
|
269
|
-
def gem(name, *requirements)
|
270
|
-
(@__data[Utils::Gems] ||= Utils::Gems.new).activate(name, *requirements)
|
271
|
-
end
|
272
|
-
|
273
262
|
##
|
274
263
|
# Exit immediately with the given status code
|
275
264
|
#
|
data/lib/toys/utils/gems.rb
CHANGED
@@ -58,22 +58,35 @@ module Toys
|
|
58
58
|
end
|
59
59
|
|
60
60
|
##
|
61
|
-
# Activate the given gem.
|
61
|
+
# Activate the given gem. If it is not present, attempt to install it (or
|
62
|
+
# inform the user to update the bundle).
|
62
63
|
#
|
63
64
|
# @param [String] name Name of the gem
|
64
65
|
# @param [String...] requirements Version requirements
|
65
|
-
# @param [Boolean] default_confirm Default response for the confirmation prompt
|
66
66
|
#
|
67
|
-
def self.activate(name, *requirements
|
68
|
-
new.activate(name, *requirements
|
67
|
+
def self.activate(name, *requirements)
|
68
|
+
new.activate(name, *requirements)
|
69
69
|
end
|
70
70
|
|
71
71
|
##
|
72
72
|
# Create a new gem activator.
|
73
73
|
#
|
74
|
-
|
74
|
+
# @param [IO] input Input IO
|
75
|
+
# @param [IO] output Output IO
|
76
|
+
# @param [Boolean] suppress_confirm Suppress the confirmation prompt and
|
77
|
+
# just use the given `default_confirm` value. Default is false,
|
78
|
+
# indicating the confirmation prompt appears by default.
|
79
|
+
# @param [Boolean] default_confirm Default response for the confirmation
|
80
|
+
# prompt. Default is true.
|
81
|
+
#
|
82
|
+
def initialize(input: $stdin,
|
83
|
+
output: $stderr,
|
84
|
+
suppress_confirm: false,
|
85
|
+
default_confirm: true)
|
75
86
|
@terminal = Terminal.new(input: input, output: output)
|
76
87
|
@exec = Exec.new
|
88
|
+
@suppress_confirm = suppress_confirm ? true : false
|
89
|
+
@default_confirm = default_confirm ? true : false
|
77
90
|
end
|
78
91
|
|
79
92
|
##
|
@@ -82,18 +95,26 @@ module Toys
|
|
82
95
|
#
|
83
96
|
# @param [String] name Name of the gem
|
84
97
|
# @param [String...] requirements Version requirements
|
85
|
-
# @param [Boolean] default_confirm Default response for the confirmation prompt
|
86
98
|
#
|
87
|
-
def activate(name, *requirements
|
99
|
+
def activate(name, *requirements)
|
88
100
|
gem(name, *requirements)
|
89
|
-
rescue ::Gem::
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
101
|
+
rescue ::Gem::LoadError => e1
|
102
|
+
is_missing_spec =
|
103
|
+
if defined?(::Gem::MissingSpecError)
|
104
|
+
e1.is_a?(::Gem::MissingSpecError)
|
105
|
+
else
|
106
|
+
e1.message.include?("Could not find")
|
107
|
+
end
|
108
|
+
if is_missing_spec
|
109
|
+
install_gem(name, requirements)
|
110
|
+
begin
|
111
|
+
gem(name, *requirements)
|
112
|
+
rescue ::Gem::LoadError => e2
|
113
|
+
report_error(name, requirements, e2)
|
114
|
+
end
|
115
|
+
else
|
116
|
+
report_error(name, requirements, e1)
|
95
117
|
end
|
96
|
-
raise ActivationFailedError, e.message
|
97
118
|
end
|
98
119
|
|
99
120
|
private
|
@@ -102,44 +123,40 @@ module Toys
|
|
102
123
|
"#{name.inspect}, #{requirements.map(&:inspect).join(', ')}"
|
103
124
|
end
|
104
125
|
|
105
|
-
def install_gem(name, requirements
|
126
|
+
def install_gem(name, requirements)
|
106
127
|
requirements_text = gem_requirements_text(name, requirements)
|
107
|
-
response =
|
108
|
-
|
128
|
+
response =
|
129
|
+
if @suppress_confirm
|
130
|
+
@default_confirm
|
131
|
+
else
|
132
|
+
@terminal.confirm("Gem needed: #{requirements_text}. Install?",
|
133
|
+
default: @default_confirm)
|
134
|
+
end
|
109
135
|
unless response
|
110
136
|
raise InstallFailedError, "Canceled installation of needed gem: #{requirements_text}"
|
111
137
|
end
|
112
|
-
|
113
|
-
raise InstallFailedError, "No gem found matching #{requirements_text}." unless version
|
114
|
-
perform_install(name, version)
|
115
|
-
activate(name, *requirements)
|
138
|
+
perform_install(name, requirements)
|
116
139
|
end
|
117
140
|
|
118
|
-
def
|
119
|
-
@terminal.spinner(leading_text: "
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
else
|
128
|
-
raise InstallFailedError, "Unable to determine existing versions of gem #{name.inspect}"
|
129
|
-
end
|
141
|
+
def perform_install(name, requirements)
|
142
|
+
result = @terminal.spinner(leading_text: "Installing gem #{name}... ",
|
143
|
+
final_text: "Done.\n") do
|
144
|
+
@exec.exec(["gem", "install", name, "--version", requirements.join(",")],
|
145
|
+
out: :capture, err: :capture)
|
146
|
+
end
|
147
|
+
@terminal.puts(result.captured_out + result.captured_err)
|
148
|
+
if result.error?
|
149
|
+
raise InstallFailedError, "Failed to install gem #{name}"
|
130
150
|
end
|
151
|
+
::Gem::Specification.reset
|
131
152
|
end
|
132
153
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
out: :capture, err: :capture)
|
138
|
-
if result.error?
|
139
|
-
@terminal.puts(result.captured_out + result.captured_err)
|
140
|
-
raise InstallFailedError, "Failed to install gem #{name} #{version}"
|
141
|
-
end
|
154
|
+
def report_error(name, requirements, err)
|
155
|
+
if ::ENV["BUNDLE_GEMFILE"]
|
156
|
+
raise GemfileUpdateNeededError.new(gem_requirements_text(name, requirements),
|
157
|
+
::ENV["BUNDLE_GEMFILE"])
|
142
158
|
end
|
159
|
+
raise ActivationFailedError, err.message
|
143
160
|
end
|
144
161
|
end
|
145
162
|
end
|
data/lib/toys/utils/terminal.rb
CHANGED
@@ -55,6 +55,12 @@ module Toys
|
|
55
55
|
# * An array of ANSI codes as integers.
|
56
56
|
#
|
57
57
|
class Terminal
|
58
|
+
##
|
59
|
+
# Fatal terminal error.
|
60
|
+
#
|
61
|
+
class TerminalError < ::StandardError
|
62
|
+
end
|
63
|
+
|
58
64
|
## ANSI style code to clear styles
|
59
65
|
CLEAR_CODE = "\e[0m"
|
60
66
|
|
@@ -207,23 +213,29 @@ module Toys
|
|
207
213
|
# Confirm with the user.
|
208
214
|
#
|
209
215
|
# @param [String] prompt Prompt string. Defaults to `"Proceed?"`.
|
210
|
-
# @param [Boolean] default Default value
|
216
|
+
# @param [Boolean,nil] default Default value, or `nil` for no default.
|
217
|
+
# Uses `nil` if not specified.
|
211
218
|
# @return [Boolean]
|
212
219
|
#
|
213
|
-
def confirm(prompt = "Proceed?", default:
|
214
|
-
y = default ? "Y" : "y"
|
215
|
-
n = default ? "n" : "N"
|
220
|
+
def confirm(prompt = "Proceed?", default: nil)
|
221
|
+
y = default == true ? "Y" : "y"
|
222
|
+
n = default == false ? "n" : "N"
|
216
223
|
write("#{prompt} (#{y}/#{n}) ")
|
217
|
-
resp = input.gets
|
224
|
+
resp = input.gets
|
218
225
|
case resp
|
219
226
|
when /^y/i
|
220
227
|
true
|
221
228
|
when /^n/i
|
222
229
|
false
|
223
|
-
when
|
230
|
+
when nil
|
231
|
+
raise TerminalError, "Cannot confirm because the input stream is at eof." if default.nil?
|
224
232
|
default
|
225
233
|
else
|
226
|
-
|
234
|
+
if !resp.strip.empty? || default.nil?
|
235
|
+
confirm("Please answer \"y\" or \"n\"")
|
236
|
+
else
|
237
|
+
default
|
238
|
+
end
|
227
239
|
end
|
228
240
|
end
|
229
241
|
|
metadata
CHANGED
@@ -1,99 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toys-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: highline
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: minitest
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5.11'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '5.11'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: minitest-
|
42
|
+
name: minitest-focus
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '1.1'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '1.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: minitest-rg
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '5.2'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '5.2'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rubocop
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.57.2
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 0.57.2
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: yard
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 0.9.14
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 0.9.14
|
97
97
|
description: Toys-Core is the command line tool framework underlying Toys. It can
|
98
98
|
be used to create command line binaries using the internal Toys APIs.
|
99
99
|
email:
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- lib/toys/standard_middleware/show_root_version.rb
|
132
132
|
- lib/toys/standard_mixins/exec.rb
|
133
133
|
- lib/toys/standard_mixins/fileutils.rb
|
134
|
+
- lib/toys/standard_mixins/gems.rb
|
134
135
|
- lib/toys/standard_mixins/highline.rb
|
135
136
|
- lib/toys/standard_mixins/terminal.rb
|
136
137
|
- lib/toys/template.rb
|