toys-core 0.9.1 → 0.9.2
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 +9 -1
 - data/README.md +3 -3
 - data/docs/guide.md +109 -14
 - data/lib/toys/cli.rb +33 -28
 - data/lib/toys/core.rb +1 -1
 - data/lib/toys/dsl/tool.rb +4 -3
 - data/lib/toys/loader.rb +177 -132
 - data/lib/toys/middleware.rb +185 -3
 - data/lib/toys/module_lookup.rb +28 -16
 - data/lib/toys/standard_mixins/exec.rb +42 -32
 - data/lib/toys/standard_mixins/gems.rb +1 -1
 - data/lib/toys/standard_mixins/terminal.rb +1 -1
 - data/lib/toys/tool.rb +5 -4
 - data/lib/toys/utils/exec.rb +28 -23
 - metadata +8 -8
 
    
        data/lib/toys/middleware.rb
    CHANGED
    
    | 
         @@ -40,9 +40,10 @@ module Toys 
     | 
|
| 
       40 
40 
     | 
    
         
             
              # replace it outright, or leave it unmodified.
         
     | 
| 
       41 
41 
     | 
    
         
             
              #
         
     | 
| 
       42 
42 
     | 
    
         
             
              # Generally, a middleware is a class that implements the two methods defined
         
     | 
| 
       43 
     | 
    
         
            -
              # in this module: {Toys::Middleware#config} and {Toys::Middleware#run}.  
     | 
| 
       44 
     | 
    
         
            -
              #  
     | 
| 
       45 
     | 
    
         
            -
              #  
     | 
| 
      
 43 
     | 
    
         
            +
              # in this module: {Toys::Middleware#config} and {Toys::Middleware#run}. To
         
     | 
| 
      
 44 
     | 
    
         
            +
              # get default implementations that do nothing, a middleware can
         
     | 
| 
      
 45 
     | 
    
         
            +
              # `include Toys::Middleware` or subclass {Toys::Middleware::Base}, but this
         
     | 
| 
      
 46 
     | 
    
         
            +
              # is not required.
         
     | 
| 
       46 
47 
     | 
    
         
             
              #
         
     | 
| 
       47 
48 
     | 
    
         
             
              module Middleware
         
     | 
| 
       48 
49 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -89,5 +90,186 @@ module Toys 
     | 
|
| 
       89 
90 
     | 
    
         
             
                def run(context) # rubocop:disable Lint/UnusedMethodArgument
         
     | 
| 
       90 
91 
     | 
    
         
             
                  yield
         
     | 
| 
       91 
92 
     | 
    
         
             
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 95 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 96 
     | 
    
         
            +
                  # Create a middleware spec.
         
     | 
| 
      
 97 
     | 
    
         
            +
                  #
         
     | 
| 
      
 98 
     | 
    
         
            +
                  # @overload spec(middleware_object)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  #   Create a spec wrapping an existing middleware object
         
     | 
| 
      
 100 
     | 
    
         
            +
                  #
         
     | 
| 
      
 101 
     | 
    
         
            +
                  #   @param middleware_object [Toys::Middleware] The middleware object
         
     | 
| 
      
 102 
     | 
    
         
            +
                  #   @return [Toys::Middleware::Spec] A spec
         
     | 
| 
      
 103 
     | 
    
         
            +
                  #
         
     | 
| 
      
 104 
     | 
    
         
            +
                  # @overload spec(name, *args, **kwargs, &block)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  #   Create a spec indicating a given middleware name should be
         
     | 
| 
      
 106 
     | 
    
         
            +
                  #   instantiated with the given arguments.
         
     | 
| 
      
 107 
     | 
    
         
            +
                  #
         
     | 
| 
      
 108 
     | 
    
         
            +
                  #   @param name [String,Symbol,Class] The middleware name or class
         
     | 
| 
      
 109 
     | 
    
         
            +
                  #   @param args [Array] The arguments to pass to the constructor
         
     | 
| 
      
 110 
     | 
    
         
            +
                  #   @param kwargs [Hash] The keyword arguments to pass to the constructor
         
     | 
| 
      
 111 
     | 
    
         
            +
                  #   @param block [Proc,nil] The block to pass to the constructor
         
     | 
| 
      
 112 
     | 
    
         
            +
                  #   @return [Toys::Middleware::Spec] A spec
         
     | 
| 
      
 113 
     | 
    
         
            +
                  #
         
     | 
| 
      
 114 
     | 
    
         
            +
                  def spec(middleware, *args, **kwargs, &block)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    if middleware.is_a?(::String) || middleware.is_a?(::Symbol) || middleware.is_a?(::Class)
         
     | 
| 
      
 116 
     | 
    
         
            +
                      Spec.new(nil, middleware, args, kwargs, block)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    else
         
     | 
| 
      
 118 
     | 
    
         
            +
                      Spec.new(middleware, nil, nil, nil, nil)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 123 
     | 
    
         
            +
                  # Create a middleware spec from an array specification.
         
     | 
| 
      
 124 
     | 
    
         
            +
                  #
         
     | 
