class CommandKit::Commands::AutoLoad

Provides lazy-loading access to a directory / module namespace of command classes.

## Examples

class CLI

  include CommandKit::Commands::AutoLoad.new(
    dir:       "#{__dir__}/cli/commands",
    namespace: 'CLI::Commands'
  )

end

### Explicit Mapping

class CLI

  include CommandKit::Commands::AutoLoad.new(
    dir:       "#{__dir__}/cli/commands",
    namespace: 'CLI::Commands'
  ) { |autoload|
    autoload.command 'foo', 'Foo', 'foo.rb', summary: 'Foo command'
    autoload.command 'bar', 'Bar', 'bar.rb', summary: 'Bar command'
  }

end

Attributes

commands[R]

The auto-load subcommands.

@return [Hash{String => Subcommand}]

@api private

dir[R]

The path to the directory containing the command files.

@return [String]

@api private

namespace[R]

The namespace that the will contain the command classes.

@return [String]

@api private

Public Class Methods

new(dir: , namespace: ) { |self| ... } click to toggle source

Initializes the namespace.

@param [String] dir

The path to the directory containing the command files.

@param [Module, Class, String] namespace

The namespace constant that contains the command classes.

@yield [self]

If a block is given, it will be used to explicitly map the files
within {#dir} as commands.

@api public

# File lib/command_kit/commands/auto_load.rb, line 76
def initialize(dir: , namespace: )
  @commands  = {}

  @dir       = dir
  @namespace = namespace

  if block_given?
    yield self
  else
    files.each do |path|
      base_name    = File.basename(path)
      file_name    = base_name.chomp('.rb')
      command_name = Inflector.dasherize(file_name)
      class_name   = Inflector.camelize(file_name)

      command command_name, class_name, base_name
    end
  end
end

Public Instance Methods

command(name, constant, file, **kwargs) click to toggle source

Defines an auto-loaded command mapping.

@param [#to_s] name

The name of the command.

@param [String] constant

The constant name of the command class.

@param [String] file

The file name of the command class.

@param [Hash{Symbol => Object}] kwargs

Keyword arguments.

@option kwargs [String, nil] summary

An optional summary for the command.

@option kwargs [Array<String>] aliases

Optional alias names for the subcommand.

@api public

# File lib/command_kit/commands/auto_load.rb, line 119
def command(name, constant, file, **kwargs)
  @commands[name.to_s] = Subcommand.new(
    "#{@namespace}::#{constant}",
    join(file),
    **kwargs
  )
end
files() click to toggle source

Returns the files within given directory.

@return [Array<String>]

The paths to the `.rb` files in the directory.

@api private

# File lib/command_kit/commands/auto_load.rb, line 150
def files
  Dir.glob(join('*.rb'))
end
included(command) click to toggle source

Includes {Commands} and registers all files within the namespace as lazy-loaded subcommands.

@param [Class] command

The command class including {AutoLoad}.

@api private

# File lib/command_kit/commands/auto_load.rb, line 163
def included(command)
  command.include Commands
  command.commands.merge!(@commands)
end
join(path) click to toggle source

Joins a relative path with {#dir}.

@param [String] path

The relative path.

@return [String]

The joined absolute path.

@api private

# File lib/command_kit/commands/auto_load.rb, line 138
def join(path)
  File.join(@dir,path)
end