Class: CSD::Options

Inherits:
GlobalOpenStruct show all
Defined in:
lib/csd/options.rb

Overview

A class that handles the command line option parsing and manipulation

Class Method Summary collapse

Methods inherited from GlobalOpenStruct

method_missing

Class Method Details

.clearObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/csd/options.rb', line 41

def self.clear
  # First we define all valid actions and scopes
  self.actions = []
  self.scopes  = []
  # Then we define the default literals
  self.help        = false
  self.application = nil
  self.action      = nil
  # Now we define the default options
  self.yes       = false
  self.dry       = false
  self.reveal    = false
  self.verbose   = false
  self.debug     = false
  self.silent    = false
  self.developer = false
end

.define_actions_and_scopesObject



32
33
34
35
36
37
38
39
# File 'lib/csd/options.rb', line 32

def self.define_actions_and_scopes
  if Applications.current
    # Here we overwrite the default supported actions and scopes with the application specific ones
    self.actions = Applications.current.actions
    # At this point we know that the first argument is no option, but *some* action (may it be valid or not)
    self.scopes  = Applications.current.scopes(self.action)
  end
end

.parse!Object



18
19
20
21
22
23
# File 'lib/csd/options.rb', line 18

def self.parse!
  clear
  parse_literals
  define_actions_and_scopes
  parse_options
end

.parse_literalsObject

Here we check for literals, i.e. “help”, ACTION and APPLICATION.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/csd/options.rb', line 61

def self.parse_literals
  # First let's see whether we are in help mode, i.e. whether the first argument is `help´.
  # If so, we would like to remove it from the ARGV list.
  if ARGV.first == 'help'
    self.help = true
    ARGV.shift
  end
  # The action and the application name are the other literals we're interested in at this point.
  # Note: If there is no application specified, there is pretty much nothing we can do for the user.
  if Applications.current and Applications.current.name == ARGV.first
    # The application name is the first argument (i.e. there is no action specified at all)
    # Let's store the application name and remove it from the argument line
    self.application = ARGV.shift
  elsif Applications.current and Applications.current.name == ARGV.second
    # The second argument is the application name. This means that the first argument must be the
    # action or happens to be some option. In case it's no option, lets take it as desired action.
    unless ARGV.first.starts_with?('-')
      self.action      = ARGV.shift
      self.application = ARGV.shift # Removing the application name from the argument list
    end
  end
end

.parse_optionsObject

Parse all options that the user gave as command parameter. Note that this function strips the options from ARGV and leaves only literal (non-option) parameters (i.e. actions/applications/scopes; strings without – and -).



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/csd/options.rb', line 87

def self.parse_options
  OptionParser.new do |opts|
    self.banner = Applications.current ? "ADVANCED HELP FOR #{Applications.current.name}" : "Usage: ".bold + "ai [help] [TASK] APPLICATION [OPTIONS]"
    opts.banner = self.banner.magenta.bold

    unless Applications.current
      opts.headline "EXAMPLE COMMANDS".green.bold
      opts.list_item 'ai', 'Lists all available applications'
      opts.list_item 'ai minisip', 'Lists available tasks for the application MiniSIP'
      opts.list_item 'ai minisip --developer', 'Lists advanced AI tasks for the application MiniSIP'
      opts.list_item 'ai compile minisip', 'Downloads MiniSIP and compiles it'
      opts.list_item 'ai help compile minisip', 'Shows more details about the different compiling options'
    end
  
    # Here we load application-specific options file.
    # TODO: There must be a better way for this in general than to eval the raw ruby code
    begin
      unless Applications.current.options(self.action).size.blank?
        opts.headline "#{self.action.to_s.upcase} #{Applications.current.name.upcase} OPTIONS".green.bold
        eval Applications.current.options(self.action)
      else
        UI.debug "There were no options to be loaded from #{Applications.current}" 
      end
    rescue SyntaxError => e
      raise Error::Application::OptionsSyntax, "The individual options of #{Applications.current.inspect} could not be parsed (SyntaxError)."
    end if Applications.current
    
    # And here we load all general options
    options_prepend = Applications.current ? 'GENERAL ' : nil
    opts.headline "#{options_prepend}OPTIONS".green.bold
    opts.on("-y", "--yes", "Answer all questions with `yes´ (batch mode)") do |value|
      self.yes = value
    end
    opts.on("-p", "--dry","Don't actually execute any commands (preview mode)") do |value|
      self.dry = value
    end
    opts.on("-r", "--reveal","List all commands that normally would be executed in this operation") do |value|
      self.reveal = value
    end
    opts.on("-e", "--verbose","Show more elaborate output") do |value|
      self.verbose = value
    end
    opts.on("-d", "--debug","Show more elaborate output and debugging information") do |value|
      self.debug = value
    end
    opts.on("-s", "--silent","Don't show any output") do |value|
      self.silent = value
    end
    opts.on_tail("-a", "--developer", "Activating advanced AI functionality (developers only)") do |value|
      self.developer = value
    end
    opts.on_tail("-h", "--help", "Show detailed help (regarding the given ACTION and APPLICATION)") do |value|
      self.help = value
    end
    opts.on_tail("-v", "--version", "Show version") do
      puts "CSD Gem Version: #{CSD::VERSION}".blue
      exit
    end
    self.helptext = opts.help
  end.parse!
end

.valid_action?Boolean

Returns:

  • (Boolean)


25
26
27
28
29
30
# File 'lib/csd/options.rb', line 25

def self.valid_action?
  public_actions    = actions[:public] ? self.actions[:public].map { |pair| pair.keys.first } : []
  developer_actions = actions[:developer] ? self.actions[:developer].map { |pair| pair.keys.first } : []
  all_actions = public_actions + developer_actions
  all_actions.include?(self.action)
end