| 
      
 125 
     | 
    
         
            +
                  # The array must be 1-4 elements long. The first element must be the
         
     | 
| 
      
 126 
     | 
    
         
            +
                  # middleware name or class. The other three arguments may include any or
         
     | 
| 
      
 127 
     | 
    
         
            +
                  # all of the following optional elements, in any order:
         
     | 
| 
      
 128 
     | 
    
         
            +
                  #  *  An array for the positional arguments to pass to the constructor
         
     | 
| 
      
 129 
     | 
    
         
            +
                  #  *  A hash for the keyword arguments to pass to the constructor
         
     | 
| 
      
 130 
     | 
    
         
            +
                  #  *  A proc for the block to pass to the constructor
         
     | 
| 
      
 131 
     | 
    
         
            +
                  #
         
     | 
| 
      
 132 
     | 
    
         
            +
                  # @param array [Array] The array input
         
     | 
| 
      
 133 
     | 
    
         
            +
                  # @return [Toys::Middleware::Spec] A spec
         
     | 
| 
      
 134 
     | 
    
         
            +
                  #
         
     | 
| 
      
 135 
     | 
    
         
            +
                  def spec_from_array(array)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    middleware = array.first
         
     | 
| 
      
 137 
     | 
    
         
            +
                    if !middleware.is_a?(::String) && !middleware.is_a?(::Symbol) && !middleware.is_a?(::Class)
         
     | 
| 
      
 138 
     | 
    
         
            +
                      raise ::ArgumentError, "Bad middleware name: #{middleware.inspect}"
         
     | 
| 
      
 139 
     | 
    
         
            +
                    end
         
     | 
| 
      
 140 
     | 
    
         
            +
                    args = []
         
     | 
| 
      
 141 
     | 
    
         
            +
                    kwargs = {}
         
     | 
| 
      
 142 
     | 
    
         
            +
                    block = nil
         
     | 
| 
      
 143 
     | 
    
         
            +
                    array.slice(1..-1).each do |param|
         
     | 
| 
      
 144 
     | 
    
         
            +
                      case param
         
     | 
| 
      
 145 
     | 
    
         
            +
                      when ::Array
         
     | 
| 
      
 146 
     | 
    
         
            +
                        args += param
         
     | 
| 
      
 147 
     | 
    
         
            +
                      when ::Hash
         
     | 
| 
      
 148 
     | 
    
         
            +
                        kwargs = kwargs.merge(param)
         
     | 
| 
      
 149 
     | 
    
         
            +
                      when ::Proc
         
     | 
| 
      
 150 
     | 
    
         
            +
                        block = param
         
     | 
| 
      
 151 
     | 
    
         
            +
                      else
         
     | 
| 
      
 152 
     | 
    
         
            +
                        raise ::ArgumentError, "Bad param: #{param.inspect}"
         
     | 
| 
      
 153 
     | 
    
         
            +
                      end
         
     | 
| 
      
 154 
     | 
    
         
            +
                    end
         
     | 
| 
      
 155 
     | 
    
         
            +
                    Spec.new(nil, middleware, args, kwargs, block)
         
     | 
| 
      
 156 
     | 
    
         
            +
                  end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 159 
     | 
    
         
            +
                  # Resolve all arguments into an array of middleware specs. Each argument
         
     | 
| 
      
 160 
     | 
    
         
            +
                  # may be one of the following:
         
     | 
| 
      
 161 
     | 
    
         
            +
                  #
         
     | 
| 
      
 162 
     | 
    
         
            +
                  #  *  A {Toys::Middleware} object
         
     | 
| 
      
 163 
     | 
    
         
            +
                  #  *  A {Toys::Middleware::Spec}
         
     | 
| 
      
 164 
     | 
    
         
            +
                  #  *  An array whose first element is a middleware name or class, and the
         
     | 
| 
      
 165 
     | 
    
         
            +
                  #     subsequent elements are params that define what to pass to the class
         
     | 
| 
      
 166 
     | 
    
         
            +
                  #     constructor (see {Toys::Middleware.spec_from_array})
         
     | 
| 
      
 167 
     | 
    
         
            +
                  #
         
     | 
| 
      
 168 
     | 
    
         
            +
                  # @param items [Array<Toys::Middleware,Toys::Middleware::Spec,Array>]
         
     | 
| 
      
 169 
     | 
    
         
            +
                  # @return [Array<Toys::Middleware::Spec>]
         
     | 
| 
      
 170 
     | 
    
         
            +
                  #
         
     | 
| 
      
 171 
     | 
    
         
            +
                  def resolve_specs(*items)
         
     | 
| 
      
 172 
     | 
    
         
            +
                    items.map do |item|
         
     | 
| 
      
 173 
     | 
    
         
            +
                      case item
         
     | 
| 
      
 174 
     | 
    
         
            +
                      when ::Array
         
     | 
| 
      
 175 
     | 
    
         
            +
                        spec_from_array(item)
         
     | 
| 
      
 176 
     | 
    
         
            +
                      when Spec
         
     | 
| 
      
 177 
     | 
    
         
            +
                        item
         
     | 
