Class: Sym::App::CLI

Inherits:
Object show all
Includes:
CLISlop
Defined in:
lib/sym/app/cli.rb

Overview

This is the main interface class for the CLI application. It is responsible for parsing user’s input, providing help, examples, coordination of various sub-systems (such as PrivateKey detection), etc.

Besides holding the majority of the application state, it contains two primary public methods: #new and #run.

The constructor is responsible for parsing the flags and determining the the application is about to do. It sets up input/output, but doesn’t really execute any encryption or decryption. This happens in the #run method called immediately after #new.

{Shh{Shh::App{Shh::App::CLI} module effectively performs the translation of the opts object (of type Slop::Result) and interpretation of users intentions. It holds on to opts for the duration of the program.

Responsibility Delegated

The responsibility of determining the private key from various options provided is performed by the PrivateKey::Handler instance. See there for more details.

Subsequently, #run method handles the finding of the appropriate Sym::App::Commands::BaseCommand subclass to respond to user’s request. Command registry, sorting, command dependencies, and finding them is done by the Coommands module.

User input is handled by the Input::Handler instance, while the output is provided by the procs in the Output classes.

Finally, the Mac OS-X -specific usage of the KeyChain, is encapsulated in a cross-platform way inside the Keychain module.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from CLISlop

#key_spec, #parse

Constructor Details

#initialize(argv, stdin = $stdin, stdout = $stdout, stderr = $stderr, kernel = nil) ⇒ CLI

Returns a new instance of CLI.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/sym/app/cli.rb', line 61

def initialize(argv, stdin = $stdin, stdout = $stdout, stderr = $stderr, kernel = nil)
  self.args   = argv
  self.stdin  = stdin
  self.stdout = stdout
  self.stderr = stderr
  self.kernel = kernel

  Sym::App.stdin  = stdin
  Sym::App.stdout = stdout
  Sym::App.stderr = stderr

  begin
    # Re-map any legacy options to the new options
    self.opts = parse(args)

    if opts[:user_home]
      Constants.user_home = opts[:user_home]
      raise InvalidSymHomeDirectory, "#{opts[:user_home]} does not exist!" unless Dir.exist?(Constants.user_home)
    end

    # Deal with SYM_ARGS and -A
    if opts[:sym_args] && non_empty_array?(sym_args)
        args << sym_args
        args.flatten!
        args.compact!
        args.delete('-A')
        args.delete('--sym-args')
        self.opts = parse(args)
    end

    # Disable coloring if requested, or if piping STDOUT
    if opts[:no_color] || !self.stdout.tty?
      Colored2.disable! # reparse options without the colors to create new help msg
      self.opts = parse(args)
    end

  rescue StandardError => e
    log :error, "#{e.message}" if opts
    error exception: e
    quit!(127) if stdin == $stdin
  end

  self.application = ::Sym::Application.new(self.opts, stdin, stdout, stderr, kernel)
end

Instance Attribute Details

#applicationObject

Returns the value of attribute application.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def application
  @application
end

#argsObject

Returns the value of attribute args.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def args
  @args
end

#kernelObject

Returns the value of attribute kernel.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def kernel
  @kernel
end

#optsObject

Returns the value of attribute opts.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def opts
  @opts
end

#outputsObject

Returns the value of attribute outputs.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def outputs
  @outputs
end

#stderrObject

Returns the value of attribute stderr.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def stderr
  @stderr
end

#stdinObject

Returns the value of attribute stdin.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def stdin
  @stdin
end

#stdoutObject

Returns the value of attribute stdout.



59
60
61
# File 'lib/sym/app/cli.rb', line 59

def stdout
  @stdout
end

Instance Method Details

#commandObject



128
129
130
# File 'lib/sym/app/cli.rb', line 128

def command
  @command ||= self.application.command if self.application
end

#executeObject



118
119
120
121
122
123
124
125
126
# File 'lib/sym/app/cli.rb', line 118

def execute
  return Sym::App.exit_code if Sym::App.exit_code != 0
  result = application.execute
  if result.is_a?(Hash)
    self.output_proc ::Sym::App::Args.new({}).output_class
    error(result)
  end
  Sym::App.exit_code
end

#execute!Object



114
115
116
# File 'lib/sym/app/cli.rb', line 114

def execute!
  execute
end

#log(*args) ⇒ Object



146
147
148
# File 'lib/sym/app/cli.rb', line 146

def log(*args)
  Sym::App.log(*args, **opts.to_hash)
end

#opts_presentObject



140
141
142
143
144
# File 'lib/sym/app/cli.rb', line 140

def opts_present
  opts.to_hash.tap do |o|
    o.keys.map { |k| opts[k] ? nil : k }.compact.each { |k| o.delete(k) }
  end
end

#output_proc(proc = nil) ⇒ Object



132
133
134
135
136
137
138
# File 'lib/sym/app/cli.rb', line 132

def output_proc(proc = nil)
  if self.application
    self.application.output = proc if proc
    return self.application.output
  end
  nil
end

#quit!(code = 0) ⇒ Object



106
107
108
# File 'lib/sym/app/cli.rb', line 106

def quit!(code = 0)
  exit(code)
end

#sym_argsObject



110
111
112
# File 'lib/sym/app/cli.rb', line 110

def sym_args
  (ENV['SYM_ARGS']&.split(/\s+/) || [])
end