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(input = 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.

Signature

parameter input 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(input = ARGV, output: $stderr)
	self.parse(input).call
rescue Error => error
	error.command.print_usage(output: output) do |formatter|
		formatter.map(error)
	end
	
	return nil
end

def self.parse(input)

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 input Array(String)

The command-line arguments to parse.

returns Command

The parsed command instance.

raises Error

If parsing fails.

Implementation

def self.parse(input)
	self.new(input)
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.[](*input, **options)

Create a new command instance with the given arguments.

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

Signature

parameter input 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.[](*input, **options)
	self.new(input, **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