SamovarSourceSamovarOptions

class Options

Represents a collection of command-line options.

Options provide a DSL for defining multiple option flags in a single block.

Definitions

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

Parse and create an options collection from a block.

Signature

parameter arguments Array

The arguments for the options collection.

parameter options Hash

Additional options.

yields {|...| ...}

A block that defines options using #option.

returns Options

The frozen options collection.

Implementation

def self.parse(*arguments, **options, &block)
	options = self.new(*arguments, **options)
	
	options.instance_eval(&block) if block_given?
	
	return options.freeze
end

def parse(input, parent = nil, default = nil)

Parse options from the input.

Signature

parameter input Array(String)

The command-line arguments.

parameter parent Command | Nil

The parent command.

parameter default Hash | Nil

Default values to use.

returns Hash

The parsed option values.

Implementation

def parse(input, parent = nil, default = nil)
	values = (default || defaults).dup
	
	while option = @keyed[input.first]
		# prefix = input.first
		result = option.parse(input)
		if result != nil
			values[option.key] = result
		end
	end
	
	# Validate required options
	@ordered.each do |option|
		if option.required && !values.key?(option.key)
			raise MissingValueError.new(parent, option.key)
		end
	end
	
	return values
end

def initialize(title = "Options", key: :options)

Initialize a new options collection.

Signature

parameter title String

The title for this options group in usage output.

parameter key Symbol

The key to use for storing parsed options.

Implementation

def initialize(title = "Options", key: :options)
	@title = title
	@ordered = []
	
	# We use this flag to option cache to improve parsing performance:
	@keyed = {}
	
	@key = key
	
	@defaults = {}
end

def initialize_dup(source)

Initialize a duplicate of this options collection.

Signature

parameter source Options

The source options to duplicate.

Implementation

def initialize_dup(source)
	super
	
	@ordered = @ordered.dup
	@keyed = @keyed.dup
	@defaults = @defaults.dup
end

attr :title

The title for this options group in usage output.

Signature

attribute String

attr :ordered

The ordered list of options.

Signature

attribute Array(Option)

attr :key

The key to use for storing parsed options.

Signature

attribute Symbol

def defaults

The default values for options.

Signature

returns Hash

The resolved default values.

Implementation

def defaults
	@defaults.transform_values(&:default)
end

def freeze

Freeze this options collection.

Signature

returns Options

The frozen options collection.

Implementation

def freeze
	return self if frozen?
	
	@ordered.freeze
	@keyed.freeze
	@defaults.freeze
	
	@ordered.each(&:freeze)
	
	super
end

def each(&block)

Iterate over each option.

Signature

yields {|option| ...}

Each option in the collection.

Implementation

def each(&block)
	@ordered.each(&block)
end

def option_for(token)

Find the option that matches the given flag token.

Signature

parameter token String

The flag token to match.

returns Option | Nil

The matching option.

Implementation

def option_for(token)
	@keyed[token]
end

def completions

The possible flag prefixes for completion.

Signature

returns Array(String)

The option flag prefixes and alternatives.

Implementation

def completions
	@ordered.flat_map{|option| option.flags.completions}
end

def empty?

Check if this options collection is empty.

Signature

returns Boolean

True if there are no options.

Implementation

def empty?
	@ordered.empty?
end

def option(*arguments, **options, &block)

Define a new option in this collection.

Signature

parameter arguments Array

The arguments for the option.

parameter options Hash

Additional options.

yields {|value| ...}

An optional block to transform the parsed value.

Implementation

def option(*arguments, **options, &block)
	self << Option.new(*arguments, **options, &block)
end

def merge!(options)

Merge another options collection into this one.

Signature

parameter options Options

The options to merge.

Implementation

def merge!(options)
	options.each do |option|
		self << option
	end
end

def <<(option)

Add an option to this collection.

Signature

parameter option Option

The option to add.

Implementation

def << option
	@ordered << option
	option.flags.each do |flag|
		@keyed[flag.prefix] = option
		
		flag.alternatives.each do |alternative|
			@keyed[alternative] = option
		end
	end
	
	if option.default?
		@defaults[option.key] = option
	end
end

def complete(input, context, collected)

Complete option flags or option values.

Signature

parameter input Array(String)

Previously completed command-line arguments.

parameter context Completion::Context

The completion context.

parameter collected Array(Completion::Suggestion)

Suggestions collected so far.

returns Completion::Result | Nil

A final completion result, or nil to continue.

Implementation

def complete(input, context, collected)
	result = consume(input, context)
	return result if result
	
	return nil unless input.empty?
	
	flags = suggestions(context.current)
	
	if context.current.start_with?("-") && flags.any?
		return Completion::Result.new(flags)
	elsif context.current.empty?
		collected.concat(flags)
		return nil
	end
	
	return nil
end

def consume(input, context)

Consume option tokens before the current completion position.

Signature

parameter input Array(String)

Previously completed command-line arguments.

parameter context Completion::Context

The completion context.

returns Completion::Result | Nil

A completion result for an option value, or nil to continue.

Implementation

def consume(input, context)
	while token = input.first
		break unless option = option_for(token)
		
		flag = option.flag_for(token)
		input.shift
		
		if flag && !flag.boolean?
			if input.any?
				input.shift
			else
				return option.suggestions(context)
			end
		end
	end
	
	return nil
end

def suggestions(prefix)

Complete option flags for the given prefix.

Signature

parameter prefix String

The option prefix being completed.

returns Array(Completion::Suggestion)

The matching option flag suggestions.

Implementation

def suggestions(prefix)
	flat_map do |option|
		option.flags.completions.collect do |value|
			next unless value.start_with?(prefix)
			
			Completion::Suggestion.new(value, description: option.description, type: :option)
		end
	end.compact
end

def to_s

Generate a string representation for usage output.

Signature

returns String

The usage string.

Implementation

def to_s
	@ordered.collect(&:to_s).join(" ")
end

def usage(rows)

Generate usage information for this options collection.

Signature

parameter rows Output::Rows

The rows to append usage information to.

Implementation

def usage(rows)
	@ordered.each do |option|
		rows << option
	end
end