toys-core 0.10.1 → 0.11.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +5 -5
- data/docs/guide.md +2 -0
- data/lib/toys-core.rb +3 -0
- data/lib/toys/compat.rb +13 -4
- data/lib/toys/core.rb +1 -1
- data/lib/toys/dsl/tool.rb +17 -0
- data/lib/toys/loader.rb +71 -31
- data/lib/toys/source_info.rb +22 -23
- data/lib/toys/standard_mixins/bundler.rb +121 -40
- data/lib/toys/standard_mixins/exec.rb +1 -1
- data/lib/toys/utils/exec.rb +88 -24
- data/lib/toys/utils/gems.rb +124 -30
- data/lib/toys/utils/help_text.rb +54 -59
- data/lib/toys/utils/terminal.rb +1 -1
- metadata +5 -131
data/lib/toys/utils/help_text.rb
CHANGED
@@ -32,14 +32,13 @@ module Toys
|
|
32
32
|
# @return [Toys::Utils::HelpText]
|
33
33
|
#
|
34
34
|
def self.from_context(context)
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
delegates = []
|
36
|
+
cur = context
|
37
|
+
while (cur = cur[Context::Key::DELEGATED_FROM])
|
38
|
+
delegates << cur[Context::Key::TOOL]
|
38
39
|
end
|
39
|
-
delegate_target = orig_context == context ? nil : orig_context[Context::Key::TOOL_NAME]
|
40
40
|
cli = context[Context::Key::CLI]
|
41
|
-
new(context[Context::Key::TOOL], cli.loader, cli.executable_name,
|
42
|
-
delegate_target: delegate_target)
|
41
|
+
new(context[Context::Key::TOOL], cli.loader, cli.executable_name, delegates: delegates)
|
43
42
|
end
|
44
43
|
|
45
44
|
##
|
@@ -49,16 +48,15 @@ module Toys
|
|
49
48
|
# @param loader [Toys::Loader] A loader that can provide subcommands.
|
50
49
|
# @param executable_name [String] The name of the executable.
|
51
50
|
# e.g. `"toys"`.
|
52
|
-
# @param
|
53
|
-
# tool will delegate to. Default is `nil` for no delegation.
|
51
|
+
# @param delegates [Array<Toys::Tool>] The delegation path to the tool.
|
54
52
|
#
|
55
53
|
# @return [Toys::Utils::HelpText]
|
56
54
|
#
|
57
|
-
def initialize(tool, loader, executable_name,
|
55
|
+
def initialize(tool, loader, executable_name, delegates: [])
|
58
56
|
@tool = tool
|
59
57
|
@loader = loader
|
60
58
|
@executable_name = executable_name
|
61
|
-
@
|
59
|
+
@delegates = delegates
|
62
60
|
end
|
63
61
|
|
64
62
|
##
|
@@ -88,8 +86,7 @@ module Toys
|
|
88
86
|
indent ||= DEFAULT_INDENT
|
89
87
|
subtools = find_subtools(recursive, nil, include_hidden)
|
90
88
|
assembler = UsageStringAssembler.new(
|
91
|
-
@tool, @executable_name,
|
92
|
-
indent, left_column_width, wrap_width
|
89
|
+
@tool, @executable_name, subtools, indent, left_column_width, wrap_width
|
93
90
|
)
|
94
91
|
assembler.result
|
95
92
|
end
|
@@ -121,7 +118,7 @@ module Toys
|
|
121
118
|
indent2 ||= DEFAULT_INDENT
|
122
119
|
subtools = find_subtools(recursive, search, include_hidden)
|
123
120
|
assembler = HelpStringAssembler.new(
|
124
|
-
@tool, @executable_name, @
|
121
|
+
@tool, @executable_name, @delegates, subtools, search, show_source_path,
|
125
122
|
indent, indent2, wrap_width, styled
|
126
123
|
)
|
127
124
|
assembler.result
|
@@ -155,22 +152,29 @@ module Toys
|
|
155
152
|
private
|
156
153
|
|
157
154
|
def find_subtools(recursive, search, include_hidden)
|
158
|
-
|
159
|
-
|
160
|
-
|
155
|
+
subtools_by_name = {}
|
156
|
+
([@tool] + @delegates).each do |tool|
|
157
|
+
name_len = tool.full_name.length
|
158
|
+
subtools = @loader.list_subtools(tool.full_name,
|
159
|
+
recursive: recursive, include_hidden: include_hidden)
|
160
|
+
subtools.each do |subtool|
|
161
|
+
local_name = subtool.full_name.slice(name_len..-1).join(" ")
|
162
|
+
subtools_by_name[local_name] = subtool
|
163
|
+
end
|
164
|
+
end
|
165
|
+
subtool_list = subtools_by_name.sort_by { |(local_name, _tool)| local_name }
|
166
|
+
return subtool_list if search.nil? || search.empty?
|
161
167
|
regex = ::Regexp.new(search, ::Regexp::IGNORECASE)
|
162
|
-
|
163
|
-
regex =~
|
168
|
+
subtool_list.find_all do |local_name, tool|
|
169
|
+
regex =~ local_name || regex =~ tool.desc.to_s
|
164
170
|
end
|
165
171
|
end
|
166
172
|
|
167
173
|
## @private
|
168
174
|
class UsageStringAssembler
|
169
|
-
def initialize(tool, executable_name,
|
170
|
-
indent, left_column_width, wrap_width)
|
175
|
+
def initialize(tool, executable_name, subtools, indent, left_column_width, wrap_width)
|
171
176
|
@tool = tool
|
172
177
|
@executable_name = executable_name
|
173
|
-
@delegate_target = delegate_target
|
174
178
|
@subtools = subtools
|
175
179
|
@indent = indent
|
176
180
|
@left_column_width = left_column_width
|
@@ -195,7 +199,7 @@ module Toys
|
|
195
199
|
def add_synopsis_section
|
196
200
|
synopses = []
|
197
201
|
synopses << namespace_synopsis unless @subtools.empty?
|
198
|
-
synopses <<
|
202
|
+
synopses << tool_synopsis
|
199
203
|
first = true
|
200
204
|
synopses.each do |synopsis|
|
201
205
|
@lines << (first ? "Usage: #{synopsis}" : " #{synopsis}")
|
@@ -212,11 +216,6 @@ module Toys
|
|
212
216
|
synopsis.join(" ")
|
213
217
|
end
|
214
218
|
|
215
|
-
def delegate_synopsis
|
216
|
-
target = @delegate_target.join(" ")
|
217
|
-
"#{@executable_name} #{@tool.display_name} [ARGUMENTS FOR \"#{target}\"...]"
|
218
|
-
end
|
219
|
-
|
220
219
|
def namespace_synopsis
|
221
220
|
"#{@executable_name} #{@tool.display_name} TOOL [ARGUMENTS...]"
|
222
221
|
end
|
@@ -256,12 +255,10 @@ module Toys
|
|
256
255
|
|
257
256
|
def add_subtool_list_section
|
258
257
|
return if @subtools.empty?
|
259
|
-
name_len = @tool.full_name.length
|
260
258
|
@lines << ""
|
261
259
|
@lines << "Tools:"
|
262
|
-
@subtools.each do |subtool|
|
263
|
-
|
264
|
-
add_right_column_desc(tool_name, wrap_desc(subtool.desc))
|
260
|
+
@subtools.each do |local_name, subtool|
|
261
|
+
add_right_column_desc(local_name, wrap_desc(subtool.desc))
|
265
262
|
end
|
266
263
|
end
|
267
264
|
|
@@ -301,12 +298,12 @@ module Toys
|
|
301
298
|
|
302
299
|
## @private
|
303
300
|
class HelpStringAssembler
|
304
|
-
def initialize(tool, executable_name,
|
301
|
+
def initialize(tool, executable_name, delegates, subtools, search_term,
|
305
302
|
show_source_path, indent, indent2, wrap_width, styled)
|
306
303
|
require "toys/utils/terminal"
|
307
304
|
@tool = tool
|
308
305
|
@executable_name = executable_name
|
309
|
-
@
|
306
|
+
@delegates = delegates
|
310
307
|
@subtools = subtools
|
311
308
|
@search_term = search_term
|
312
309
|
@show_source_path = show_source_path
|
@@ -356,7 +353,7 @@ module Toys
|
|
356
353
|
@lines << ""
|
357
354
|
@lines << bold("SYNOPSIS")
|
358
355
|
add_synopsis_clause(namespace_synopsis) unless @subtools.empty?
|
359
|
-
add_synopsis_clause(@
|
356
|
+
add_synopsis_clause(tool_synopsis(@tool))
|
360
357
|
end
|
361
358
|
|
362
359
|
def add_synopsis_clause(synopsis)
|
@@ -367,8 +364,8 @@ module Toys
|
|
367
364
|
end
|
368
365
|
end
|
369
366
|
|
370
|
-
def tool_synopsis
|
371
|
-
synopsis = [full_executable_name]
|
367
|
+
def tool_synopsis(tool_for_name)
|
368
|
+
synopsis = [full_executable_name(tool_for_name)]
|
372
369
|
@tool.flag_groups.each do |flag_group|
|
373
370
|
case flag_group
|
374
371
|
when FlagGroup::Required
|
@@ -441,19 +438,14 @@ module Toys
|
|
441
438
|
end
|
442
439
|
|
443
440
|
def namespace_synopsis
|
444
|
-
synopsis = [full_executable_name
|
441
|
+
synopsis = [full_executable_name(@tool),
|
442
|
+
underline("TOOL"),
|
443
|
+
"[#{underline('ARGUMENTS')}...]"]
|
445
444
|
wrap_indent_indent2(WrappableString.new(synopsis))
|
446
445
|
end
|
447
446
|
|
448
|
-
def
|
449
|
-
|
450
|
-
args_clause = underline("ARGUMENTS FOR \"#{target}\"")
|
451
|
-
synopsis = [full_executable_name, "[#{args_clause}...]"]
|
452
|
-
wrap_indent_indent2(WrappableString.new(synopsis))
|
453
|
-
end
|
454
|
-
|
455
|
-
def full_executable_name
|
456
|
-
bold(([@executable_name] + @tool.full_name).join(" "))
|
447
|
+
def full_executable_name(tool_for_name)
|
448
|
+
bold(([@executable_name] + tool_for_name.full_name).join(" "))
|
457
449
|
end
|
458
450
|
|
459
451
|
def add_source_section
|
@@ -461,15 +453,22 @@ module Toys
|
|
461
453
|
@lines << ""
|
462
454
|
@lines << bold("SOURCE")
|
463
455
|
@lines << indent_str("Defined in #{@tool.source_info.source_name}")
|
456
|
+
@delegates.each do |delegate|
|
457
|
+
@lines << indent_str("Delegated from \"#{delegate.display_name}\"" \
|
458
|
+
" defined in #{delegate.source_info.source_name}")
|
459
|
+
end
|
464
460
|
end
|
465
461
|
|
466
462
|
def add_description_section
|
467
|
-
desc = @tool.long_desc
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
463
|
+
desc = @tool.long_desc.dup
|
464
|
+
@delegates.each do |delegate|
|
465
|
+
desc << "" << "Delegated from \"#{delegate.display_name}\""
|
466
|
+
unless delegate.long_desc.empty?
|
467
|
+
desc << ""
|
468
|
+
desc += delegate.long_desc
|
469
|
+
end
|
472
470
|
end
|
471
|
+
desc = desc[1..-1] if desc.first == ""
|
473
472
|
desc = wrap_indent(desc)
|
474
473
|
return if desc.empty?
|
475
474
|
@lines << ""
|
@@ -533,10 +532,8 @@ module Toys
|
|
533
532
|
@lines << indent_str("Showing search results for \"#{@search_term}\"")
|
534
533
|
@lines << ""
|
535
534
|
end
|
536
|
-
|
537
|
-
|
538
|
-
tool_name = subtool.full_name.slice(name_len..-1).join(" ")
|
539
|
-
add_prefix_with_desc(bold(tool_name), subtool.desc)
|
535
|
+
@subtools.each do |local_name, subtool|
|
536
|
+
add_prefix_with_desc(bold(local_name), subtool.desc)
|
540
537
|
end
|
541
538
|
end
|
542
539
|
|
@@ -637,10 +634,8 @@ module Toys
|
|
637
634
|
end
|
638
635
|
|
639
636
|
def add_list
|
640
|
-
|
641
|
-
|
642
|
-
tool_name = subtool.full_name.slice(name_len..-1).join(" ")
|
643
|
-
add_prefix_with_desc(bold(tool_name), subtool.desc)
|
637
|
+
@subtools.each do |local_name, subtool|
|
638
|
+
add_prefix_with_desc(bold(local_name), subtool.desc)
|
644
639
|
end
|
645
640
|
end
|
646
641
|
|
data/lib/toys/utils/terminal.rb
CHANGED
metadata
CHANGED
@@ -1,141 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toys-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.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: 2020-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: did_you_mean
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: highline
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2.0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '2.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: minitest
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '5.14'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '5.14'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: minitest-focus
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.1'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.1'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest-rg
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '5.2'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '5.2'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rdoc
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 6.1.2
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 6.1.2
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: redcarpet
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '3.5'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '3.5'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 0.79.0
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 0.79.0
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: yard
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: 0.9.24
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 0.9.24
|
11
|
+
date: 2020-08-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
139
13
|
description: Toys-Core is the command line tool framework underlying Toys. It can
|
140
14
|
be used to create command line executables using the Toys DSL and classes.
|
141
15
|
email:
|
@@ -195,10 +69,10 @@ homepage: https://github.com/dazuma/toys
|
|
195
69
|
licenses:
|
196
70
|
- MIT
|
197
71
|
metadata:
|
198
|
-
changelog_uri: https://github.
|
72
|
+
changelog_uri: https://dazuma.github.io/toys/gems/toys-core/v0.11.0/file.CHANGELOG.html
|
199
73
|
source_code_uri: https://github.com/dazuma/toys
|
200
74
|
bug_tracker_uri: https://github.com/dazuma/toys/issues
|
201
|
-
documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.
|
75
|
+
documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.11.0
|
202
76
|
post_install_message:
|
203
77
|
rdoc_options: []
|
204
78
|
require_paths:
|