Class: Samovar::Options

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/samovar/options.rb

Overview

Represents a collection of command-line options.

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title = "Options", key: :options) ⇒ Options

Initialize a new options collection.



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/samovar/options.rb', line 34

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

Instance Attribute Details

#keyObject

The key to use for storing parsed options.



70
71
72
# File 'lib/samovar/options.rb', line 70

def key
  @key
end

#orderedObject (readonly)

The ordered list of options.



65
66
67
# File 'lib/samovar/options.rb', line 65

def ordered
  @ordered
end

#titleObject (readonly)

The title for this options group in usage output.



60
61
62
# File 'lib/samovar/options.rb', line 60

def title
  @title
end

Class Method Details

.parse(*arguments, **options, &block) ⇒ Object

Parse and create an options collection from a block.



22
23
24
25
26
27
28
# File 'lib/samovar/options.rb', line 22

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

Instance Method Details

#<<(option) ⇒ Object

Add an option to this collection.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/samovar/options.rb', line 144

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

#complete(input, context, collected) ⇒ Object

Complete option flags or option values.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/samovar/options.rb', line 192

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

#completionsObject

The possible flag prefixes for completion.



112
113
114
# File 'lib/samovar/options.rb', line 112

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

#consume(input, context) ⇒ Object

Consume option tokens before the current completion position.



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/samovar/options.rb', line 215

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

#defaultsObject

The default values for options.



75
76
77
# File 'lib/samovar/options.rb', line 75

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

#each(&block) ⇒ Object

Iterate over each option.



97
98
99
# File 'lib/samovar/options.rb', line 97

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

#empty?Boolean

Check if this options collection is empty.

Returns:

  • (Boolean)


119
120
121
# File 'lib/samovar/options.rb', line 119

def empty?
	@ordered.empty?
end

#freezeObject

Freeze this options collection.



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/samovar/options.rb', line 82

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

#initialize_dup(source) ⇒ Object

Initialize a duplicate of this options collection.



49
50
51
52
53
54
55
# File 'lib/samovar/options.rb', line 49

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

#merge!(options) ⇒ Object

Merge another options collection into this one.



135
136
137
138
139
# File 'lib/samovar/options.rb', line 135

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

#option(*arguments, **options, &block) ⇒ Object

Define a new option in this collection.



128
129
130
# File 'lib/samovar/options.rb', line 128

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

#option_for(token) ⇒ Object

Find the option that matches the given flag token.



105
106
107
# File 'lib/samovar/options.rb', line 105

def option_for(token)
	@keyed[token]
end

#parse(input, parent = nil, default = nil) ⇒ Object

Parse options from the input.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/samovar/options.rb', line 165

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

#suggestions(prefix) ⇒ Object

Complete option flags for the given prefix.



238
239
240
241
242
243
244
245
246
# File 'lib/samovar/options.rb', line 238

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

#to_sObject

Generate a string representation for usage output.



251
252
253
# File 'lib/samovar/options.rb', line 251

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

#usage(rows) ⇒ Object

Generate usage information for this options collection.



258
259
260
261
262
# File 'lib/samovar/options.rb', line 258

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