| 
      
 178 
     | 
    
         
            +
                      else
         
     | 
| 
      
 179 
     | 
    
         
            +
                        spec(item)
         
     | 
| 
      
 180 
     | 
    
         
            +
                      end
         
     | 
| 
      
 181 
     | 
    
         
            +
                    end
         
     | 
| 
      
 182 
     | 
    
         
            +
                  end
         
     | 
| 
      
 183 
     | 
    
         
            +
                end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                ##
         
     | 
| 
      
 186 
     | 
    
         
            +
                # A base class that provides default NOP implementations of the middleware
         
     | 
| 
      
 187 
     | 
    
         
            +
                # interface. This base class may optionally be subclassed by a middleware
         
     | 
| 
      
 188 
     | 
    
         
            +
                # implementation.
         
     | 
| 
      
 189 
     | 
    
         
            +
                #
         
     | 
| 
      
 190 
     | 
    
         
            +
                class Base
         
     | 
| 
      
 191 
     | 
    
         
            +
                  include Middleware
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                ##
         
     | 
| 
      
 195 
     | 
    
         
            +
                # A middleware specification, including the middleware class and the
         
     | 
| 
      
 196 
     | 
    
         
            +
                # arguments to pass to the constructor.
         
     | 
| 
      
 197 
     | 
    
         
            +
                #
         
     | 
| 
      
 198 
     | 
    
         
            +
                # Use {Toys::Middleware.spec} to create a middleware spec.
         
     | 
| 
      
 199 
     | 
    
         
            +
                #
         
     | 
| 
      
 200 
     | 
    
         
            +
                class Spec
         
     | 
| 
      
 201 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 202 
     | 
    
         
            +
                  # Builds a middleware for this spec, given a ModuleLookup for middleware.
         
     | 
| 
      
 203 
     | 
    
         
            +
                  #
         
     | 
| 
      
 204 
     | 
    
         
            +
                  # If this spec wraps an existing middleware object, returns that object.
         
     | 
| 
      
 205 
     | 
    
         
            +
                  # Otherwise, constructs a middleware object from the spec.
         
     | 
| 
      
 206 
     | 
    
         
            +
                  #
         
     | 
| 
      
 207 
     | 
    
         
            +
                  # @param lookup [Toys::ModuleLookup] A module lookup to resolve
         
     | 
| 
      
 208 
     | 
    
         
            +
                  #     middleware names
         
     | 
| 
      
 209 
     | 
    
         
            +
                  # @return [Toys::Middleware] The middleware
         
     | 
| 
      
 210 
     | 
    
         
            +
                  #
         
     | 
| 
      
 211 
     | 
    
         
            +
                  def build(lookup)
         
     | 
| 
      
 212 
     | 
    
         
            +
                    return @object unless @object.nil?
         
     | 
| 
      
 213 
     | 
    
         
            +
                    if @name.is_a?(::String) || @name.is_a?(::Symbol)
         
     | 
| 
      
 214 
     | 
    
         
            +
                      klass = lookup&.lookup(@name)
         
     | 
| 
      
 215 
     | 
    
         
            +
                      raise ::NameError, "Unknown middleware name #{@name.inspect}" if klass.nil?
         
     | 
| 
      
 216 
     | 
    
         
            +
                    else
         
     | 
| 
      
 217 
     | 
    
         
            +
                      klass = @name
         
     | 
| 
      
 218 
     | 
    
         
            +
                    end
         
     | 
| 
      
 219 
     | 
    
         
            +
                    # Due to a bug in Ruby < 2.7, passing an empty **kwargs splat to
         
     | 
| 
      
 220 
     | 
    
         
            +
                    # initialize will fail if there are no formal keyword args.
         
     | 
| 
      
 221 
     | 
    
         
            +
                    formals = klass.instance_method(:initialize).parameters
         
     | 
| 
      
 222 
     | 
    
         
            +
                    if @kwargs.empty? && formals.all? { |arg| arg.first != :key && arg.first != :keyrest }
         
     | 
| 
      
 223 
     | 
    
         
            +
                      klass.new(*@args, &@block)
         
     | 
| 
      
 224 
     | 
    
         
            +
                    else
         
     | 
| 
      
 225 
     | 
    
         
            +
                      klass.new(*@args, **@kwargs, &@block)
         
     | 
| 
      
 226 
     | 
    
         
            +
                    end
         
     | 
| 
      
 227 
     | 
    
         
            +
                  end
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 230 
     | 
    
         
            +
                  # @return [Toys::Middleware] if this spec wraps a middleware object
         
     | 
| 
      
 231 
     | 
    
         
            +
                  # @return [nil] if this spec represents a class to instantiate
         
     | 
| 
      
 232 
     | 
    
         
            +
                  #
         
     | 
| 
      
 233 
     | 
    
         
            +
                  attr_reader :object
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 236 
     | 
    
         
            +
                  # @return [String,Symbol] if this spec represents a middleware name
         
     | 
| 
      
 237 
     | 
    
         
            +
                  # @return [Class] if this spec represents a middleware class
         
     | 
