toys-core 0.14.1 → 0.14.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49f6342ac835f193218570f20cc534fc7f1d4fab14742602df3a7174cfc8a554
4
- data.tar.gz: 27b8298897b5c8fd08319fffec33540c057675ed8655700280b4837f413cc635
3
+ metadata.gz: de679852961f700752c16ccbec8b08bf28390070ce6e7a29f6d34bf6dd9a1ba3
4
+ data.tar.gz: b149a5af7458b8ef26bb2a12dcc3ede565af9450780e8de7d132576550c65217
5
5
  SHA512:
6
- metadata.gz: 55dc00e57b5c6b3212ed24d45bb3a595dae8b5b6fd076ddefdbe4835d621dfeb70d58b8551ae69a8190dc3884a66968e78b800d93b07eed6b61d42eef70faea7
7
- data.tar.gz: eb6b5c306c815947290a8fb99834a4a809052edf7e6c781f1b562c61217cf49c63a9609beb168b0e06c5e09ace51083bbb7da15ad58746e72fc5017e04f9546d
6
+ metadata.gz: f7dc86145d43b4c778da09c6f31195a89aa62eab6a2bb4ef2efe1100b18863b17854540f07711c255c9eb95f8f2232c53808bdef87e0237fd8ec541c0bbc79cd
7
+ data.tar.gz: 50f4c29636dca1fe75c94a7d53dc23315ba6f49e5f7e1ac39e13cd4f0459fbdf57b3eccee159558476042f9a8aaa831f7bcf3c86bb2dd976b02f63e029fe67a8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Release History
2
2
 
3
+ ### v0.14.2 / 2022-10-09
4
+
5
+ * ADDED: The tool directive supports the delegate_relative argument, as a preferred alternative over alias_tool.
6
+ * FIXED: The toys file reference now properly appears in error messages on Ruby 3.1.
7
+ * FIXED: Error messages show the correct toys file line number on TruffleRuby.
8
+ * FIXED: Inspect strings for tool classes are less opaque and include the tool name.
9
+ * FIXED: The presence of an acceptor forces an ambiguous flag to take a value rather than erroring.
10
+
3
11
  ### v0.14.1 / 2022-10-03
4
12
 
5
13
  * (No significant changes)
data/lib/toys/context.rb CHANGED
@@ -338,12 +338,15 @@ module Toys
338
338
  end
339
339
 
340
340
  ##
341
+ # Include the tool name in the object inspection dump.
342
+ #
341
343
  # @private
342
344
  #
343
345
  def inspect
344
- name = Array(@__data[Key::TOOL_NAME]).join(" ")
346
+ words = Array(@__data[Key::TOOL_NAME])
347
+ name = words.empty? ? "(root)" : words.join(" ").inspect
345
348
  id = object_id.to_s(16)
346
- "#<Toys::Context id=0x#{id} #{name}>"
349
+ "#<Toys::Context id=0x#{id} tool=#{name}>"
347
350
  end
348
351
  end
349
352
  end
data/lib/toys/core.rb CHANGED
@@ -9,7 +9,7 @@ module Toys
9
9
  # Current version of Toys core.
10
10
  # @return [String]
11
11
  #
12
- VERSION = "0.14.1"
12
+ VERSION = "0.14.2"
13
13
  end
14
14
 
15
15
  ##
@@ -68,6 +68,24 @@ module Toys
68
68
  end
69
69
  end
70
70
 
71
+ ##
72
+ # Called by the DSL implementation to analyze the name of a new tool
73
+ # definition in context.
74
+ #
75
+ # @private
76
+ #
77
+ def analyze_name(tool_class, words)
78
+ loader = tool_class.instance_variable_get(:@__loader)
79
+ subtool_words = tool_class.instance_variable_get(:@__words).dup
80
+ next_remaining = tool_class.instance_variable_get(:@__remaining_words)
81
+ loader.split_path(words).each do |word|
82
+ word = word.to_s
83
+ subtool_words << word
84
+ next_remaining = Loader.next_remaining_words(next_remaining, word)
85
+ end
86
+ [subtool_words, next_remaining]
87
+ end
88
+
71
89
  ##
72
90
  # Called by the DSL implementation to add a getter to the tool class.
73
91
  #
data/lib/toys/dsl/tool.rb CHANGED
@@ -273,7 +273,8 @@ module Toys
273
273
  # end
274
274
  # end
275
275
  #
276
- # The following example defines a tool that runs one of its subtools.
276
+ # The following example uses `delegate_to` to define a tool that runs one
277
+ # of its subtools.
277
278
  #
