SamovarSourceSamovarCommand

class Command

Represents a command in the command-line interface.

Commands are the main building blocks of Samovar applications. Each command is a class that can parse command-line arguments, options, and sub-commands.

Nested

Definitions

def self.call(arguments = ARGV, output: $stderr)

Parse and execute the command with the given input.

This is the high-level entry point for CLI applications. It handles errors gracefully by printing usage and returning nil. The given arguments are passed to the parser, which consumes them as mutable input.

Signature

parameter arguments Array(String)

The command-line arguments to parse.

parameter output IO

The output stream for error messages.

returns Object | Nil

The result of the command's call method, or nil if parsing/execution failed.

Implementation

def self.call(arguments = ARGV, output: $stderr)
	self.parse(arguments).call
rescue Error => error
	error.command.print_usage(output: output) do |formatter|
		formatter.map(error)
	end
	
	return nil
end

def self.complete(arguments = ARGV, environment: ENV, output: $stdout)

Complete the command-line input without executing the command. The given arguments are treated as the stable command-line boundary; completion internals consume derived input arrays.

Signature

parameter arguments Array(String)

The command-line arguments to complete.

parameter environment Hash

The environment for completion callbacks.

parameter output IO

The output stream for printing completion results.

returns Completion::Result

The completion result.

Implementation

def self.complete(arguments = ARGV, environment: ENV, output: $stdout)
	Completion.complete(self, arguments, environment: environment).tap do |result|
		result.print(output)
	end
end

def self.parse(arguments)

Parse the command-line input and create a command instance.

This is the low-level parsing primitive. It raises class Samovar::Error exceptions on parsing failures. For CLI applications, use Samovar::Command.call instead which handles errors gracefully.

Signature

parameter arguments Array(String)

The command-line arguments to parse.

returns Command

The parsed command instance.

raises Error

If parsing fails.

Implementation

def self.parse(arguments)
	self.new(arguments)
end

def parse(input)

Parse the command-line input.

Signature

parameter input Array(String)

The command-line arguments to parse.

returns Command

The command instance.

Implementation

def parse(input)
	self.class.table.merged.parse(input, self)
	
	if input.empty?
		return self
	else
		raise InvalidInputError.new(self, input)
	end
end

def self.[](*arguments, **options)

Create a new command instance with the given arguments.

This is a convenience method for creating command instances with explicit arguments.

Signature

parameter arguments Array(String)

The command-line arguments to parse.

parameter options Hash

Additional options to pass to the command.

returns Command

The command instance.

Implementation

def self.[](*arguments, **options)
	self.new(arguments, **options)
end

def [](*input)

Duplicate the command with additional arguments.

Signature

parameter input Array(String)

The additional command-line arguments to parse.

returns Command

The duplicated command instance.

Implementation

def [](*input)
	self.dup.tap{|command| command.parse(input)}
end

def self.table

The table of rows for parsing command-line arguments.

Signature

returns Table

The table of parsing rows.

Implementation

def self.table
	@table ||= Table.nested(self)
end

def self.append(row)

Append a row to the parsing table.

Implementation

def self.append(row)
	if method_defined?(row.key, false)
		raise ArgumentError, "Method for key #{row.key} is already defined!"
	end
	
	attr_accessor(row.key) if row.respond_to?(:key)
	
	self.table << row
end

def self.options(*arguments, **options, &block)

Define command-line options for this command.

Signature

parameter arguments Array

The arguments for the options.

parameter options Hash

Additional options.

yields {|...| ...}

A block that defines the options using class Samovar::Options.

Implementation

def self.options(*arguments, **options, &block)
	append Options.parse(*arguments, **options, &block)
end

def self.nested(*arguments, **options)

Define a nested sub-command.

Signature

parameter arguments Array

The arguments for the nested command.

parameter options Hash

A hash mapping command names to command classes.

Implementation

def self.nested(*arguments, **options)
	append Nested.new(*arguments, **options)
end

def self.one(*arguments, **options)

Define a single required positional argument.

Signature

parameter arguments Array

The arguments for the positional parameter.

parameter options Hash

Additional options.

Implementation

def self.one(*arguments, **options)
	append One.new(*arguments, **options)
end

def self.many(*arguments, **options)

Define multiple positional arguments.

Signature

parameter arguments Array

The arguments for the positional parameters.

parameter options Hash

Additional options.

Implementation

def self.many(*arguments, **options)
	append Many.new(*arguments, **options)
end

def self.split(*arguments, **options)

Define a split point in the argument list (typically --).

Signature

parameter arguments Array

The arguments for the split.

parameter options Hash

Additional options.

Implementation

def self.split(*arguments, **options)
	append Split.new(*arguments, **options)
end

def self.usage(rows, name)

Generate usage information for this command.

Signature

parameter rows Output::Rows

The rows to append usage information to.

parameter name String

The name of the command.

Implementation

def self.usage(rows, name)
	rows.nested(name, self) do |rows|
		return unless table = self.table.merged
		
		table.each do |row|
			if row.respond_to?(:usage)
				row.usage(rows)
			else
				rows << row
			end
		end
	end
end

def self.command_line(name)

Generate a command-line usage string.

Signature

parameter name String

The name of the command.

returns String

The command-line usage string.

Implementation

def self.command_line(name)
	table = self.table.merged
	
	return "#{name} #{table.usage}"
end

def initialize(input = nil, name: File.basename($0), parent: nil, output: nil)

Initialize a new command instance.

Signature

parameter input Array(String) | Nil

The command-line arguments to parse.

parameter name String

The name of the command (defaults to the script name).

parameter parent Command | Nil

The parent command, if this is a nested command.

parameter output IO | Nil

The output stream for usage information.

Implementation

def initialize(input = nil, name: File.basename($0), parent: nil, output: nil)
	@name = name
	@parent = parent
	@output = output
	
	parse(input) if input
end

attr :output

The output stream for usage information.

Signature

attribute IO

def output

The output stream for usage information, defaults to $stdout.

Signature

returns IO

The output stream.

Implementation

def output
	@output || $stdout
end

def to_s

Generate a string representation of the command.

Signature

returns String

The class name.

Implementation

def to_s
	self.class.name
end

attr :name

The name of the command.

Signature

attribute String

attr :parent

The parent command, if this is a nested command.

Signature

attribute Command | Nil

def print_usage(output: self.output, formatter: Output::UsageFormatter, &block)

Print usage information for this command.

Signature

parameter output IO

The output stream to print to.

parameter formatter Class

The formatter class to use for output.

yields {|formatter| ...}

A block to customize the output.

Implementation

def print_usage(output: self.output, formatter: Output::UsageFormatter, &block)
	rows = Output::Rows.new
	
	self.class.usage(rows, @name)
	
	formatter.print(rows, output, &block)
end