Class: Ing::Task

Inherits:
Object
  • Object
show all
Defined in:
lib/ing/task.rb

Overview

A base class to simplify typical task use-cases. Adds some class methods and state to allow inherited options/flexibly- ordered option specification. Note that options are inherited to subclasses, but description and usage lines are not.

Direct Known Subclasses

Generator

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Task

Returns a new instance of Task.



130
131
132
# File 'lib/ing/task.rb', line 130

def initialize(options)
  self.options = initial_options(options)
end

Class Attribute Details

.inherited_optionsObject

Returns the value of attribute inherited_options.



14
15
16
# File 'lib/ing/task.rb', line 14

def inherited_options
  @inherited_options
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



129
130
131
# File 'lib/ing/task.rb', line 129

def options
  @options
end

#shellObject

Returns the value of attribute shell.



129
130
131
# File 'lib/ing/task.rb', line 129

def shell
  @shell
end

Class Method Details

.all_optionsObject

Options merged into inherited options. This is only used by the inherited hook (on subclassing), and should not be used otherwise.



117
118
119
# File 'lib/ing/task.rb', line 117

def all_options
  (inherited_options || {}).merge(options)
end

.default(name, val) ⇒ Object

Modify the default for option name to val. Option will be created if it doesn’t exist.



50
51
52
# File 'lib/ing/task.rb', line 50

def default(name, val)
  modify_option name, {:default => val}
end

.desc(line = "") ⇒ Object Also known as: description

Add a description line



55
56
57
# File 'lib/ing/task.rb', line 55

def desc(line="")
  desc_lines << line
end

.desc_linesObject

Description lines



100
101
102
# File 'lib/ing/task.rb', line 100

def desc_lines
  @desc_lines ||= []
end

.inherited(subclass) ⇒ Object

On subclassing, deep copy the merge of current options into inherited options



18
19
20
# File 'lib/ing/task.rb', line 18

def inherited(subclass)
  subclass.inherited_options = Marshal.load(Marshal.dump(self.all_options))
end

.inherited_option?(name) ⇒ Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/ing/task.rb', line 22

def inherited_option?(name)
  inherited_options.has_key?(name)
end

.modify_option(name, specs) ⇒ Object

Modify the option named name according to specs (Hash). Option will be created if it doesn’t exist.

Example:

modify_option :file, :required => true


37
38
39
40
41
42
43
44
45
# File 'lib/ing/task.rb', line 37

def modify_option(name, specs)
  if inherited_option?(name)
    inherited_options[name].opts.merge!(specs)
  elsif option?(name)
    options[name].opts.merge!(specs)
  else
    opt(name, '', specs)
  end
end

.opt(name, desc = "", settings = {}) ⇒ Object Also known as: option

Add an option. Note the syntax is identical to Trollop::Parser#opt



66
67
68
# File 'lib/ing/task.rb', line 66

def opt(name, desc="", settings={})
  options[name] = Option.new(name, desc, settings)
end

.option?(name) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/ing/task.rb', line 26

def option?(name)
  options.has_key?(name)
end

.optionsObject

Options hash. Note that in a subclass, options are copied down from superclass into inherited_options.



111
112
113
# File 'lib/ing/task.rb', line 111

def options
  @options ||= {}
end

.specify_options(parser) ⇒ Object

Build option parser based on desc, usage, and options (including inherited options). This method is called by Ing::Command. Note that this assumes the syntax of the Trollop parser.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/ing/task.rb', line 75

def specify_options(parser)
  desc_lines.each do |line|
    parser.text line
  end
  unless usage_lines.empty?
    parser.text "\nUsage:"
    usage_lines.each do |line|
      parser.text line
    end
  end
  unless options.empty?
    parser.text "\nOptions:"
    options.each do |name, opt|
      parser.opt *opt.to_args
    end
  end
  unless inherited_options.empty?
    parser.text "\nCommon Options:"
    inherited_options.each do |name, opt|
      parser.opt *opt.to_args
    end
  end
end

.usage(line = "") ⇒ Object

Add a usage line



61
62
63
# File 'lib/ing/task.rb', line 61

def usage(line="")
  usage_lines << line
end

.usage_linesObject

Usage lines



105
106
107
# File 'lib/ing/task.rb', line 105

def usage_lines
  @usage_lines ||= []
end

Instance Method Details

#ask_unless_given(*opts) ⇒ Object

Build a hash of options that weren’t given from command line via ask (i.e., $stdin.gets).

Note it currently does not cast options to appropriate types. Also note because the shell is not available until after initialization, this must be called from command method(s), e.g. #call



146
147
148
149
150
151
152
153
154
# File 'lib/ing/task.rb', line 146

def ask_unless_given(*opts)
  opts.inject({}) do |memo, opt|
    next memo if options[:"#{opt}_given"]
    msg = self.class.options[opt].desc + "?"
    df  = self.class.options[opt].default
    memo[opt] = shell.ask(msg, :default => df)
    memo
  end
end

#ask_unless_given!(*opts) ⇒ Object

Shortcut for:

options.merge! ask_unless_given :opt1, :opt2


160
161
162
# File 'lib/ing/task.rb', line 160

def ask_unless_given!(*opts)
  self.options.merge! ask_unless_given(*opts)
end

#initial_options(given) ⇒ Object

Override in subclass for adjusting given options on initialization



135
136
137
# File 'lib/ing/task.rb', line 135

def initial_options(given)
  given
end

#validate_option(opt, desc = opt, msg = nil) ⇒ Object

Use in initialization for option validation (post-parsing).

Example:

validate_option(:color, "Color must be :black or :white") do |actual|
  [:black, :white].include?(actual)
end


172
173
174
175
# File 'lib/ing/task.rb', line 172

def validate_option(opt, desc=opt, msg=nil)
  msg ||= "Error in option #{desc} for `#{self.class}`."
  !!yield(self.options[opt]) or raise ArgumentError, msg
end

#validate_option_exists(opt, desc = opt) ⇒ Object

Validate that the option was passed or otherwise defaulted to something truthy. Note that in most cases, instead you should set :required => true on the option and let Trollop catch the error – rather than catching it post-parsing.

Note validate_option_exists will raise an error if the option is passed but false or nil, unlike the Trollop parser.



184
185
186
187
188
189
# File 'lib/ing/task.rb', line 184

def validate_option_exists(opt, desc=opt)
  msg = "No #{desc} specified for #{self.class}. You must either " +
        "specify a `--#{opt}` option or set a default in #{self.class} or " +
        "in its superclass(es)."
  validate_option(opt, desc, msg) {|val| val }
end