| 
      
 238 
     | 
    
         
            +
                  # @return [nil] if this spec wraps a middleware object
         
     | 
| 
      
 239 
     | 
    
         
            +
                  #
         
     | 
| 
      
 240 
     | 
    
         
            +
                  attr_reader :name
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 243 
     | 
    
         
            +
                  # @return [Array] the positional arguments to be passed to a middleware
         
     | 
| 
      
 244 
     | 
    
         
            +
                  #     class constructor, or the empty array if there are no positional
         
     | 
| 
      
 245 
     | 
    
         
            +
                  #     arguments
         
     | 
| 
      
 246 
     | 
    
         
            +
                  # @return [nil] if this spec wraps a middleware object
         
     | 
| 
      
 247 
     | 
    
         
            +
                  #
         
     | 
| 
      
 248 
     | 
    
         
            +
                  attr_reader :args
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 251 
     | 
    
         
            +
                  # @return [Hash] the keyword arguments to be passed to a middleware class
         
     | 
| 
      
 252 
     | 
    
         
            +
                  #     constructor, or the empty hash if there are no keyword arguments
         
     | 
| 
      
 253 
     | 
    
         
            +
                  # @return [nil] if this spec wraps a middleware object
         
     | 
| 
      
 254 
     | 
    
         
            +
                  #
         
     | 
| 
      
 255 
     | 
    
         
            +
                  attr_reader :kwargs
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
      
 257 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 258 
     | 
    
         
            +
                  # @return [Proc] if there is a block argument to be passed to a
         
     | 
| 
      
 259 
     | 
    
         
            +
                  #     middleware class constructor
         
     | 
| 
      
 260 
     | 
    
         
            +
                  # @return [nil] if there is no block argument, or this spec wraps a
         
     | 
| 
      
 261 
     | 
    
         
            +
                  #     middleware object
         
     | 
| 
      
 262 
     | 
    
         
            +
                  #
         
     | 
| 
      
 263 
     | 
    
         
            +
                  attr_reader :block
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
                  ## @private
         
     | 
| 
      
 266 
     | 
    
         
            +
                  def initialize(object, name, args, kwargs, block)
         
     | 
| 
      
 267 
     | 
    
         
            +
                    @object = object
         
     | 
| 
      
 268 
     | 
    
         
            +
                    @name = name
         
     | 
| 
      
 269 
     | 
    
         
            +
                    @args = args
         
     | 
| 
      
 270 
     | 
    
         
            +
                    @kwargs = kwargs
         
     | 
| 
      
 271 
     | 
    
         
            +
                    @block = block
         
     | 
| 
      
 272 
     | 
    
         
            +
                  end
         
     | 
| 
      
 273 
     | 
    
         
            +
                end
         
     | 
| 
       92 
274 
     | 
    
         
             
              end
         
     | 
| 
       93 
275 
     | 
    
         
             
            end
         
     | 
    
        data/lib/toys/module_lookup.rb
    CHANGED
    
    | 
         @@ -21,6 +21,8 @@ 
     | 
|
| 
       21 
21 
     | 
    
         
             
            # IN THE SOFTWARE.
         
     | 
| 
       22 
22 
     | 
    
         
             
            ;
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            require "monitor"
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       24 
26 
     | 
    
         
             
            module Toys
         
     | 
| 
       25 
27 
     | 
    
         
             
              ##
         
     | 
| 
       26 
28 
     | 
    
         
             
              # A helper module that provides methods to do module lookups. This is
         
     | 
| 
         @@ -71,11 +73,15 @@ module Toys 
     | 
|
| 
       71 
73 
     | 
    
         
             
                  end
         
     | 
| 
       72 
74 
     | 
    
         
             
                end
         
     | 
| 
       73 
75 
     | 
    
         | 
| 
      
 76 
     | 
    
         
            +
                include ::MonitorMixin
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
       74 
78 
     | 
    
         
             
                ##
         
     | 
| 
       75 
79 
     | 
    
         
             
                # Create an empty ModuleLookup
         
     | 
| 
       76 
80 
     | 
    
         
             
                #
         
     | 
| 
       77 
81 
     | 
    
         
             
                def initialize
         
     | 
| 
      
 82 
     | 
    
         
            +
                  super()
         
     | 
| 
       78 
83 
     | 
    
         
             
                  @paths = []
         
     | 
| 
      
 84 
     | 
    
         
            +
                  @paths_locked = false
         
     | 
| 
       79 
85 
     | 
    
         
             
                end
         
     | 
| 
       80 
86 
     | 
    
         | 
| 
       81 
87 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -90,10 +96,13 @@ module Toys 
     | 
|
| 
       90 
96 
     | 
    
         
             
                #
         
     | 
| 
       91 
97 
     | 
    
         
             
                def add_path(path_base, module_base: nil, high_priority: false)
         
     | 
| 
       92 
98 
     | 
    
         
             
                  module_base ||= ModuleLookup.path_to_module(path_base)
         
     | 
| 
       93 
     | 
    
         
            -
                   
     | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
      
 99 
     | 
    
         
            +
                  synchronize do
         
     | 