278
279
  # tool "test", delegate_to: ["test", "unit"] do
279
280
  # tool "unit" do
@@ -294,17 +295,14 @@ module Toys
294
295
  # delegate to another tool, specified by the full path. This path may
295
296
  # be given as an array of strings, or a single string possibly
296
297
  # delimited by path separators.
298
+ # @param delegate_relative [String,Array<String>] Optional. Similar to
299
+ # delegate_to, but takes a delegate name relative to the context in
300
+ # which this tool is being defined.
297
301
  # @param block [Proc] Defines the subtool.
298
302
  # @return [self]
299
303
  #
300
- def tool(words, if_defined: :combine, delegate_to: nil, &block)
301
- subtool_words = @__words.dup
302
- next_remaining = @__remaining_words
303
- @__loader.split_path(words).each do |word|
304
- word = word.to_s
305
- subtool_words << word
306
- next_remaining = Loader.next_remaining_words(next_remaining, word)
307
- end
304
+ def tool(words, if_defined: :combine, delegate_to: nil, delegate_relative: nil, &block)
305
+ subtool_words, next_remaining = DSL::Internal.analyze_name(self, words)
308
306
  subtool = @__loader.get_tool(subtool_words, @__priority)
309
307
  if subtool.includes_definition?
310
308
  case if_defined
@@ -314,9 +312,14 @@ module Toys
314
312
  subtool.reset_definition
315
313
  end
316
314
  end
317
- if delegate_to
318
- delegator = proc { self.delegate_to(delegate_to) }
319
- @__loader.load_block(source_info, delegator, subtool_words, next_remaining, @__priority)
315
+ if delegate_to || delegate_relative
316
+ delegate_to2 = @__words + @__loader.split_path(delegate_relative) if delegate_relative
317
+ orig_block = block
318
+ block = proc do
319
+ self.delegate_to(delegate_to) if delegate_to
320
+ self.delegate_to(delegate_to2) if delegate_to2
321
+ instance_eval(&orig_block) if orig_block
322
+ end
320
323
  end
321
324
  if block
322
325
  @__loader.load_block(source_info, block, subtool_words, next_remaining, @__priority)
@@ -327,9 +330,9 @@ module Toys
327
330
  ##
328
331
  # Create an alias, representing an "alternate name" for a tool.
329
332
  #
330
- # This is functionally equivalent to creating a subtool with the
331
- # `delegate_to` option, except that `alias_tool` takes a _relative_ name
332
- # for the delegate.
333
+ # Note: This is functionally equivalent to creating a tool with the
334
+ # `:delegate_relative` option. As such, `alias_tool` is considered
335
+ # deprecated.
333
336
  #
334
337
  # ### Example
335
338
  #
@@ -342,21 +345,25 @@ module Toys
342
345
  # end
343
346
  # end
344
347
  # alias_tool "t", "test"
348
+ # # Note: the following is preferred over alias_tool:
349
+ # # tool "t", delegate_relative: "test"
345
350
  #
346
351
  # @param word [String] The name of the alias
347
352
  # @param target [String,Array<String>] Relative path to the target of the
348
353
  # alias. This path may be given as an array of strings, or a single
349
354
  # string possibly delimited by path separators.
350
355
  # @return [self]
356
+ # @deprecated Use {#tool} and pass `:delegate_relative` instead
351
357
  #
352
358
  def alias_tool(word, target)
353
- tool(word, delegate_to: @__words + @__loader.split_path(target))
359
+ tool(word, delegate_relative: target)
354
360
  self
355
361
  end
356
362
 
357
363
  ##
358
- # Causes the current tool to delegate to another tool. When run, it
359
- # simply invokes the target tool with the same arguments.
364
+ # Causes the current tool to delegate to another tool, specified by the
365
+ # full tool name. When run, it simply invokes the target tool with the
366
+ # same arguments.
360
367
  #
361
368
  # ### Example
362
369
  #
@@ -1721,6 +1728,18 @@ module Toys
1721
1728
  super
1722
1729
  DSL::Internal.current_tool(self, true)&.check_definition_state(is_method: true)
1723
1730
  end
1731
+
1732
+ ##
1733
+ # Include the tool name in the class inspection dump.
1734
+ #
1735
+ # @private
1736
+ #
1737
+ def inspect
1738
+ return super unless defined? @__words
1739
+ name = @__words.empty? ? "(root)" : @__words.join(" ").inspect
1740
+ id = object_id.to_s(16)
1741
+ "#<Class id=0x#{id} tool=#{name}>"
1742
+ end
1724
1743
  end
