Class: Beaker::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/beaker/command.rb

Overview

An object that represents a “command” on a remote host. Is responsible for munging the environment correctly. Probably poorly named.

Direct Known Subclasses

HostCommand, PuppetCommand, SedCommand

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command, args = [], options = {}) ⇒ Command

Note:

For backwards compatability we must support any number of strings or symbols (or arrays of strings an symbols) and essentially ensure they are in a flattened array, coerced to strings, and call #join(‘ ’) on it. We have options for the command line invocation that must be turned into ‘–key=value’ and similarly joined as well as a hash of environment key value pairs, and finally we need a hash of options to control the default envs that are included.

Returns a new instance of Command.

Examples:

Recommended usage programmatically:

Command.new('git add', files, :patch => true, 'ENV' => {'PATH' => '/opt/csw/bin'})

My favorite example of a signature that we must maintain

Command.new('puppet', :resource, 'scheduled_task', name,
            [ 'ensure=present',
              'command=c:\\\\windows\\\\system32\\\\notepad2.exe',
              "arguments=args-#{name}" ] )

Parameters:

  • command (String)

    The program to call, either an absolute path or one in the PATH (can be overridden)

  • args (Array) (defaults to: [])

    These are addition arguments to the command

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

    These are addition options to the command. They will be added in “–key=value” after the command but before the arguments. There is a special key, ‘ENV’, that won’t be used as a command option, but instead can be used to set any default environment variables



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/beaker/command.rb', line 46

def initialize command, args = [], options = {}
  @command = command
  @options = options
  @args    = args
  @environment = {}
  @cmdexe = @options.delete(:cmdexe) || false
  @prepend_cmds = @options.delete(:prepend_cmds) || nil
  @append_cmds = @options.delete(:append_cmds) || nil

  # this is deprecated and will not allow you to use a command line
  # option of `--environment`, please use ENV instead.
  [:ENV, :environment, 'environment', 'ENV'].each do |k|
    @environment = @environment.merge(@options.delete(k)) if @options[k].is_a?(Hash)
  end
end

Instance Attribute Details

#argsObject

An array of additional arguments to be supplied to the command



17
18
19
# File 'lib/beaker/command.rb', line 17

def args
  @args
end

#commandObject

A string representing the (possibly) incomplete command



8
9
10
# File 'lib/beaker/command.rb', line 8

def command
  @command
end

#environmentObject

A hash key-values where the keys are environment variables to be set



11
12
13
# File 'lib/beaker/command.rb', line 11

def environment
  @environment
end

#optionsObject

A hash of options. Keys with values of nil are considered flags



14
15
16
# File 'lib/beaker/command.rb', line 14

def options
  @options
end

Instance Method Details

#args_string(args = @args) ⇒ String

Returns String of the arguments for command.

Parameters:

  • args (Array) (defaults to: @args)

    An array of arguments to the command.

Returns:

  • (String)

    String of the arguments for command.



121
122
123
# File 'lib/beaker/command.rb', line 121

def args_string args = @args
  args.flatten.compact.join(' ')
end

#cmd_line(host, cmd = @command, env = @environment, pc = @prepend_cmds, ac = @append_cmds) ⇒ String

Returns This returns the fully formed command line invocation.

Parameters:

  • host (Host)

    An object that implements Host‘s interface.

  • cmd (String) (defaults to: @command)

    An command to call.

  • env (Hash) (defaults to: @environment)

    An optional hash of environment variables to be used

  • pc (String) (defaults to: @prepend_cmds)

    An optional list of commands to prepend

Returns:

  • (String)

    This returns the fully formed command line invocation.



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/beaker/command.rb', line 69

def cmd_line host, cmd = @command, env = @environment, pc = @prepend_cmds, ac = @append_cmds
  env_string = host.environment_string(env)
  prepend_commands = host.prepend_commands(cmd, pc, :cmd_exe => @cmdexe)
  append_commands = host.append_commands(cmd, ac, :cmd_exe => @cmdexe)

  # This will cause things like `puppet -t -v agent` which is maybe bad.
  cmd_line_array = if host[:platform]&.include?('cisco_ios_xr')
                     [prepend_commands, env_string, cmd, options_string, args_string, append_commands]
                   else
                     [env_string, prepend_commands, cmd, options_string, args_string, append_commands]
                   end
  cmd_line_array.compact.reject(&:empty?).join(' ')
end

#options_string(opts = @options) ⇒ String

Note:

Why no. Not the least bit Unixy, why do you ask?

Returns String of the options and flags for command.

Parameters:

  • opts (Hash) (defaults to: @options)

    These are the options that the command takes

Returns:

  • (String)

    String of the options and flags for command.



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
# File 'lib/beaker/command.rb', line 88

def options_string opts = @options
  flags = []
  options = opts.dup
  options.each_key do |key|
    if options[key] == nil
      flags << key
      options.delete(key)
    end
  end

  short_flags, long_flags = flags.partition { |flag| flag.to_s.length == 1 }
  parsed_short_flags = short_flags.map { |f| "-#{f}" }
  parsed_long_flags = long_flags.map { |f| "--#{f}" }

  short_opts, long_opts = {}, {}
  options.each_key do |key|
    if key.to_s.length == 1
      short_opts[key] = options[key]
    else
      long_opts[key] = options[key]
    end
  end
  parsed_short_opts = short_opts.map { |k, v| "-#{k}=#{v}" }
  parsed_long_opts = long_opts.map { |k, v| "--#{k}=#{v}" }

  return (parsed_short_flags +
          parsed_long_flags +
          parsed_short_opts + parsed_long_opts).join(' ')
end