toys-core 0.15.6 → 0.16.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 +6 -1
- data/README.md +2 -2
- data/lib/toys/arg_parser.rb +2 -2
- data/lib/toys/cli.rb +8 -10
- data/lib/toys/compat.rb +11 -83
- data/lib/toys/completion.rb +3 -3
- data/lib/toys/core.rb +1 -1
- data/lib/toys/dsl/internal.rb +4 -3
- data/lib/toys/dsl/tool.rb +1 -1
- data/lib/toys/input_file.rb +3 -5
- data/lib/toys/loader.rb +2 -2
- data/lib/toys/middleware.rb +1 -1
- data/lib/toys/settings.rb +11 -2
- data/lib/toys/standard_mixins/highline.rb +12 -12
- data/lib/toys/tool_definition.rb +12 -19
- data/lib/toys/utils/exec.rb +33 -45
- data/lib/toys/utils/gems.rb +7 -7
- data/lib/toys/utils/git_cache.rb +6 -3
- data/lib/toys/utils/help_text.rb +4 -4
- data/lib/toys/utils/pager.rb +3 -5
- data/lib/toys/utils/terminal.rb +8 -12
- data/lib/toys/utils/xdg.rb +2 -2
- data/lib/toys-core.rb +2 -1
- metadata +6 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c3713d359e1b03fc22968ed9e3254c82c92e157c92146c6d5728d514eb88dc1c
|
|
4
|
+
data.tar.gz: d96baedc494f78a534a9f0a00ca64409bdbd25e1cf33ec48d2a16f59824c72b9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ca769a0b88654941c7369f9fdcf22c532ae53358c554e38817beea217d9d544d20324cd2288c8d961cd37ab2527a22e82289a3726e6d5113a7c6d42f6502a56
|
|
7
|
+
data.tar.gz: c50ff7f52713c42eed61ea3e2e81e7b53d1a75ccc89b8ceaff6f4114d71d647018ecf80c529d4254234501108dd5e9f95406e297a64d5064d3f7fa88e8297b47
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
### v0.16.0 / 2025-10-31
|
|
4
|
+
|
|
5
|
+
* ADDED: Updated minimum Ruby version to 2.7
|
|
6
|
+
* FIXED: ToolDefinition#includes_arguments no longer returns true if only default data is set
|
|
7
|
+
|
|
3
8
|
### v0.15.6 / 2024-05-15
|
|
4
9
|
|
|
5
|
-
* FIXED: Fixed argument parsing
|
|
10
|
+
* FIXED: Fixed argument parsing so flags with value delimited by "=" will support values containing newlines
|
|
6
11
|
|
|
7
12
|
### v0.15.5 / 2024-01-31
|
|
8
13
|
|
data/README.md
CHANGED
|
@@ -338,7 +338,7 @@ Detailed usage information can be found in the
|
|
|
338
338
|
|
|
339
339
|
## System requirements
|
|
340
340
|
|
|
341
|
-
Toys-Core requires Ruby 2.
|
|
341
|
+
Toys-Core requires Ruby 2.7 or later.
|
|
342
342
|
|
|
343
343
|
Most parts of Toys-Core work on JRuby. However, JRuby is not recommended
|
|
344
344
|
because of JVM boot latency, lack of support for Kernel#fork, and other issues.
|
|
@@ -348,7 +348,7 @@ recommended because it has a few known bugs that affect Toys.
|
|
|
348
348
|
|
|
349
349
|
## License
|
|
350
350
|
|
|
351
|
-
Copyright 2019-
|
|
351
|
+
Copyright 2019-2025 Daniel Azuma and the Toys contributors
|
|
352
352
|
|
|
353
353
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
354
354
|
of this software and associated documentation files (the "Software"), to deal
|
data/lib/toys/arg_parser.rb
CHANGED
|
@@ -465,7 +465,7 @@ module Toys
|
|
|
465
465
|
|
|
466
466
|
def handle_single_flags(str)
|
|
467
467
|
until str.empty?
|
|
468
|
-
str = handle_plain_flag("-#{str[0]}", str[1
|
|
468
|
+
str = handle_plain_flag("-#{str[0]}", str[1..])
|
|
469
469
|
end
|
|
470
470
|
end
|
|
471
471
|
|
|
@@ -521,7 +521,7 @@ module Toys
|
|
|
521
521
|
|
|
522
522
|
def find_flag(name)
|
|
523
523
|
flag_result = @tool.resolve_flag(name)
|
|
524
|
-
if flag_result.not_found? || @require_exact_flag_match && !flag_result.found_exact?
|
|
524
|
+
if flag_result.not_found? || (@require_exact_flag_match && !flag_result.found_exact?)
|
|
525
525
|
@errors << FlagUnrecognizedError.new(
|
|
526
526
|
value: name, suggestions: Compat.suggestions(name, @tool.used_flags)
|
|
527
527
|
)
|
data/lib/toys/cli.rb
CHANGED
|
@@ -628,17 +628,15 @@ module Toys
|
|
|
628
628
|
|
|
629
629
|
def build_executor(tool, context)
|
|
630
630
|
executor = proc do
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
yield context
|
|
638
|
-
end
|
|
639
|
-
rescue ::SignalException => e
|
|
640
|
-
handle_signal_by_tool(context, tool, e)
|
|
631
|
+
if !context[Context::Key::USAGE_ERRORS].empty?
|
|
632
|
+
handle_usage_errors(context, tool)
|
|
633
|
+
elsif !tool.runnable?
|
|
634
|
+
raise NotRunnableError, "No implementation for tool #{tool.display_name.inspect}"
|
|
635
|
+
else
|
|
636
|
+
yield context
|
|
641
637
|
end
|
|
638
|
+
rescue ::SignalException => e
|
|
639
|
+
handle_signal_by_tool(context, tool, e)
|
|
642
640
|
end
|
|
643
641
|
tool.built_middleware.reverse_each do |middleware|
|
|
644
642
|
executor = make_executor(middleware, context, executor)
|
data/lib/toys/compat.rb
CHANGED
|
@@ -4,13 +4,17 @@ require "rbconfig"
|
|
|
4
4
|
|
|
5
5
|
module Toys
|
|
6
6
|
##
|
|
7
|
-
# Compatibility wrappers for
|
|
7
|
+
# Compatibility wrappers for certain Ruby implementations and versions, and
|
|
8
|
+
# other environment differences.
|
|
8
9
|
#
|
|
9
10
|
# @private
|
|
10
11
|
#
|
|
11
12
|
module Compat
|
|
12
13
|
parts = ::RUBY_VERSION.split(".")
|
|
13
|
-
ruby_version = parts[0].to_i * 10000 + parts[1].to_i * 100 + parts[2].to_i
|
|
14
|
+
ruby_version = (parts[0].to_i * 10000) + (parts[1].to_i * 100) + parts[2].to_i
|
|
15
|
+
|
|
16
|
+
# @private
|
|
17
|
+
RUBY_VERSION_CODE = ruby_version
|
|
14
18
|
|
|
15
19
|
# @private
|
|
16
20
|
def self.jruby?
|
|
@@ -27,6 +31,11 @@ module Toys
|
|
|
27
31
|
::RbConfig::CONFIG["host_os"] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
|
28
32
|
end
|
|
29
33
|
|
|
34
|
+
# @private
|
|
35
|
+
def self.macos?
|
|
36
|
+
::RbConfig::CONFIG["host_os"] =~ /darwin/
|
|
37
|
+
end
|
|
38
|
+
|
|
30
39
|
# @private
|
|
31
40
|
def self.allow_fork?
|
|
32
41
|
!jruby? && !truffleruby? && !windows?
|
|
@@ -58,86 +67,5 @@ module Toys
|
|
|
58
67
|
[]
|
|
59
68
|
end
|
|
60
69
|
end
|
|
61
|
-
|
|
62
|
-
# The :base argument to Dir.glob requires Ruby 2.5 or later.
|
|
63
|
-
if ruby_version >= 20500
|
|
64
|
-
# @private
|
|
65
|
-
def self.glob_in_dir(glob, dir)
|
|
66
|
-
::Dir.glob(glob, base: dir)
|
|
67
|
-
end
|
|
68
|
-
else
|
|
69
|
-
# @private
|
|
70
|
-
def self.glob_in_dir(glob, dir)
|
|
71
|
-
::Dir.chdir(dir) { ::Dir.glob(glob) }
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Dir.children requires Ruby 2.5 or later.
|
|
76
|
-
if ruby_version >= 20500
|
|
77
|
-
# @private
|
|
78
|
-
def self.dir_children(dir)
|
|
79
|
-
::Dir.children(dir)
|
|
80
|
-
end
|
|
81
|
-
else
|
|
82
|
-
# @private
|
|
83
|
-
def self.dir_children(dir)
|
|
84
|
-
::Dir.entries(dir) - [".", ".."]
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Due to a bug in Ruby < 2.7, passing an empty **kwargs splat to
|
|
89
|
-
# initialize will fail if there are no formal keyword args.
|
|
90
|
-
# This also hits TruffleRuby
|
|
91
|
-
# (see https://github.com/oracle/truffleruby/issues/2567)
|
|
92
|
-
if ruby_version >= 20700 && !truffleruby?
|
|
93
|
-
# @private
|
|
94
|
-
def self.instantiate(klass, args, kwargs, block)
|
|
95
|
-
klass.new(*args, **kwargs, &block)
|
|
96
|
-
end
|
|
97
|
-
else
|
|
98
|
-
# @private
|
|
99
|
-
def self.instantiate(klass, args, kwargs, block)
|
|
100
|
-
formals = klass.instance_method(:initialize).parameters
|
|
101
|
-
if kwargs.empty? && formals.all? { |arg| arg.first != :key && arg.first != :keyrest }
|
|
102
|
-
klass.new(*args, &block)
|
|
103
|
-
else
|
|
104
|
-
klass.new(*args, **kwargs, &block)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# File.absolute_path? requires Ruby 2.7 or later. For earlier Rubies, use
|
|
110
|
-
# an ad-hoc mechanism.
|
|
111
|
-
if ruby_version >= 20700
|
|
112
|
-
# @private
|
|
113
|
-
def self.absolute_path?(path)
|
|
114
|
-
::File.absolute_path?(path)
|
|
115
|
-
end
|
|
116
|
-
elsif ::Dir.getwd =~ /^[a-zA-Z]:/
|
|
117
|
-
# @private
|
|
118
|
-
def self.absolute_path?(path)
|
|
119
|
-
/^[a-zA-Z]:/.match?(path)
|
|
120
|
-
end
|
|
121
|
-
else
|
|
122
|
-
# @private
|
|
123
|
-
def self.absolute_path?(path)
|
|
124
|
-
path.start_with?("/")
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# The second argument to method_defined? and private_method_defined?
|
|
129
|
-
# requires Ruby 2.6 or later.
|
|
130
|
-
if ruby_version >= 20600
|
|
131
|
-
# @private
|
|
132
|
-
def self.method_defined_without_ancestors?(klass, name)
|
|
133
|
-
klass.method_defined?(name, false) || klass.private_method_defined?(name, false)
|
|
134
|
-
end
|
|
135
|
-
else
|
|
136
|
-
# @private
|
|
137
|
-
def self.method_defined_without_ancestors?(klass, name)
|
|
138
|
-
klass.instance_methods(false).include?(name) ||
|
|
139
|
-
klass.private_instance_methods(false).include?(name)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
70
|
end
|
|
143
71
|
end
|
data/lib/toys/completion.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Toys
|
|
|
49
49
|
# @return [Toys::Completion::Context]
|
|
50
50
|
#
|
|
51
51
|
def with(**delta_params)
|
|
52
|
-
Context.new(**@params
|
|
52
|
+
Context.new(**@params, **delta_params)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
##
|
|
@@ -195,7 +195,7 @@ module Toys
|
|
|
195
195
|
# @private
|
|
196
196
|
#
|
|
197
197
|
def hash
|
|
198
|
-
string.hash
|
|
198
|
+
[@string, @partial].hash
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
##
|
|
@@ -295,7 +295,7 @@ module Toys
|
|
|
295
295
|
return [] unless ::File.directory?(dir)
|
|
296
296
|
prefix = nil if [".", ""].include?(prefix)
|
|
297
297
|
omits = [".", "..", ""]
|
|
298
|
-
children =
|
|
298
|
+
children = ::Dir.glob(name, base: dir).find_all do |child|
|
|
299
299
|
!omits.include?(child)
|
|
300
300
|
end
|
|
301
301
|
children += ::Dir.entries(dir).find_all do |child|
|
data/lib/toys/core.rb
CHANGED
data/lib/toys/dsl/internal.rb
CHANGED
|
@@ -12,8 +12,8 @@ module Toys
|
|
|
12
12
|
# @private A list of method names to avoid using as getters
|
|
13
13
|
#
|
|
14
14
|
AVOID_GETTERS = (::Object.instance_methods + [:run, :initialize])
|
|
15
|
-
.
|
|
16
|
-
.
|
|
15
|
+
.grep(/^[a-z]\w*$/)
|
|
16
|
+
.to_h { |name| [name, true] }
|
|
17
17
|
.freeze
|
|
18
18
|
|
|
19
19
|
class << self
|
|
@@ -109,7 +109,8 @@ module Toys
|
|
|
109
109
|
when nil
|
|
110
110
|
return if !/^[a-zA-Z]\w*[!?]?$/.match?(key.to_s) ||
|
|
111
111
|
AVOID_GETTERS.key?(key) ||
|
|
112
|
-
|
|
112
|
+
tool_class.method_defined?(key, false) ||
|
|
113
|
+
tool_class.private_method_defined?(key, false)
|
|
113
114
|
end
|
|
114
115
|
tool_class.class_eval do
|
|
115
116
|
define_method(key) do
|
data/lib/toys/dsl/tool.rb
CHANGED
|
@@ -504,7 +504,7 @@ module Toys
|
|
|
504
504
|
if template_class.nil?
|
|
505
505
|
raise ToolDefinitionError, "Template not found: #{name.inspect}"
|
|
506
506
|
end
|
|
507
|
-
template =
|
|
507
|
+
template = template_class.new(*args, **kwargs)
|
|
508
508
|
yield template if block_given?
|
|
509
509
|
class_exec(template, &template_class.expansion)
|
|
510
510
|
self
|
data/lib/toys/input_file.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
|
|
|
14
14
|
def self.evaluate(tool_class, words, priority, remaining_words, source, loader)
|
|
15
15
|
namespace = ::Module.new
|
|
16
16
|
namespace.module_eval do
|
|
17
|
-
include ::Toys::Context::Key
|
|
17
|
+
include ::Toys::Context::Key # rubocop:disable Layout/EmptyLinesAfterModuleInclusion
|
|
18
18
|
@__tool_class = tool_class
|
|
19
19
|
end
|
|
20
20
|
path = source.source_path
|
|
@@ -25,9 +25,7 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
|
|
|
25
25
|
const_set(name, namespace)
|
|
26
26
|
::Toys::DSL::Internal.prepare(tool_class, words, priority, remaining_words, source, loader) do
|
|
27
27
|
::Toys::ContextualError.capture_path("Error while loading Toys config!", path) do
|
|
28
|
-
# rubocop:disable Security/Eval
|
|
29
|
-
eval(str, __binding, path)
|
|
30
|
-
# rubocop:enable Security/Eval
|
|
28
|
+
eval(str, __binding, path) # rubocop:disable Security/Eval
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
end
|
|
@@ -48,7 +46,7 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
|
|
|
48
46
|
return nil if index.nil?
|
|
49
47
|
"#{string[0, index]}" \
|
|
50
48
|
"module #{module_name}; @__tool_class.class_eval do; " \
|
|
51
|
-
"#{string[index
|
|
49
|
+
"#{string[index..]}\n" \
|
|
52
50
|
"end; end\n"
|
|
53
51
|
end
|
|
54
52
|
end
|
data/lib/toys/loader.rb
CHANGED
|
@@ -288,7 +288,7 @@ module Toys
|
|
|
288
288
|
found_tools = all_cur_definitions.find_all do |tool|
|
|
289
289
|
name = tool.full_name
|
|
290
290
|
name.length > len && name.slice(0, len) == words &&
|
|
291
|
-
(include_hidden || name[len
|
|
291
|
+
(include_hidden || name[len..].none? { |word| word.start_with?("_") })
|
|
292
292
|
end
|
|
293
293
|
found_tools.sort_by!(&:full_name)
|
|
294
294
|
found_tools = filter_non_runnable_tools(found_tools, include_namespaces, include_non_runnable)
|
|
@@ -303,7 +303,7 @@ module Toys
|
|
|
303
303
|
# @param words [Array<String>] The name of the parent tool
|
|
304
304
|
# @return [Boolean]
|
|
305
305
|
#
|
|
306
|
-
def has_subtools?(words) # rubocop:disable Naming/
|
|
306
|
+
def has_subtools?(words) # rubocop:disable Naming/PredicatePrefix
|
|
307
307
|
load_for_prefix(words)
|
|
308
308
|
len = words.length
|
|
309
309
|
all_cur_definitions.any? do |tool|
|
data/lib/toys/middleware.rb
CHANGED
data/lib/toys/settings.rb
CHANGED
|
@@ -769,10 +769,19 @@ module Toys
|
|
|
769
769
|
attr_reader :default
|
|
770
770
|
attr_reader :group_class
|
|
771
771
|
|
|
772
|
+
##
|
|
773
|
+
# @return [boolean] Whether the field is a group
|
|
774
|
+
#
|
|
772
775
|
def group?
|
|
773
776
|
!@group_class.nil?
|
|
774
777
|
end
|
|
775
778
|
|
|
779
|
+
##
|
|
780
|
+
# Validate the given value.
|
|
781
|
+
#
|
|
782
|
+
# @return [Object] The validated value
|
|
783
|
+
# @raise [FieldError] If the value cannot be validated
|
|
784
|
+
#
|
|
776
785
|
def validate(value)
|
|
777
786
|
validated_value = @type.call(value)
|
|
778
787
|
if validated_value == ILLEGAL_VALUE
|
|
@@ -877,8 +886,8 @@ module Toys
|
|
|
877
886
|
raise ::ArgumentError, "Illegal settings field name: #{name}"
|
|
878
887
|
end
|
|
879
888
|
existing = public_instance_methods(false)
|
|
880
|
-
if existing.include?(name.to_sym) || existing.include?("#{name}="
|
|
881
|
-
existing.include?("#{name}_set?"
|
|
889
|
+
if existing.include?(name.to_sym) || existing.include?(:"#{name}=") ||
|
|
890
|
+
existing.include?(:"#{name}_set?") || existing.include?(:"#{name}_unset!")
|
|
882
891
|
raise ::ArgumentError, "Settings field already exists: #{name}"
|
|
883
892
|
end
|
|
884
893
|
name.to_sym
|
|
@@ -48,43 +48,43 @@ module Toys
|
|
|
48
48
|
##
|
|
49
49
|
# Calls [HighLine#agree](https://www.rubydoc.info/gems/highline/HighLine:agree)
|
|
50
50
|
#
|
|
51
|
-
def agree(
|
|
52
|
-
self[KEY].agree(
|
|
51
|
+
def agree(...)
|
|
52
|
+
self[KEY].agree(...)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
##
|
|
56
56
|
# Calls [HighLine#ask](https://www.rubydoc.info/gems/highline/HighLine:ask)
|
|
57
57
|
#
|
|
58
|
-
def ask(
|
|
59
|
-
self[KEY].ask(
|
|
58
|
+
def ask(...)
|
|
59
|
+
self[KEY].ask(...)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
##
|
|
63
63
|
# Calls [HighLine#choose](https://www.rubydoc.info/gems/highline/HighLine:choose)
|
|
64
64
|
#
|
|
65
|
-
def choose(
|
|
66
|
-
self[KEY].choose(
|
|
65
|
+
def choose(...)
|
|
66
|
+
self[KEY].choose(...)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
##
|
|
70
70
|
# Calls [HighLine#list](https://www.rubydoc.info/gems/highline/HighLine:list)
|
|
71
71
|
#
|
|
72
|
-
def list(
|
|
73
|
-
self[KEY].list(
|
|
72
|
+
def list(...)
|
|
73
|
+
self[KEY].list(...)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
##
|
|
77
77
|
# Calls [HighLine#say](https://www.rubydoc.info/gems/highline/HighLine:say)
|
|
78
78
|
#
|
|
79
|
-
def say(
|
|
80
|
-
self[KEY].say(
|
|
79
|
+
def say(...)
|
|
80
|
+
self[KEY].say(...)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
##
|
|
84
84
|
# Calls [HighLine#indent](https://www.rubydoc.info/gems/highline/HighLine:indent)
|
|
85
85
|
#
|
|
86
|
-
def indent(
|
|
87
|
-
self[KEY].indent(
|
|
86
|
+
def indent(...)
|
|
87
|
+
self[KEY].indent(...)
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
##
|
data/lib/toys/tool_definition.rb
CHANGED
|
@@ -552,9 +552,8 @@ module Toys
|
|
|
552
552
|
# @return [true,false]
|
|
553
553
|
#
|
|
554
554
|
def runnable?
|
|
555
|
-
@run_handler.is_a?(::
|
|
556
|
-
tool_class.public_instance_methods(false).include?(@run_handler)
|
|
557
|
-
@run_handler.is_a?(::Proc)
|
|
555
|
+
@run_handler.is_a?(::Proc) ||
|
|
556
|
+
(@run_handler.is_a?(::Symbol) && tool_class.public_instance_methods(false).include?(@run_handler))
|
|
558
557
|
end
|
|
559
558
|
|
|
560
559
|
##
|
|
@@ -608,8 +607,7 @@ module Toys
|
|
|
608
607
|
# @return [true,false]
|
|
609
608
|
#
|
|
610
609
|
def includes_arguments?
|
|
611
|
-
!
|
|
612
|
-
!required_args.empty? || !optional_args.empty? ||
|
|
610
|
+
!flags.empty? || !required_args.empty? || !optional_args.empty? ||
|
|
613
611
|
!remaining_arg.nil? || flags_before_args_enforced?
|
|
614
612
|
end
|
|
615
613
|
|
|
@@ -619,7 +617,7 @@ module Toys
|
|
|
619
617
|
#
|
|
620
618
|
def includes_definition?
|
|
621
619
|
includes_arguments? || runnable? || argument_parsing_disabled? ||
|
|
622
|
-
includes_modules? || includes_description?
|
|
620
|
+
includes_modules? || includes_description? || !default_data.empty?
|
|
623
621
|
end
|
|
624
622
|
|
|
625
623
|
##
|
|
@@ -690,7 +688,7 @@ module Toys
|
|
|
690
688
|
# @return [nil] if no acceptor of the given name is found.
|
|
691
689
|
#
|
|
692
690
|
def lookup_acceptor(name)
|
|
693
|
-
@acceptors.fetch(name.to_s) { |k| @parent
|
|
691
|
+
@acceptors.fetch(name.to_s) { |k| @parent&.lookup_acceptor(k) }
|
|
694
692
|
end
|
|
695
693
|
|
|
696
694
|
##
|
|
@@ -701,7 +699,7 @@ module Toys
|
|
|
701
699
|
# @return [nil] if no template of the given name is found.
|
|
702
700
|
#
|
|
703
701
|
def lookup_template(name)
|
|
704
|
-
@templates.fetch(name.to_s) { |k| @parent
|
|
702
|
+
@templates.fetch(name.to_s) { |k| @parent&.lookup_template(k) }
|
|
705
703
|
end
|
|
706
704
|
|
|
707
705
|
##
|
|
@@ -712,7 +710,7 @@ module Toys
|
|
|
712
710
|
# @return [nil] if no mixin of the given name is found.
|
|
713
711
|
#
|
|
714
712
|
def lookup_mixin(name)
|
|
715
|
-
@mixins.fetch(name.to_s) { |k| @parent
|
|
713
|
+
@mixins.fetch(name.to_s) { |k| @parent&.lookup_mixin(k) }
|
|
716
714
|
end
|
|
717
715
|
|
|
718
716
|
##
|
|
@@ -723,7 +721,7 @@ module Toys
|
|
|
723
721
|
# @return [nil] if no completion of the given name is found.
|
|
724
722
|
#
|
|
725
723
|
def lookup_completion(name)
|
|
726
|
-
@completions.fetch(name.to_s) { |k| @parent
|
|
724
|
+
@completions.fetch(name.to_s) { |k| @parent&.lookup_completion(k) }
|
|
727
725
|
end
|
|
728
726
|
|
|
729
727
|
##
|
|
@@ -1347,15 +1345,10 @@ module Toys
|
|
|
1347
1345
|
"Cannot delegate tool #{display_name.inspect} to #{target.join(' ')} because it" \
|
|
1348
1346
|
" already delegates to \"#{@delegate_target.join(' ')}\"."
|
|
1349
1347
|
end
|
|
1350
|
-
if includes_arguments?
|
|
1351
|
-
raise ToolDefinitionError,
|
|
1352
|
-
"Cannot delegate tool #{display_name.inspect} because" \
|
|
1353
|
-
" arguments have already been defined."
|
|
1354
|
-
end
|
|
1355
|
-
if runnable?
|
|
1348
|
+
if includes_arguments? || runnable? || includes_modules? || !default_data.empty?
|
|
1356
1349
|
raise ToolDefinitionError,
|
|
1357
1350
|
"Cannot delegate tool #{display_name.inspect} because" \
|
|
1358
|
-
"
|
|
1351
|
+
" some implementation has already been created for it."
|
|
1359
1352
|
end
|
|
1360
1353
|
disable_argument_parsing
|
|
1361
1354
|
self.run_handler = make_delegation_run_handler(target)
|
|
@@ -1393,7 +1386,7 @@ module Toys
|
|
|
1393
1386
|
def finish_definition(loader)
|
|
1394
1387
|
unless @definition_finished
|
|
1395
1388
|
ContextualError.capture("Error installing tool middleware!", tool_name: full_name) do
|
|
1396
|
-
config_proc = proc {
|
|
1389
|
+
config_proc = proc {}
|
|
1397
1390
|
@built_middleware.reverse_each do |middleware|
|
|
1398
1391
|
config_proc = make_config_proc(middleware, loader, config_proc)
|
|
1399
1392
|
end
|
|
@@ -1493,7 +1486,7 @@ module Toys
|
|
|
1493
1486
|
case signal
|
|
1494
1487
|
when ::String, ::Symbol
|
|
1495
1488
|
sigstr = signal.to_s
|
|
1496
|
-
sigstr = sigstr[3
|
|
1489
|
+
sigstr = sigstr[3..] if sigstr.start_with?("SIG")
|
|
1497
1490
|
signo = ::Signal.list[sigstr]
|
|
1498
1491
|
return signo if signo
|
|
1499
1492
|
when ::Integer
|
data/lib/toys/utils/exec.rb
CHANGED
|
@@ -304,7 +304,7 @@ module Toys
|
|
|
304
304
|
if cmd.is_a?(::Array)
|
|
305
305
|
if cmd.size > 1
|
|
306
306
|
binary = canonical_binary_spec(cmd.first, exec_opts)
|
|
307
|
-
[binary] + cmd[1
|
|
307
|
+
[binary] + cmd[1..].map(&:to_s)
|
|
308
308
|
else
|
|
309
309
|
[canonical_binary_spec(Array(cmd.first), exec_opts)]
|
|
310
310
|
end
|
|
@@ -521,14 +521,12 @@ module Toys
|
|
|
521
521
|
def capture(which)
|
|
522
522
|
stream = stream_for(which)
|
|
523
523
|
@join_threads << ::Thread.new do
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
@
|
|
527
|
-
@captures[which] = data
|
|
528
|
-
end
|
|
529
|
-
ensure
|
|
530
|
-
stream.close
|
|
524
|
+
data = stream.read
|
|
525
|
+
@mutex.synchronize do
|
|
526
|
+
@captures[which] = data
|
|
531
527
|
end
|
|
528
|
+
ensure
|
|
529
|
+
stream.close
|
|
532
530
|
end
|
|
533
531
|
self
|
|
534
532
|
end
|
|
@@ -577,16 +575,14 @@ module Toys
|
|
|
577
575
|
end
|
|
578
576
|
stream = stream_for(which, allow_in: true)
|
|
579
577
|
@join_threads << ::Thread.new do
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
::IO.copy_stream(stream, io)
|
|
585
|
-
end
|
|
586
|
-
ensure
|
|
587
|
-
stream.close
|
|
588
|
-
io.close
|
|
578
|
+
if which == :in
|
|
579
|
+
::IO.copy_stream(io, stream)
|
|
580
|
+
else
|
|
581
|
+
::IO.copy_stream(stream, io)
|
|
589
582
|
end
|
|
583
|
+
ensure
|
|
584
|
+
stream.close
|
|
585
|
+
io.close
|
|
590
586
|
end
|
|
591
587
|
self
|
|
592
588
|
end
|
|
@@ -1065,7 +1061,7 @@ module Toys
|
|
|
1065
1061
|
else
|
|
1066
1062
|
cmd_binary = @spawn_cmd.first
|
|
1067
1063
|
cmd_binary = cmd_binary.first if cmd_binary.is_a?(::Array)
|
|
1068
|
-
"exec: #{([cmd_binary] + @spawn_cmd[1
|
|
1064
|
+
"exec: #{([cmd_binary] + @spawn_cmd[1..]).inspect}"
|
|
1069
1065
|
end
|
|
1070
1066
|
end
|
|
1071
1067
|
end
|
|
@@ -1218,7 +1214,7 @@ module Toys
|
|
|
1218
1214
|
|
|
1219
1215
|
def interpret_in_array(setting)
|
|
1220
1216
|
if setting.first.is_a?(::Symbol)
|
|
1221
|
-
setup_in_stream_of_type(setting.first, setting[1
|
|
1217
|
+
setup_in_stream_of_type(setting.first, setting[1..])
|
|
1222
1218
|
elsif setting.first.is_a?(::String)
|
|
1223
1219
|
setup_in_stream_of_type(:file, setting)
|
|
1224
1220
|
elsif setting.size == 2 && setting.first.is_a?(::IO) && setting.last.is_a?(::IO)
|
|
@@ -1292,7 +1288,7 @@ module Toys
|
|
|
1292
1288
|
|
|
1293
1289
|
def interpret_out_array(key, setting)
|
|
1294
1290
|
if setting.first.is_a?(::Symbol)
|
|
1295
|
-
setup_out_stream_of_type(key, setting.first, setting[1
|
|
1291
|
+
setup_out_stream_of_type(key, setting.first, setting[1..])
|
|
1296
1292
|
elsif setting.first.is_a?(::String)
|
|
1297
1293
|
setup_out_stream_of_type(key, :file, setting)
|
|
1298
1294
|
elsif setting.size == 2 && setting.first.is_a?(::IO) && setting.last.is_a?(::IO)
|
|
@@ -1381,7 +1377,7 @@ module Toys
|
|
|
1381
1377
|
(arg.first == :autoclose || arg.first.is_a?(::IO))
|
|
1382
1378
|
[arg.last, :close]
|
|
1383
1379
|
else
|
|
1384
|
-
arg = arg[1
|
|
1380
|
+
arg = arg[1..] if arg.first == :file
|
|
1385
1381
|
if arg.empty? || !arg.first.is_a?(::String)
|
|
1386
1382
|
raise "Expected file name for #{key} tee argument"
|
|
1387
1383
|
end
|
|
@@ -1498,49 +1494,41 @@ module Toys
|
|
|
1498
1494
|
def write_string_thread(string)
|
|
1499
1495
|
stream = make_in_pipe
|
|
1500
1496
|
@join_threads << ::Thread.new do
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
stream.close
|
|
1505
|
-
end
|
|
1497
|
+
stream.write string
|
|
1498
|
+
ensure
|
|
1499
|
+
stream.close
|
|
1506
1500
|
end
|
|
1507
1501
|
end
|
|
1508
1502
|
|
|
1509
1503
|
def copy_to_in_thread(io)
|
|
1510
1504
|
stream = make_in_pipe
|
|
1511
1505
|
@join_threads << ::Thread.new do
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
io.close
|
|
1517
|
-
end
|
|
1506
|
+
::IO.copy_stream(io, stream)
|
|
1507
|
+
ensure
|
|
1508
|
+
stream.close
|
|
1509
|
+
io.close
|
|
1518
1510
|
end
|
|
1519
1511
|
end
|
|
1520
1512
|
|
|
1521
1513
|
def copy_from_out_thread(key, io)
|
|
1522
1514
|
stream = make_out_pipe(key)
|
|
1523
1515
|
@join_threads << ::Thread.new do
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
io.close
|
|
1529
|
-
end
|
|
1516
|
+
::IO.copy_stream(stream, io)
|
|
1517
|
+
ensure
|
|
1518
|
+
stream.close
|
|
1519
|
+
io.close
|
|
1530
1520
|
end
|
|
1531
1521
|
end
|
|
1532
1522
|
|
|
1533
1523
|
def capture_stream_thread(key)
|
|
1534
1524
|
stream = make_out_pipe(key)
|
|
1535
1525
|
@join_threads << ::Thread.new do
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
@
|
|
1539
|
-
@captures[key] = data
|
|
1540
|
-
end
|
|
1541
|
-
ensure
|
|
1542
|
-
stream.close
|
|
1526
|
+
data = stream.read
|
|
1527
|
+
@mutex.synchronize do
|
|
1528
|
+
@captures[key] = data
|
|
1543
1529
|
end
|
|
1530
|
+
ensure
|
|
1531
|
+
stream.close
|
|
1544
1532
|
end
|
|
1545
1533
|
end
|
|
1546
1534
|
end
|
data/lib/toys/utils/gems.rb
CHANGED
|
@@ -146,11 +146,9 @@ module Toys
|
|
|
146
146
|
#
|
|
147
147
|
def activate(name, *requirements)
|
|
148
148
|
Gems.synchronize do
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
handle_activation_error(e, name, requirements)
|
|
153
|
-
end
|
|
149
|
+
gem(name, *requirements)
|
|
150
|
+
rescue ::Gem::LoadError => e
|
|
151
|
+
handle_activation_error(e, name, requirements)
|
|
154
152
|
end
|
|
155
153
|
end
|
|
156
154
|
|
|
@@ -395,7 +393,7 @@ module Toys
|
|
|
395
393
|
modified_lockfile_path = find_lockfile_path(modified_gemfile_path)
|
|
396
394
|
if ::File.readable?(lockfile_path)
|
|
397
395
|
lockfile_content = ::File.read(lockfile_path)
|
|
398
|
-
::File.
|
|
396
|
+
::File.write(modified_lockfile_path, lockfile_content)
|
|
399
397
|
end
|
|
400
398
|
modified_gemfile_path
|
|
401
399
|
end
|
|
@@ -423,9 +421,11 @@ module Toys
|
|
|
423
421
|
end
|
|
424
422
|
|
|
425
423
|
def delete_modified_gemfile(modified_gemfile_path)
|
|
424
|
+
# rubocop:disable Lint/NonAtomicFileOperation
|
|
426
425
|
::File.delete(modified_gemfile_path) if ::File.exist?(modified_gemfile_path)
|
|
427
426
|
modified_lockfile_path = find_lockfile_path(modified_gemfile_path)
|
|
428
427
|
::File.delete(modified_lockfile_path) if ::File.exist?(modified_lockfile_path)
|
|
428
|
+
# rubocop:enable Lint/NonAtomicFileOperation
|
|
429
429
|
end
|
|
430
430
|
|
|
431
431
|
def restore_toys_libs
|
|
@@ -465,7 +465,7 @@ module Toys
|
|
|
465
465
|
return if result.success?
|
|
466
466
|
terminal.puts("Failed to update. Trying update with clean lockfile...")
|
|
467
467
|
lockfile_path = find_lockfile_path(gemfile_path)
|
|
468
|
-
::File.delete(lockfile_path) if ::File.exist?(lockfile_path)
|
|
468
|
+
::File.delete(lockfile_path) if ::File.exist?(lockfile_path) # rubocop:disable Lint/NonAtomicFileOperation
|
|
469
469
|
result = exec_util.exec_ruby([bundler_bin, "update"] + args)
|
|
470
470
|
return if result.success?
|
|
471
471
|
raise ::Bundler::InstallError, "Failed to install or update bundle: #{gemfile_path}"
|
data/lib/toys/utils/git_cache.rb
CHANGED
|
@@ -545,7 +545,7 @@ module Toys
|
|
|
545
545
|
repo_dir = ::File.join(dir, REPO_DIR_NAME)
|
|
546
546
|
is_sha = commit =~ /^[0-9a-f]{40}$/
|
|
547
547
|
update = repo_lock.ref_stale?(commit, update) unless is_sha
|
|
548
|
-
if update && !is_sha || !commit_exists?(repo_dir, local_commit)
|
|
548
|
+
if (update && !is_sha) || !commit_exists?(repo_dir, local_commit)
|
|
549
549
|
git(repo_dir, ["fetch", "--depth=1", "--force", "origin", "#{commit}:#{local_commit}"],
|
|
550
550
|
error_message: "Unable to fetch commit: #{commit}")
|
|
551
551
|
repo_lock.update_ref!(commit)
|
|
@@ -579,7 +579,7 @@ module Toys
|
|
|
579
579
|
repo_path = ::File.join(dir, REPO_DIR_NAME)
|
|
580
580
|
::FileUtils.mkdir_p(into)
|
|
581
581
|
::FileUtils.chmod_R("u+w", into, force: true)
|
|
582
|
-
|
|
582
|
+
::Dir.children(into).each { |child| ::FileUtils.rm_rf(::File.join(into, child)) }
|
|
583
583
|
result = copy_from_repo(repo_path, into, sha, path)
|
|
584
584
|
repo_lock.access_repo!
|
|
585
585
|
result
|
|
@@ -588,7 +588,7 @@ module Toys
|
|
|
588
588
|
def copy_from_repo(repo_dir, into, sha, path)
|
|
589
589
|
git(repo_dir, ["checkout", sha])
|
|
590
590
|
if path == "."
|
|
591
|
-
|
|
591
|
+
::Dir.children(repo_dir).each do |entry|
|
|
592
592
|
next if entry == ".git"
|
|
593
593
|
to_path = ::File.join(into, entry)
|
|
594
594
|
unless ::File.exist?(to_path)
|
|
@@ -746,6 +746,9 @@ module Toys
|
|
|
746
746
|
@data["sources"][sha]&.fetch(path, nil)
|
|
747
747
|
end
|
|
748
748
|
|
|
749
|
+
##
|
|
750
|
+
# @private
|
|
751
|
+
#
|
|
749
752
|
def find_sources(paths: nil, shas: nil)
|
|
750
753
|
results = []
|
|
751
754
|
@data["sources"].each do |sha, sha_data|
|
data/lib/toys/utils/help_text.rb
CHANGED
|
@@ -312,7 +312,7 @@ module Toys
|
|
|
312
312
|
remaining_doc = desc
|
|
313
313
|
if initial.size <= @indent + @left_column_width
|
|
314
314
|
@lines << "#{initial} #{desc.first}"
|
|
315
|
-
remaining_doc = desc[1
|
|
315
|
+
remaining_doc = desc[1..] || []
|
|
316
316
|
else
|
|
317
317
|
@lines << initial
|
|
318
318
|
end
|
|
@@ -398,7 +398,7 @@ module Toys
|
|
|
398
398
|
else
|
|
399
399
|
desc = wrap_indent_indent2(WrappableString.new(["#{prefix} -"] + desc.fragments))
|
|
400
400
|
@lines << indent_str(desc[0])
|
|
401
|
-
desc[1
|
|
401
|
+
desc[1..].each do |line|
|
|
402
402
|
@lines << indent2_str(line)
|
|
403
403
|
end
|
|
404
404
|
end
|
|
@@ -523,7 +523,7 @@ module Toys
|
|
|
523
523
|
desc += delegate.long_desc
|
|
524
524
|
end
|
|
525
525
|
end
|
|
526
|
-
desc = desc[1
|
|
526
|
+
desc = desc[1..] if desc.first == ""
|
|
527
527
|
desc = wrap_indent(desc)
|
|
528
528
|
return if desc.empty?
|
|
529
529
|
@lines << ""
|
|
@@ -728,7 +728,7 @@ module Toys
|
|
|
728
728
|
else
|
|
729
729
|
desc = wrap_indent(WrappableString.new(["#{prefix} -"] + desc.fragments))
|
|
730
730
|
@lines << desc[0]
|
|
731
|
-
desc[1
|
|
731
|
+
desc[1..].each do |line|
|
|
732
732
|
@lines << indent_str(line)
|
|
733
733
|
end
|
|
734
734
|
end
|
data/lib/toys/utils/pager.rb
CHANGED
|
@@ -64,11 +64,9 @@ module Toys
|
|
|
64
64
|
def start
|
|
65
65
|
if @command
|
|
66
66
|
result = @exec_service.exec(@command, in: :controller) do |controller|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
raise e unless @rescue_broken_pipes
|
|
71
|
-
end
|
|
67
|
+
yield controller.in if controller.pid
|
|
68
|
+
rescue ::Errno::EPIPE => e
|
|
69
|
+
raise e unless @rescue_broken_pipes
|
|
72
70
|
end
|
|
73
71
|
return result.exit_code unless result.failed?
|
|
74
72
|
end
|
data/lib/toys/utils/terminal.rb
CHANGED
|
@@ -155,12 +155,10 @@ module Toys
|
|
|
155
155
|
#
|
|
156
156
|
def write(str = "", *styles)
|
|
157
157
|
@output_mutex.synchronize do
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
nil
|
|
163
|
-
end
|
|
158
|
+
output&.write(apply_styles(str.to_s, *styles))
|
|
159
|
+
output&.flush
|
|
160
|
+
rescue ::IOError
|
|
161
|
+
nil
|
|
164
162
|
end
|
|
165
163
|
self
|
|
166
164
|
end
|
|
@@ -173,11 +171,9 @@ module Toys
|
|
|
173
171
|
#
|
|
174
172
|
def readline
|
|
175
173
|
@input_mutex.synchronize do
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
nil
|
|
180
|
-
end
|
|
174
|
+
input&.gets
|
|
175
|
+
rescue ::IOError
|
|
176
|
+
nil
|
|
181
177
|
end
|
|
182
178
|
end
|
|
183
179
|
|
|
@@ -470,7 +466,7 @@ module Toys
|
|
|
470
466
|
@terminal.write(@frames[@cur_frame][0])
|
|
471
467
|
@cond.wait(@frame_length)
|
|
472
468
|
size = @frames[@cur_frame][1]
|
|
473
|
-
@terminal.write("\b" * size + " " * size + "\b" * size)
|
|
469
|
+
@terminal.write(("\b" * size) + (" " * size) + ("\b" * size))
|
|
474
470
|
@cur_frame += 1
|
|
475
471
|
@cur_frame = 0 if @cur_frame >= @frames.size
|
|
476
472
|
end
|
data/lib/toys/utils/xdg.rb
CHANGED
|
@@ -260,7 +260,7 @@ module Toys
|
|
|
260
260
|
|
|
261
261
|
def validate_dir_env(name)
|
|
262
262
|
path = @env[name].to_s
|
|
263
|
-
!path.empty? &&
|
|
263
|
+
!path.empty? && ::File.absolute_path?(path) ? path : nil
|
|
264
264
|
end
|
|
265
265
|
|
|
266
266
|
def validate_dirs_env(name)
|
|
@@ -268,7 +268,7 @@ module Toys
|
|
|
268
268
|
end
|
|
269
269
|
|
|
270
270
|
def validate_dirs(paths)
|
|
271
|
-
paths = paths.find_all { |path|
|
|
271
|
+
paths = paths.find_all { |path| ::File.absolute_path?(path) }
|
|
272
272
|
paths.empty? ? nil : paths
|
|
273
273
|
end
|
|
274
274
|
|
data/lib/toys-core.rb
CHANGED
|
@@ -120,10 +120,11 @@ module Toys
|
|
|
120
120
|
CORE_LIB_PATH = __dir__
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
+
require "toys/compat"
|
|
124
|
+
|
|
123
125
|
require "toys/acceptor"
|
|
124
126
|
require "toys/arg_parser"
|
|
125
127
|
require "toys/cli"
|
|
126
|
-
require "toys/compat"
|
|
127
128
|
require "toys/completion"
|
|
128
129
|
require "toys/context"
|
|
129
130
|
require "toys/core"
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: toys-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Azuma
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
12
|
description: Toys-Core is the command line tool framework underlying Toys. It can
|
|
14
13
|
be used to create command line executables using the Toys DSL and classes.
|
|
@@ -79,11 +78,10 @@ homepage: https://github.com/dazuma/toys
|
|
|
79
78
|
licenses:
|
|
80
79
|
- MIT
|
|
81
80
|
metadata:
|
|
82
|
-
changelog_uri: https://dazuma.github.io/toys/gems/toys-core/v0.
|
|
81
|
+
changelog_uri: https://dazuma.github.io/toys/gems/toys-core/v0.16.0/file.CHANGELOG.html
|
|
83
82
|
source_code_uri: https://github.com/dazuma/toys/tree/main/toys-core
|
|
84
83
|
bug_tracker_uri: https://github.com/dazuma/toys/issues
|
|
85
|
-
documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.
|
|
86
|
-
post_install_message:
|
|
84
|
+
documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.16.0
|
|
87
85
|
rdoc_options: []
|
|
88
86
|
require_paths:
|
|
89
87
|
- lib
|
|
@@ -91,15 +89,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
91
89
|
requirements:
|
|
92
90
|
- - ">="
|
|
93
91
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: 2.
|
|
92
|
+
version: 2.7.0
|
|
95
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
94
|
requirements:
|
|
97
95
|
- - ">="
|
|
98
96
|
- !ruby/object:Gem::Version
|
|
99
97
|
version: '0'
|
|
100
98
|
requirements: []
|
|
101
|
-
rubygems_version: 3.
|
|
102
|
-
signing_key:
|
|
99
|
+
rubygems_version: 3.6.9
|
|
103
100
|
specification_version: 4
|
|
104
101
|
summary: Framework for creating command line executables
|
|
105
102
|
test_files: []
|