Class: RVM::Shell::AbstractWrapper

Inherits:
Object
  • Object
show all
Includes:
Utility
Defined in:
lib/rvm/shell/abstract_wrapper.rb

Overview

Provides the most common functionality expected of a shell wrapper. Namely, implements general utility methods and tools to extract output from a given command but doesn’t actually run any commands itself, leaving that up to concrete implementations.

Usage

Commands are run inside of a shell (usually bash) and can either be exectuted in two situations (each with wrapper methods available) - silently or verbosely.

Silent commands (via run_silently and run_command) do exactly as they say - that can modify the environment etc but anything they print (to stdout or stderr) will be discarded.

Verbose commands will run the command and then print the command epilog (which contains the output stastus and the current env in yaml format). This allows us to not only capture all output but to also return the exit status and environment variables in a way that makes persisted shell sessions possible.

Under the hood, #run and run_silently are the preferred ways of invoking commands - if passed a single command, they’ll run it as is (much like system in ruby) but when given multiple arguments anything after the first will be escaped (e.g. you can hence pass code etc). #run will also parse the results of this epilog into a usable RVM::Shell::Result object.

run_command and run_command_silently do the actual hard work for these behind the scenes, running a string as the shell command. Hence, these two commands are what must be implemented in non-abstract wrappers.

For an example of the shell wrapper functionality in action, see RVM::Environment which delegates most of the work to a shell wrapper.

Direct Known Subclasses

SingleShotWrapper

Constant Summary collapse

COMMAND_EPILOG_START =

Used the mark the end of a commands output and the start of the rvm env.

"---------------RVM-RESULTS-START---------------"
COMMAND_EPILOG_END =

Used to mark the end of the commands epilog.

"----------------RVM-RESULTS-END----------------"
WRAPPER_LOCATION =

The location of the shell file with the epilog function definition.

File.expand_path('./shell_wrapper.sh', File.dirname(__FILE__))

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utility

#build_cli_call, #escape_argument, #escape_arguments

Constructor Details

#initialize(sh = 'bash', &setup_block) ⇒ AbstractWrapper

Initializes a new shell wrapper, including setting the default setup block. Implementations must override this method but must ensure that they call super to perform the expected standard setup.



52
53
54
55
# File 'lib/rvm/shell/abstract_wrapper.rb', line 52

def initialize(sh = 'bash', &setup_block)
  setup &setup_block
  @shell_executable = sh
end

Instance Attribute Details

#shell_executableObject (readonly)

Defines the shell exectuable.



46
47
48
# File 'lib/rvm/shell/abstract_wrapper.rb', line 46

def shell_executable
  @shell_executable
end

Instance Method Details

#[](var_name) ⇒ Object

Returns a given environment variables’ value.



96
97
98
# File 'lib/rvm/shell/abstract_wrapper.rb', line 96

def [](var_name)
  run(:true)[var_name]
end

#run(command, *arguments) ⇒ Object

Runs the gives command (with optional arguments), returning an RVM::Shell::Result object, including stdout / stderr streams. Under the hood, uses run_command to actually process it all.



69
70
71
72
73
# File 'lib/rvm/shell/abstract_wrapper.rb', line 69

def run(command, *arguments)
  expanded_command = build_cli_call(command, arguments)
  status, out, err = run_command(expanded_command)
  Result.new(expanded_command, status, out, err)
end

#run_command(full_command) ⇒ Object

Given a command, it will execute it in the current wrapper and once done, will return:

  • the hash from the epilog output.

  • a string representing stdout.

  • a string representing stderr.

Raises:

  • (NotImplementedError)


86
87
88
# File 'lib/rvm/shell/abstract_wrapper.rb', line 86

def run_command(full_command)
  raise NotImplementedError.new("run_command is only available in concrete implementations")
end

#run_command_silently(full_command) ⇒ Object

Like run_command, but doesn’t care about output.

Raises:

  • (NotImplementedError)


91
92
93
# File 'lib/rvm/shell/abstract_wrapper.rb', line 91

def run_command_silently(full_command)
  raise NotImplementedError.new("run_command_silently is only available in concrete implementations")
end

#run_silently(command, *arguments) ⇒ Object

Wrapper around run_command_silently that correctly escapes arguments. Essentially, #run but using run_command_silently.



77
78
79
# File 'lib/rvm/shell/abstract_wrapper.rb', line 77

def run_silently(command, *arguments)
  run_command_silently build_cli_call(command, arguments)
end

#setup(&blk) ⇒ Object

Defines a setup block to be run when initiating a wrapper session. Usually used for doing things such as sourcing the rvm file. Please note that the wrapper file is automatically source.

The setup block should be automatically run by wrapper implementations.



62
63
64
# File 'lib/rvm/shell/abstract_wrapper.rb', line 62

def setup(&blk)
  @setup_block = blk
end