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



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

def initialize command, args = [], options = {}
  @command = command
  @options = options
  @args    = args
  @environment = {}
  @cmdexe = @options.delete(:cmdexe) || false
  @prepend_cmds = @options.delete(:prepend_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|
     if @options[k].is_a?(Hash)
       @environment = @environment.merge(@options.delete(k))
     end
  end

end

Instance Attribute Details

#argsObject

An array of additional arguments to be supplied to the command



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

def args
  @args
end

#commandObject

A string representing the (possibly) incomplete command



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

def command
  @command
end

#environmentObject

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



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

def environment
  @environment
end

#optionsObject

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



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

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.



128
129
130
# File 'lib/beaker/command.rb', line 128

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

#cmd_line(host, cmd = @command, env = @environment, pc = @prepend_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.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/beaker/command.rb', line 72

def cmd_line host, cmd = @command, env = @environment, pc = @prepend_cmds
  env_string = host.environment_string( env )
  prepend_commands = host.prepend_commands( cmd, pc, :cmd_exe => @cmdexe )
  if host[:platform] =~ /cisco/ && host[:user] != 'root'
    append_command = '"'
    cmd = cmd.gsub('"') { '\\"' }
  end

  # This will cause things like `puppet -t -v agent` which is maybe bad.
  if host[:platform] =~ /cisco_ios_xr/ 
    cmd_line_array = [prepend_commands, env_string, cmd, options_string, args_string]
  else
    cmd_line_array = [env_string, prepend_commands, cmd, options_string, args_string]
  end
  cmd_line_array << append_command unless (cmd =~ /ntpdate/ && host[:platform] =~ /cisco_nexus/)
  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.



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

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