Class: SystemWrapper

Inherits:
Object show all
Defined in:
lib/ceedling/system_wrapper.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSystemWrapper

Returns a new instance of SystemWrapper.



29
30
31
# File 'lib/ceedling/system_wrapper.rb', line 29

def initialize()
  @argv = ARGV.clone.freeze
end

Class Method Details

.time_stopwatch_sObject



19
20
21
22
23
24
25
26
27
# File 'lib/ceedling/system_wrapper.rb', line 19

def self.time_stopwatch_s
  # Wall clock time that can be adjusted for a variety of reasons and lead to
  # unexpected negative durations -- only option on Windows.
  return Time.now() if SystemWrapper.windows?

  # On Posix systems, this time value is a steadily increasing count from
  # a known system event (usually restart) and is more better
  return Process.clock_gettime( Process::CLOCK_MONOTONIC, :float_second )
end

.windows?Boolean

static method for use in defaults

Returns:

  • (Boolean)


14
15
16
17
# File 'lib/ceedling/system_wrapper.rb', line 14

def self.windows?
  return ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) if defined?(RbConfig)
  return ((Config::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false)
end

Instance Method Details

#add_load_path(path) ⇒ Object



131
132
133
134
# File 'lib/ceedling/system_wrapper.rb', line 131

def add_load_path(path)
  # Prevent trouble with string freezing by dup()ing paths here
  $LOAD_PATH.unshift( path.dup() )
end

#constants_include?(item) ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
148
# File 'lib/ceedling/system_wrapper.rb', line 145

def constants_include?(item)
  # forcing to strings provides consistency across Ruby versions
  return Object.constants.map{|constant| constant.to_s}.include?(item.to_s)
end

#env_get(name) ⇒ Object



58
59
60
# File 'lib/ceedling/system_wrapper.rb', line 58

def env_get(name)
  return ENV[name]
end

#env_set(name, value) ⇒ Object



54
55
56
# File 'lib/ceedling/system_wrapper.rb', line 54

def env_set(name, value)
  ENV[name] = value
end

#eval(string) ⇒ Object



42
43
44
# File 'lib/ceedling/system_wrapper.rb', line 42

def eval(string)
  return eval(string)
end

#get_cmdlineObject



50
51
52
# File 'lib/ceedling/system_wrapper.rb', line 50

def get_cmdline
  return @argv
end

#module_eval(string) ⇒ Object



38
39
40
# File 'lib/ceedling/system_wrapper.rb', line 38

def module_eval(string)
  return Object.module_eval("\"" + string + "\"")
end

#require_file(path) ⇒ Object



136
137
138
# File 'lib/ceedling/system_wrapper.rb', line 136

def require_file(path)
  require(path)
end

#ruby_success?Boolean

Returns:

  • (Boolean)


140
141
142
143
# File 'lib/ceedling/system_wrapper.rb', line 140

def ruby_success?
  # We are successful if we've never had an exit code that went boom (either because it's empty or it was 0)
  return ($exit_code.nil? || ($exit_code == 0)) && ($!.nil? || $!.is_a?(SystemExit) && $!.success?)
end

#search_pathsObject



46
47
48
# File 'lib/ceedling/system_wrapper.rb', line 46

def search_paths
  return ENV['PATH'].split(File::PATH_SEPARATOR)
end

#shell_backticks(command:, boom: false) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/ceedling/system_wrapper.rb', line 104

def shell_backticks(command:, boom:false)
  output = `#{command}`.freeze
  $exit_code = ($?.exitstatus).freeze if boom
  return {
    :output    => output.freeze,
    :exit_code => ($?.exitstatus).freeze
  }
end

#shell_capture3(command:, boom: false) ⇒ Object

If set, ‘boom` allows a non-zero exit code in results. Otherwise, disabled `boom` forces a success exit code but collects errors.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ceedling/system_wrapper.rb', line 69

def shell_capture3(command:, boom:false) 
  # Beginning with later versions of Ruby2, simple exit codes were replaced
  # by the more capable and robust Process::Status.
  # Parts of Process::Status's behavior is similar to an integer exit code in
  # some operations but not all.
  exit_code = 0

  stdout, stderr = '' # Safe initialization defaults
  status = nil        # Safe initialization default
  
  stdout, stderr, status = Open3.capture3( command )

  # If boom, then capture the actual exit code.
  # Otherwise, leave it as zero as though execution succeeded.
  exit_code = status.exitstatus.freeze if boom and !status.nil?

  # (Re)set the global system exit code so everything matches
  $exit_code = exit_code

  return {
    # Combine stdout & stderr streams for complete output
    :output    => (stdout + stderr).to_s.freeze,
    
    # Individual streams for detailed logging
    :stdout    => stdout.freeze,
    :stderr    => stderr.freeze,

    # Relay full Process::Status
    :status    => status.freeze,
    
    # Provide simple exit code accessor
    :exit_code => exit_code.freeze
  }
end

#shell_system(command:, args: [], verbose: false, boom: false) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/ceedling/system_wrapper.rb', line 113

def shell_system(command:, args:[], verbose:false, boom:false)
  result = nil

  if verbose
    # Allow console output
    result = system( command, *args )
  else
    # Shush the console output
    result = system( command, *args, [:out, :err] => File::NULL )
  end

  $exit_code = ($?.exitstatus).freeze if boom
  return {
    :result    => result.freeze,
    :exit_code => ($?.exitstatus).freeze
  }
end

#time_now(format = nil) ⇒ Object



62
63
64
65
# File 'lib/ceedling/system_wrapper.rb', line 62

def time_now(format=nil)
  return Time.now.asctime if format.nil?
  return Time.now.strftime( format )
end

#windows?Boolean

class method so as to be mockable for tests

Returns:

  • (Boolean)


34
35
36
# File 'lib/ceedling/system_wrapper.rb', line 34

def windows?
  return SystemWrapper.windows?
end