Class: U3dCore::CommandExecutor
- Inherits:
-
Object
- Object
- U3dCore::CommandExecutor
- Defined in:
- lib/u3d_core/command_executor.rb
Overview
Executes commands and takes care of error handling and more
Class Method Summary collapse
-
.execute(command: nil, print_all: false, print_command: true, error: nil, prefix: nil, loading: nil, admin: false) ⇒ String
All the output as string.
- .has_admin_privileges? ⇒ Boolean
-
.which(cmd) ⇒ Object
Cross-platform way of finding an executable in the $PATH.
Class Method Details
.execute(command: nil, print_all: false, print_command: true, error: nil, prefix: nil, loading: nil, admin: false) ⇒ String
Returns All the output as string.
60 61 62 63 64 65 66 67 68 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 103 104 105 106 107 108 109 110 |
# File 'lib/u3d_core/command_executor.rb', line 60 def execute(command: nil, print_all: false, print_command: true, error: nil, prefix: nil, loading: nil, admin: false) print_all = true if U3dCore::Globals.verbose? prefix ||= {} output = [] command = command.join(' ') if command.is_a?(Array) UI.command(command) if print_command # this is only used to show the "Loading text"... UI.command_output(loading) if print_all && loading if admin cred = U3dCore::Credentials.new(user: ENV['USER']) if Helper.windows? raise CredentialsError, "The command \'#{command}\' must be run in administrative shell" unless has_admin_privileges? else command = "sudo -k && echo #{cred.password.shellescape} | sudo -S " + command end UI.verbose 'Admin privileges granted for command execution' end begin status = U3dCore::Runner.run(command) do |stdin, _stdout, _pid| stdin.each do |l| line = l.strip # strip so that \n gets removed output << line next unless print_all # Prefix the current line with a string prefix.each do |element| line = element[:prefix] + line if element[:block] && element[:block].call(line) end UI.command_output(line) end end raise "Exit status: #{status}".red if status.nonzero? && !status.nil? rescue => ex # This could happen # * if the status is failed # * when the environment is wrong: # > invalid byte sequence in US-ASCII (ArgumentError) output << ex.to_s o = output.join("\n") UI.verbose o raise ex unless error error.call(o, nil) end return output.join("\n") end |
.has_admin_privileges? ⇒ Boolean
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/u3d_core/command_executor.rb', line 112 def has_admin_privileges? if Helper.windows? begin result = system('reg query HKU\\S-1-5-19', out: File::NULL, err: File::NULL) rescue result = false end else credentials = U3dCore::Credentials.new(user: ENV['USER']) begin # FIXME: hide / show output result = system("sudo -k && echo #{credentials.password.shellescape} | sudo -S /usr/bin/whoami") rescue result = false end credentials.forget_credentials unless result # FIXME: why? end # returns false if result is nil (command execution fail) return (result ? true : false) end |
.which(cmd) ⇒ Object
Cross-platform way of finding an executable in the $PATH. Respects the $PATHEXT, which lists valid file extensions for executables on Windows.
which('ruby') #=> /usr/bin/ruby
Derived from stackoverflow.com/a/5471032/3005
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/u3d_core/command_executor.rb', line 36 def which(cmd) # PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated. # e.g. ".COM;.EXE;.BAT;.CMD" exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| exts.each do |ext| cmd_path = File.("#{cmd}#{ext}", path) return cmd_path if File.executable?(cmd_path) && !File.directory?(cmd_path) end end return nil end |