| 
      
 100 
     | 
    
         
            +
                    raise "You cannot add a path after a lookup has already occurred." if @paths_locked
         
     | 
| 
      
 101 
     | 
    
         
            +
                    if high_priority
         
     | 
| 
      
 102 
     | 
    
         
            +
                      @paths.unshift([path_base, module_base])
         
     | 
| 
      
 103 
     | 
    
         
            +
                    else
         
     | 
| 
      
 104 
     | 
    
         
            +
                      @paths << [path_base, module_base]
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
       97 
106 
     | 
    
         
             
                  end
         
     | 
| 
       98 
107 
     | 
    
         
             
                  self
         
     | 
| 
       99 
108 
     | 
    
         
             
                end
         
     | 
| 
         @@ -105,19 +114,22 @@ module Toys 
     | 
|
| 
       105 
114 
     | 
    
         
             
                # @return [Module] The specified module
         
     | 
| 
       106 
115 
     | 
    
         
             
                #
         
     | 
| 
       107 
116 
     | 
    
         
             
                def lookup(name)
         
     | 
| 
       108 
     | 
    
         
            -
                   
     | 
| 
       109 
     | 
    
         
            -
                     
     | 
| 
       110 
     | 
    
         
            -
                     
     | 
| 
       111 
     | 
    
         
            -
                       
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
                       
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
      
 117 
     | 
    
         
            +
                  synchronize do
         
     | 
| 
      
 118 
     | 
    
         
            +
                    @paths_locked = true
         
     | 
| 
      
 119 
     | 
    
         
            +
                    @paths.each do |path_base, module_base|
         
     | 
| 
      
 120 
     | 
    
         
            +
                      path = "#{path_base}/#{ModuleLookup.to_path_name(name)}"
         
     | 
| 
      
 121 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 122 
     | 
    
         
            +
                        require path
         
     | 
| 
      
 123 
     | 
    
         
            +
                      rescue ::LoadError
         
     | 
| 
      
 124 
     | 
    
         
            +
                        next
         
     | 
| 
      
 125 
     | 
    
         
            +
                      end
         
     | 
| 
      
 126 
     | 
    
         
            +
                      mod_name = ModuleLookup.to_module_name(name)
         
     | 
| 
      
 127 
     | 
    
         
            +
                      unless module_base.constants.include?(mod_name)
         
     | 
| 
      
 128 
     | 
    
         
            +
                        raise ::NameError,
         
     | 
| 
      
 129 
     | 
    
         
            +
                              "File #{path.inspect} did not define #{module_base.name}::#{mod_name}"
         
     | 
| 
      
 130 
     | 
    
         
            +
                      end
         
     | 
| 
      
 131 
     | 
    
         
            +
                      return module_base.const_get(mod_name)
         
     | 
| 
       119 
132 
     | 
    
         
             
                    end
         
     | 
| 
       120 
     | 
    
         
            -
                    return module_base.const_get(mod_name)
         
     | 
| 
       121 
133 
     | 
    
         
             
                  end
         
     | 
| 
       122 
134 
     | 
    
         
             
                  nil
         
     | 
| 
       123 
135 
     | 
    
         
             
                end
         
     | 
| 
         @@ -95,11 +95,11 @@ module Toys 
     | 
|
| 
       95 
95 
     | 
    
         
             
                  #
         
     | 
| 
       96 
96 
     | 
    
         
             
                  KEY = ::Object.new.freeze
         
     | 
| 
       97 
97 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
                  on_initialize do  
     | 
| 
      
 98 
     | 
    
         
            +
                  on_initialize do |**opts|
         
     | 
| 
       99 
99 
     | 
    
         
             
                    require "toys/utils/exec"
         
     | 
| 
       100 
100 
     | 
    
         
             
                    context = self
         
     | 
| 
       101 
101 
     | 
    
         
             
                    opts = Exec._setup_exec_opts(opts, context)
         
     | 
| 
       102 
     | 
    
         
            -
                    context[KEY] = Utils::Exec.new(opts) do |k|
         
     | 
| 
      
 102 
     | 
    
         
            +
                    context[KEY] = Utils::Exec.new(**opts) do |k|
         
     | 
| 
       103 
103 
     | 
    
         
             
                      case k
         
     | 
| 
       104 
104 
     | 
    
         
             
                      when :logger
         
     | 
| 
       105 
105 
     | 
    
         
             
                        context[Context::Key::LOGGER]
         
     | 
| 
         @@ -115,11 +115,12 @@ module Toys 
     | 
|
| 
       115 
115 
     | 
    
         
             
                  # All options listed in the {Toys::Utils::Exec} documentation are
         
     | 
| 
       116 
116 
     | 
    
         
             
                  # supported, plus the `exit_on_nonzero_status` option.
         
     | 
| 
       117 
117 
     | 
    
         
             
                  #
         
     | 
| 
       118 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 118 
     | 
    
         
            +
                  # @param opts [keywords] The default options.
         
     | 
| 
       119 
119 
     | 
    
         
             
                  # @return [self]
         
     | 
