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

Constant Summary collapse

DEFAULT_GIT_RUBYLIB =
{
  :default => [],
  :host => %w(hieralibdir hierapuppetlibdir
              pluginlibpath puppetlibdir
              facterlibdir),
  :opts => { :additive => true,
             :separator => {:host => 'pathseparator' }
  }
}
DEFAULT_GIT_PATH =
{
  :default => [],
  :host => %w(puppetbindir facterbindir hierabindir),
  :opts => { :additive => true, :separator => ':' }
}
DEFAULT_GIT_ENV =
{ :PATH => DEFAULT_GIT_PATH, :RUBYLIB => DEFAULT_GIT_RUBYLIB }

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



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/beaker/command.rb', line 65

def initialize command, args = [], options = {}
  @command = command
  @options = options
  @args    = args
  @environment = {}

  # 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



36
37
38
# File 'lib/beaker/command.rb', line 36

def args
  @args
end

#commandObject

A string representing the (possibly) incomplete command



27
28
29
# File 'lib/beaker/command.rb', line 27

def command
  @command
end

#environmentObject

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



30
31
32
# File 'lib/beaker/command.rb', line 30

def environment
  @environment
end

#optionsObject

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



33
34
35
# File 'lib/beaker/command.rb', line 33

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.



132
133
134
# File 'lib/beaker/command.rb', line 132

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

#cmd_line(host, cmd = @command, env = @environment) ⇒ 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

Returns:

  • (String)

    This returns the fully formed command line invocation.



87
88
89
90
91
92
# File 'lib/beaker/command.rb', line 87

def cmd_line host, cmd = @command, env = @environment
  env_string = env.nil? ? '' : environment_string_for( host, env )

  # This will cause things like `puppet -t -v agent` which is maybe bad.
  "#{env_string} #{cmd} #{options_string} #{args_string}"
end

#environment_string_for(host, env) ⇒ String

Note:

I dislike the principle of this method. There is host specific knowledge contained here. Really the relationship should be reversed where a host is asked for an appropriate Command when given a generic Command.

Determine the appropriate env commands for the given host.

Parameters:

  • host (Host)

    A Host object

  • env (Hash{String=>String})

    An optional Hash containing key-value pairs to be treated as environment variables that should be set for the duration of the puppet command.

Returns:

  • (String)

    Returns a string containing command line arguments that will ensure the environment is correctly set for the given host.



153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/beaker/command.rb', line 153

def environment_string_for host, env
  return '' if env.empty?

  env_array = parse_env_hash_for( host, env ).compact

  # cygwin-ism
  cmd = host['platform'] =~ /windows/ ? 'cmd.exe /c' : nil
  env_array << cmd if cmd

  environment_string = env_array.join(' ')

  "env #{environment_string}"
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.



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

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