Module: Minicron::CLI

Defined in:
lib/minicron/cli.rb,
lib/minicron/cli/commands.rb

Overview

Handles the main CLI interaction of minicron TODO: this class is probably too complicated and should be refactored a bit

Defined Under Namespace

Classes: Commands

Class Method Summary collapse

Class Method Details

.coloured_output?Boolean

Whether or not coloured output of the rainbox gem is enabled, this is enabled by default

Returns:

  • (Boolean)

    whether rainbow is enabled or not


160
161
162
# File 'lib/minicron/cli.rb', line 160

def self.coloured_output?
  Rainbow.enabled
end

.disable_coloured_output!Boolean

Disable coloured terminal output from the rainbow gem, this is enabled by default

Returns:

  • (Boolean)

    whether rainbow is enabled or not


176
177
178
# File 'lib/minicron/cli.rb', line 176

def self.disable_coloured_output!
  Rainbow.enabled = false
end

.enable_coloured_output!Boolean

Enable coloured terminal output from the rainbow gem, this is enabled by default

Returns:

  • (Boolean)

    whether rainbow is enabled or not


168
169
170
# File 'lib/minicron/cli.rb', line 168

def self.enable_coloured_output!
  Rainbow.enabled = true
end

.parse_config(opts) ⇒ Object

Function to the parse the config of the options passed to commands

Parameters:

  • opts (Hash)

    The Commander provided options hash


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/minicron/cli.rb', line 21

def self.parse_config(opts)
  # Parse the --config file options if it was passed
  Minicron.parse_file_config(opts.config)

  # Parse the cli options
  Minicron.parse_config_hash(
    'verbose' => opts.verbose,
    'trace' => opts.trace,
    'cli' => {
      'mode' => opts.mode,
      'dry_run' => opts.dry_run
    },
    'server' => {
      'host' => opts.host,
      'port' => opts.port,
      'path' => opts.path,
      'debug' => opts.debug
    }
  )
end

.run(argv) {|output| ... } ⇒ Object

Sets up an instance of commander and runs it based on the argv param

i.e when the argv param is ['run']. A second option (the command to execute) should be present in the array

Parameters:

  • argv (Array)

    an array of arguments passed to the cli

Yield Parameters:

  • output (String)

    output from the cli

Raises:

  • (ArgumentError)

    if no arguments are passed to the run cli command


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/minicron/cli.rb', line 58

def self.run(argv)
  # replace ARGV with the contents of argv to aid testability
  ARGV.replace(argv)

  # Get an instance of commander
  @cli = Commander::Runner.new

  # Set some default otions on it
  setup

  # Add the run command to the cli
  Minicron::CLI::Commands.add_run_cli_command(@cli) { |output| yield output }

  # Add the server command to the cli
  Minicron::CLI::Commands.add_server_cli_command(@cli)

  # Add the db command to the cli
  Minicron::CLI::Commands.add_db_cli_command(@cli)

  # And off we go!
  @cli.run!
end

.run_command(command, options = {}) {|output| ... } ⇒ Object

Executes a command in a pseudo terminal and yields the output

command output. Either 'line' by line or 'char' by char. information for debugging purposes.

Parameters:

  • command (String)

    the command to execute e.g 'ls'

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • mode (String) — default: 'line'

    the method to yield the

  • verbose (Boolean)

    whether or not to output extra

Yield Parameters:

  • output (String)

    output from the command execution


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
148
149
150
151
152
153
154
# File 'lib/minicron/cli.rb', line 89

def self.run_command(command, options = {})
  # Default the options
  options[:mode] ||= 'line'
  options[:verbose] ||= false

  # Record the start time of the command
  start = Time.now.utc
  subtract_total = 0

  # yield the start time
  subtract = Time.now.utc
  yield structured :status, "START #{start.strftime("%Y-%m-%d %H:%M:%S")}"
  subtract_total += Time.now.utc - subtract

  # Spawn a process to run the command
  begin
    PTY.spawn(command) do |stdout, stdin, pid|

      # Output some debug info
      if options[:verbose]
        subtract = Time.now.utc
        yield structured :verbose, '[minicron]'.colour(:magenta)
        yield structured :verbose, ' started running '.colour(:blue) + "`#{command}`".colour(:yellow) + " at #{start}\n\n".colour(:blue)
        subtract_total += Time.now.utc - subtract
      end

      begin
        # Loop until data is no longer being sent to stdout
        until stdout.eof?
          # One character at a time or one line at a time?
          output = options[:mode] == 'char' ? stdout.read(1) : stdout.readline

          subtract = Time.now.utc
          yield structured :command, output
          subtract_total += Time.now.utc - subtract
        end
      # See https://github.com/ruby/ruby/blob/57fb2199059cb55b632d093c2e64c8a3c60acfbb/ext/pty/pty.c#L519
      rescue Errno::EIO
      ensure
        # Force waiting for the process to finish so we can get the exit status
        Process.wait pid
      end
    end
  rescue Errno::ENOENT
    raise Exception, "Running the command `#{command}` failed, are you sure it exists?"
  ensure
    # Record the time the command finished
    finish = Time.now.utc - subtract_total
    exit_status = $CHILD_STATUS.exitstatus ? $CHILD_STATUS.exitstatus : nil

    # yield the finish time and exit status
    yield structured :status, "FINISH #{finish.strftime("%Y-%m-%d %H:%M:%S")}"
    yield structured :status, "EXIT #{exit_status}"

    # Output some debug info
    if options[:verbose]
      yield structured :verbose, "\n" + '[minicron]'.colour(:magenta)
      yield structured :verbose, ' finished running '.colour(:blue) + "`#{command}`".colour(:yellow) + " at #{start}\n".colour(:blue)
      yield structured :verbose, '[minicron]'.colour(:magenta)
      yield structured :verbose, ' running '.colour(:blue) + "`#{command}`".colour(:yellow) + " took #{finish - start}s\n".colour(:blue)
      yield structured :verbose, '[minicron]'.colour(:magenta)
      yield structured :verbose, " `#{command}`".colour(:yellow) + ' finished with an exit status of '.colour(:blue)
      yield structured :verbose, exit_status == 0 ? "#{exit_status}\n".colour(:green) : "#{exit_status}\n".colour(:red)
    end
  end
end

.structured(type, output) ⇒ Hash

Used as a helper for yielding command output, returns it in a structured hash

Parameters:

  • type (Symbol)

    The type of command output, currently one of :status, :command and :verbose

  • output (String)

Returns:

  • (Hash)

47
48
49
# File 'lib/minicron/cli.rb', line 47

def self.structured(type, output)
  { :type => type, :output => output }
end