| 
       120 
120 
     | 
    
         
             
                  #
         
     | 
| 
       121 
     | 
    
         
            -
                  def configure_exec(opts 
     | 
| 
       122 
     | 
    
         
            -
                     
     | 
| 
      
 121 
     | 
    
         
            +
                  def configure_exec(**opts)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    self[KEY].configure_defaults(**opts)
         
     | 
| 
       123 
124 
     | 
    
         
             
                    self
         
     | 
| 
       124 
125 
     | 
    
         
             
                  end
         
     | 
| 
       125 
126 
     | 
    
         | 
| 
         @@ -131,7 +132,7 @@ module Toys 
     | 
|
| 
       131 
132 
     | 
    
         
             
                  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
         
     | 
| 
       132 
133 
     | 
    
         
             
                  #
         
     | 
| 
       133 
134 
     | 
    
         
             
                  # @param cmd [String,Array<String>] The command to execute.
         
     | 
| 
       134 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 135 
     | 
    
         
            +
                  # @param opts [keywords] The command options. All options listed in the
         
     | 
| 
       135 
136 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       136 
137 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       137 
138 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
         
     | 
| 
         @@ -142,8 +143,9 @@ module Toys 
     | 
|
| 
       142 
143 
     | 
    
         
             
                  # @return [Toys::Utils::Exec::Result] The result, if the process ran in
         
     | 
| 
       143 
144 
     | 
    
         
             
                  #     the foreground.
         
     | 
| 
       144 
145 
     | 
    
         
             
                  #
         
     | 
| 
       145 
     | 
    
         
            -
                  def exec(cmd, opts 
     | 
| 
       146 
     | 
    
         
            -
                     
     | 
| 
      
 146 
     | 
    
         
            +
                  def exec(cmd, **opts, &block)
         
     | 
| 
      
 147 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 148 
     | 
    
         
            +
                    self[KEY].exec(cmd, **opts, &block)
         
     | 
| 
       147 
149 
     | 
    
         
             
                  end
         
     | 
| 
       148 
150 
     | 
    
         | 
| 
       149 
151 
     | 
    
         
             
                  ##
         
     | 
| 
         @@ -153,7 +155,7 @@ module Toys 
     | 
|
| 
       153 
155 
     | 
    
         
             
                  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
         
     | 
| 
       154 
156 
     | 
    
         
             
                  #
         
     | 
| 
       155 
157 
     | 
    
         
             
                  # @param args [String,Array<String>] The arguments to ruby.
         
     | 
| 
       156 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 158 
     | 
    
         
            +
                  # @param opts [keywords] The command options. All options listed in the
         
     | 
| 
       157 
159 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       158 
160 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       159 
161 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
         
     | 
| 
         @@ -164,8 +166,9 @@ module Toys 
     | 
|
| 
       164 
166 
     | 
    
         
             
                  # @return [Toys::Utils::Exec::Result] The result, if the process ran in
         
     | 
| 
       165 
167 
     | 
    
         
             
                  #     the foreground.
         
     | 
| 
       166 
168 
     | 
    
         
             
                  #
         
     | 
| 
       167 
     | 
    
         
            -
                  def exec_ruby(args, opts 
     | 
| 
       168 
     | 
    
         
            -
                     
     | 
| 
      
 169 
     | 
    
         
            +
                  def exec_ruby(args, **opts, &block)
         
     | 
| 
      
 170 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 171 
     | 
    
         
            +
                    self[KEY].exec_ruby(args, **opts, &block)
         
     | 
| 
       169 
172 
     | 
    
         
             
                  end
         
     | 
| 
       170 
173 
     | 
    
         
             
                  alias ruby exec_ruby
         
     | 
| 
       171 
174 
     | 
    
         | 
| 
         @@ -176,7 +179,7 @@ module Toys 
     | 
|
| 
       176 
179 
     | 
    
         
             
                  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
         
     | 
| 
       177 
180 
     | 
    
         
             
                  #
         
     | 
| 
       178 
181 
     | 
    
         
             
                  # @param func [Proc] The proc to call.
         
     | 
| 
       179 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 182 
     | 
    
         
            +
                  # @param opts [keywords] The command options. Most options listed in the
         
     | 
| 
       180 
183 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       181 
184 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       182 
185 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
         
     | 
| 
         @@ -187,8 +190,9 @@ module Toys 
     | 
|
| 
       187 
190 
     | 
    
         
             
                  # @return [Toys::Utils::Exec::Result] The result, if the process ran in
         
     | 
| 
       188 
191 
     | 
    
         
             
                  #     the foreground.
         
     | 
| 
       189 
192 
     | 
    
         
             
                  #
         
     | 
| 
       190 
     | 
    
         
            -
                  def exec_proc(func, opts 
     | 
| 
       191 
     | 
    
         
            -
                     
     | 
| 
      
 193 
     | 
    
         
            +
                  def exec_proc(func, **opts, &block)
         
     | 
| 
      
 194 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 195 
     | 
    
         
            +
                    self[KEY].exec_proc(func, **opts, &block)
         
     | 
| 
       192 
196 
     | 
    
         
             
                  end
         
     | 
| 
       193 
197 
     | 
    
         | 
| 
       194 
198 
     | 
    
         
             
                  ##
         
     | 
| 
         @@ -199,7 +203,7 @@ module Toys 
     | 
|
| 
       199 
203 
     | 
    
         
             
                  # provided, a {Toys::Utils::Exec::Controller} will be yielded to it.
         
     | 
| 
       200 
204 
     | 
    
         
             
                  #
         
     | 
| 
       201 
205 
     | 
    
         
             
                  # @param cmd [String,Array<String>] The tool to execute.
         
     | 
| 
       202 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 206 
     | 
    
         
            +
                  # @param opts [keywords] The command options. Most options listed in the
         
     | 
| 
       203 
207 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       204 
208 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       205 
209 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
         
     | 
| 
         @@ -210,9 +214,10 @@ module Toys 
     | 
|
| 
       210 
214 
     | 
    
         
             
                  # @return [Toys::Utils::Exec::Result] The result, if the process ran in
         
     | 
| 
       211 
215 
     | 
    
         
             
                  #     the foreground.
         
     | 
| 
       212 
216 
     | 
    
         
             
                  #
         
     | 
| 
       213 
     | 
    
         
            -
                  def exec_tool(cmd, opts 
     | 
| 
      
 217 
     | 
    
         
            +
                  def exec_tool(cmd, **opts, &block)
         
     | 
| 
       214 
218 
     | 
    
         
             
                    func = Exec._make_tool_caller(cmd)
         
     | 
| 
       215 
     | 
    
         
            -
                     
     | 
| 
      
 219 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 220 
     | 
    
         
            +
                    self[KEY].exec_proc(func, **opts, &block)
         
     | 
| 
       216 
221 
     | 
    
         
             
                  end
         
     | 
| 
       217 
222 
     | 
    
         | 
| 
       218 
223 
     | 
    
         
             
                  ##
         
     | 
| 
         @@ -226,7 +231,7 @@ module Toys 
     | 
|
| 
       226 
231 
     | 
    
         
             
                  # yielded to it.
         
     | 
| 
       227 
232 
     | 
    
         
             
                  #
         
     | 
| 
       228 
233 
     | 
    
         
             
                  # @param cmd [String,Array<String>] The command to execute.
         
     | 
| 
       229 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 234 
     | 
    
         
            +
                  # @param opts [keywords] The command options. All options listed in the
         
     | 
| 
       230 
235 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       231 
236 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       232 
237 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
         
     | 
| 
         @@ -234,8 +239,9 @@ module Toys 
     | 
|
| 
       234 
239 
     | 
    
         
             
                  #
         
     | 
| 
       235 
240 
     | 
    
         
             
                  # @return [String] What was written to standard out.
         
     | 
| 
       236 
241 
     | 
    
         
             
                  #
         
     | 
| 
       237 
     | 
    
         
            -
                  def capture(cmd, opts 
     | 
| 
       238 
     | 
    
         
            -
                     
     | 
| 
      
 242 
     | 
    
         
            +
                  def capture(cmd, **opts, &block)
         
     | 
| 
      
 243 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 244 
     | 
    
         
            +
                    self[KEY].capture(cmd, **opts, &block)
         
     | 
| 
       239 
245 
     | 
    
         
             
                  end
         
     | 
| 
       240 
246 
     | 
    
         | 
| 
       241 
247 
     | 
    
         
             
                  ##
         
     | 
| 
         @@ -248,7 +254,7 @@ module Toys 
     | 
|
| 
       248 
254 
     | 
    
         
             
                  # yielded to it.
         
     | 
| 
       249 
255 
     | 
    
         
             
                  #
         
     | 
| 
       250 
256 
     | 
    
         
             
                  # @param args [String,Array<String>] The arguments to ruby.
         
     | 
| 
       251 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 257 
     | 
    
         
            +
                  # @param opts [keywords] The command options. All options listed in the
         
     | 
| 
       252 
258 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       253 
259 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       254 
260 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
         
     | 
| 
         @@ -256,8 +262,9 @@ module Toys 
     | 
|
| 
       256 
262 
     | 
    
         
             
                  #
         
     | 
| 
       257 
263 
     | 
    
         
             
                  # @return [String] What was written to standard out.
         
     | 
| 
       258 
264 
     | 
    
         
             
                  #
         
     | 
| 
       259 
     | 
    
         
            -
                  def capture_ruby(args, opts 
     | 
| 
       260 
     | 
    
         
            -
                     
     | 
| 
      
 265 
     | 
    
         
            +
                  def capture_ruby(args, **opts, &block)
         
     | 
| 
      
 266 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 267 
     | 
    
         
            +
                    self[KEY].capture_ruby(args, **opts, &block)
         
     | 
| 
       261 
268 
     | 
    
         
             
                  end
         
     | 
| 
       262 
269 
     | 
    
         | 
| 
       263 
270 
     | 
    
         
             
                  ##
         
     | 
| 
         @@ -270,7 +277,7 @@ module Toys 
     | 
|
| 
       270 
277 
     | 
    
         
             
                  # yielded to it.
         
     | 
| 
       271 
278 
     | 
    
         
             
                  #
         
     | 
| 
       272 
279 
     | 
    
         
             
                  # @param func [Proc] The proc to call.
         
     | 
| 
       273 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 280 
     | 
    
         
            +
                  # @param opts [keywords] The command options. Most options listed in the
         
     | 
| 
       274 
281 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       275 
282 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       276 
283 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
         
     | 
| 
         @@ -278,8 +285,9 @@ module Toys 
     | 
|
| 
       278 
285 
     | 
    
         
             
                  #
         
     | 
| 
       279 
286 
     | 
    
         
             
                  # @return [String] What was written to standard out.
         
     | 
| 
       280 
287 
     | 
    
         
             
                  #
         
     | 
| 
       281 
     | 
    
         
            -
                  def capture_proc(func, opts 
     | 
| 
       282 
     | 
    
         
            -
                     
     | 
| 
      
 288 
     | 
    
         
            +
                  def capture_proc(func, **opts, &block)
         
     | 
| 
      
 289 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 290 
     | 
    
         
            +
                    self[KEY].capture_proc(func, **opts, &block)
         
     | 
| 
       283 
291 
     | 
    
         
             
                  end
         
     | 
| 
       284 
292 
     | 
    
         | 
| 
       285 
293 
     | 
    
         
             
                  ##
         
     | 
| 
         @@ -293,7 +301,7 @@ module Toys 
     | 
|
| 
       293 
301 
     | 
    
         
             
                  # yielded to it.
         
     | 
| 
       294 
302 
     | 
    
         
             
                  #
         
     | 
| 
       295 
303 
     | 
    
         
             
                  # @param cmd [String,Array<String>] The tool to execute.
         
     | 
| 
       296 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 304 
     | 
    
         
            +
                  # @param opts [keywords] The command options. Most options listed in the
         
     | 
| 
       297 
305 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       298 
306 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       299 
307 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
         
     | 
| 
         @@ -301,9 +309,10 @@ module Toys 
     | 
|
| 
       301 
309 
     | 
    
         
             
                  #
         
     | 
| 
       302 
310 
     | 
    
         
             
                  # @return [String] What was written to standard out.
         
     | 
| 
       303 
311 
     | 
    
         
             
                  #
         
     | 
| 
       304 
     | 
    
         
            -
                  def capture_tool(cmd, opts 
     | 
| 
      
 312 
     | 
    
         
            +
                  def capture_tool(cmd, **opts, &block)
         
     | 
| 
       305 
313 
     | 
    
         
             
                    func = Exec._make_tool_caller(cmd)
         
     | 
| 
       306 
     | 
    
         
            -
                     
     | 
| 
      
 314 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 315 
     | 
    
         
            +
                    self[KEY].capture_proc(func, **opts, &block)
         
     | 
| 
       307 
316 
     | 
    
         
             
                  end
         
     | 
| 
       308 
317 
     | 
    
         | 
| 
       309 
318 
     | 
    
         
             
                  ##
         
     | 
| 
         @@ -314,7 +323,7 @@ module Toys 
     | 
|
| 
       314 
323 
     | 
    
         
             
                  # yielded to it.
         
     | 
| 
       315 
324 
     | 
    
         
             
                  #
         
     | 
| 
       316 
325 
     | 
    
         
             
                  # @param cmd [String] The shell command to execute.
         
     | 
| 
       317 
     | 
    
         
            -
                  # @param opts [ 
     | 
| 
      
 326 
     | 
    
         
            +
                  # @param opts [keywords] The command options. All options listed in the
         
     | 
| 
       318 
327 
     | 
    
         
             
                  #     {Toys::Utils::Exec} documentation are supported, plus the
         
     | 
| 
       319 
328 
     | 
    
         
             
                  #     `exit_on_nonzero_status` option.
         
     | 
| 
       320 
329 
     | 
    
         
             
                  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
         
     | 
| 
         @@ -322,8 +331,9 @@ module Toys 
     | 
|
| 
       322 
331 
     | 
    
         
             
                  #
         
     | 
| 
       323 
332 
     | 
    
         
             
                  # @return [Integer] The exit code
         
     | 
| 
       324 
333 
     | 
    
         
             
                  #
         
     | 
| 
       325 
     | 
    
         
            -
                  def sh(cmd, opts 
     | 
| 
       326 
     | 
    
         
            -
                     
     | 
| 
      
 334 
     | 
    
         
            +
                  def sh(cmd, **opts, &block)
         
     | 
| 
      
 335 
     | 
    
         
            +
                    opts = Exec._setup_exec_opts(opts, self)
         
     | 
| 
      
 336 
     | 
    
         
            +
                    self[KEY].sh(cmd, **opts, &block)
         
     | 
| 
       327 
337 
     | 
    
         
             
                  end
         
     | 
| 
       328 
338 
     | 
    
         | 
| 
       329 
339 
     | 
    
         
             
                  ##
         
     |