1725
1744
  end
1726
1745
  end
data/lib/toys/errors.rb CHANGED
@@ -172,7 +172,9 @@ module Toys
172
172
 
173
173
  def add_config_path_if_missing(error, path)
174
174
  if error.config_path.nil? && error.config_line.nil?
175
- l = (error.cause.backtrace_locations || []).find { |b| b.absolute_path == path }
175
+ l = (error.cause.backtrace_locations || []).find do |b|
176
+ b.absolute_path == path || b.path == path
177
+ end
176
178
  if l
177
179
  error.config_path = path
178
180
  error.config_line = l.lineno
data/lib/toys/flag.rb CHANGED
@@ -774,12 +774,15 @@ module Toys
774
774
  long_flag_syntax.reverse_each do |flag|
775
775
  analyze_flag_syntax(flag)
776
776
  end
777
- @flag_type ||= :boolean
778
777
  if @flag_type == :boolean && @explicit_acceptor
779
778
  raise ToolDefinitionError,
780
779
  "Flag #{key.inspect} cannot have an acceptor because it does not take a value."
781
780
  end
782
- @value_type ||= :required if @flag_type == :value
781
+ @flag_type ||= (@explicit_acceptor ? :value : :boolean)
782
+ if @flag_type == :value
783
+ @value_type ||= :required
784
+ @value_label ||= "VALUE"
785
+ end
783
786
  flag_syntax.each do |flag|
784
787
  flag.configure_canonical(@flag_type, @value_type, @value_label, @value_delim)
785
788
  end
@@ -23,7 +23,7 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
23
23
  ::Toys::DSL::Internal.prepare(tool_class, words, priority, remaining_words, source, loader) do
24
24
  ::Toys::ContextualError.capture_path("Error while loading Toys config!", path) do
25
25
  # rubocop:disable Security/Eval
26
- eval(str, __binding, path, -2)
26
+ eval(str, __binding, path)
27
27
  # rubocop:enable Security/Eval
28
28
  end
29
29
  end
@@ -43,11 +43,9 @@ module Toys::InputFile # rubocop:disable Style/ClassAndModuleChildren
43
43
  def self.build_eval_string(module_name, string)
44
44
  index = string.index(/^\s*[^#\s]/)
45
45
  return nil if index.nil?
46
- "#{string[0, index]}\n" \
47
- "module #{module_name}\n" \
48
- "@__tool_class.class_eval do\n" \
46
+ "#{string[0, index]}" \
47
+ "module #{module_name}; @__tool_class.class_eval do; " \
49
48
  "#{string[index..-1]}\n" \
50
- "end\n" \
51
- "end\n"
49
+ "end; end\n"
52
50
  end
53
51
  end
@@ -1254,9 +1254,10 @@ module Toys
1254
1254
  #
1255
1255
  def delegate_to(target)
1256
1256
  if @delegate_target
1257
+ return self if target == @delegate_target
1257
1258
  raise ToolDefinitionError,
1258
- "Cannot delegate tool #{display_name.inspect} because" \
1259
- " it already delegates to \"#{@delegate_target.join(' ')}\"."
1259
+ "Cannot delegate tool #{display_name.inspect} to #{target.join(' ')} because it" \
1260
+ " already delegates to \"#{@delegate_target.join(' ')}\"."
1260
1261
  end
1261
1262
  if includes_arguments?
1262
1263
  raise ToolDefinitionError,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toys-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.1
4
+ version: 0.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-03 00:00:00.000000000 Z
11
+ date: 2022-10-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Toys-Core is the command line tool framework underlying Toys. It can
14
14
  be used to create command line executables using the Toys DSL and classes.
@@ -78,10 +78,10 @@ homepage: https://github.com/dazuma/toys
78
78
  licenses:
79
79
  - MIT
80
80
  metadata:
81
- changelog_uri: https://dazuma.github.io/toys/gems/toys-core/v0.14.1/file.CHANGELOG.html
81
+ changelog_uri: https://dazuma.github.io/toys/gems/toys-core/v0.14.2/file.CHANGELOG.html
82
82
  source_code_uri: https://github.com/dazuma/toys/tree/main/toys-core
83
83
  bug_tracker_uri: https://github.com/dazuma/toys/issues
84
- documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.14.1
84
+ documentation_uri: https://dazuma.github.io/toys/gems/toys-core/v0.14.2
85
85
  post_install_message:
86
86
  rdoc_options: []
87
87
  require_paths: