Class: Pmgmt
- Inherits:
-
Object
- Object
- Pmgmt
- Defined in:
- lib/pmgmt.rb
Constant Summary collapse
- @@commands =
State to hold registered commands. See register_command.
[]
- @@options_parser =
Convenience method to provide access to the options parsing utility class.
PmgmtLib::OptionsParser
Instance Attribute Summary collapse
-
#docker ⇒ Object
readonly
Convenience method to easily retrieve Docker utilities.
-
#sf ⇒ Object
readonly
Convenience method to easily retrieve file-syncing utilities.
Class Method Summary collapse
-
.commands ⇒ Array
The commands array for inspection.
-
.handle_or_die(args) ⇒ Object
Handles command execution.
-
.load_scripts(scripts_dir) ⇒ void
Loads all ‘.rb` scripts from the given directory.
- .OptionsParser ⇒ Object
-
.register_command(command) ⇒ void
Registers a command.
Instance Method Summary collapse
- #blue_term_text(text) ⇒ Object
- #bold_term_text(text) ⇒ Object
-
#capture_stdout(cmd, err: STDERR) ⇒ String
Runs the given command and captures its stdout.
-
#error(text) ⇒ void
Prints “error” text (red) on STDERR.
-
#initialize ⇒ Pmgmt
constructor
A new instance of Pmgmt.
- #load_env ⇒ Object
-
#pipe(*cmds) ⇒ Object
Accepts multiple arrays of commands and pipes each one to the next, failing if any command exits with an error.
- #print_usage ⇒ Object
- #put_command(cmd, redact: nil) ⇒ Object
- #red_term_text(text) ⇒ Object
-
#run(cmd) ⇒ Status
Runs a command without echoing.
-
#run_inline(cmd, redact: nil) ⇒ void
Runs the given command “inline,” meaning that it will take over the terminal while running.
-
#run_inline_swallowing_interrupt(cmd) ⇒ Object
Similar to #run_inline but will prevent exiting when an interrupt is encountered.
-
#run_or_fail(cmd, redact: nil) ⇒ Object
Runs a command and fails on non-success exit code.
-
#status(text) ⇒ void
Prints “status” text (blue) on STDERR.
-
#warning(text) ⇒ void
Prints “warning” text (yellow) on STDERR.
- #yellow_term_text(text) ⇒ Object
Constructor Details
#initialize ⇒ Pmgmt
Returns a new instance of Pmgmt.
119 120 121 122 |
# File 'lib/pmgmt.rb', line 119 def initialize() @docker = PmgmtLib::DockerHelper.new(self) @sf = PmgmtLib::SyncFiles.new(self) end |
Instance Attribute Details
#docker ⇒ Object (readonly)
Convenience method to easily retrieve Docker utilities. See PmgmtLib::DockerHelper.
115 116 117 |
# File 'lib/pmgmt.rb', line 115 def docker @docker end |
#sf ⇒ Object (readonly)
Convenience method to easily retrieve file-syncing utilities. See PmgmtLib::SyncFiles.
117 118 119 |
# File 'lib/pmgmt.rb', line 117 def sf @sf end |
Class Method Details
.commands ⇒ Array
Returns the commands array for inspection.
72 73 74 |
# File 'lib/pmgmt.rb', line 72 def self.commands() @@commands end |
.handle_or_die(args) ⇒ Object
Handles command execution.
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 111 112 |
# File 'lib/pmgmt.rb', line 78 def self.handle_or_die(args) if args.length == 0 or args[0] == "--help" self.new.print_usage exit 0 end if args[0] == "--cmplt" # Shell completion argument name inspired by vault # Form of args: --cmplt <index-of-current-argument> ./project.rb arg arg arg index = args[1].to_i word = args[2 + index] puts @@commands.select{ |x| x[:invocation].start_with?(word) } .map{ |x| x[:invocation]}.join("\n") exit 0 end command = args.first handler = @@commands.select{ |x| x[:invocation] == command }.first if handler.nil? self.new.error "#{command} command not found." exit 1 end fn = handler[:fn] args = args if fn.is_a?(Symbol) fn = method(fn) else args = args.drop(1) end if fn.arity == 0 fn.call() else fn.call(*args) end end |
.load_scripts(scripts_dir) ⇒ void
This method returns an undefined value.
Loads all ‘.rb` scripts from the given directory. Scripts are expected to register commands as a side-effect of loading.
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/pmgmt.rb', line 23 def self.load_scripts(scripts_dir) if !File.directory?(scripts_dir) self.new.error "Cannot load scripts. Not a directory: #{scripts_dir}" exit 1 end Dir.foreach(scripts_dir) do |item| if item =~ /[.]rb$/ require "#{scripts_dir}/#{item}" end end end |
.OptionsParser ⇒ Object
15 16 17 |
# File 'lib/pmgmt.rb', line 15 def self.OptionsParser end |
.register_command(command) ⇒ void
This method returns an undefined value.
Registers a command. Registered commands can be invoked by name, appear in command lists and allow –help docs.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/pmgmt.rb', line 39 def self.register_command(command) if command.nil? self.new.error "register_command called with nil argument" exit 1 end if command.is_a?(Symbol) invocation = command.to_s fn = command else invocation = command[:invocation] fn = command[:fn] end if fn.nil? self.new.error "No :fn key defined for command #{invocation}" exit 1 end if fn.is_a?(Symbol) unless Object.private_method_defined?(fn) self.new.error "Function #{fn.to_s} is not defined for #{invocation}." exit 1 end else # TODO(dmohs): Deprecation warning. unless fn.is_a?(Proc) self.new.error ":fn key for #{invocation} does not define a Proc or Symbol" exit 1 end end @@commands.push({:invocation => invocation, :fn => fn}) end |
Instance Method Details
#blue_term_text(text) ⇒ Object
150 151 152 |
# File 'lib/pmgmt.rb', line 150 def blue_term_text(text) "\033[0;36m#{text}\033[0m" end |
#bold_term_text(text) ⇒ Object
158 159 160 |
# File 'lib/pmgmt.rb', line 158 def bold_term_text(text) "\033[1m#{text}\033[0m" end |
#capture_stdout(cmd, err: STDERR) ⇒ String
Runs the given command and captures its stdout.
197 198 199 200 201 202 203 |
# File 'lib/pmgmt.rb', line 197 def capture_stdout(cmd, err: STDERR) if err.nil? err = "/dev/null" end output, _ = Open3.capture2(*cmd, :err => err) output end |
#error(text) ⇒ void
This method returns an undefined value.
Prints “error” text (red) on STDERR.
176 177 178 |
# File 'lib/pmgmt.rb', line 176 def error(text) STDERR.puts red_term_text(text) end |
#load_env ⇒ Object
138 139 140 141 142 143 144 |
# File 'lib/pmgmt.rb', line 138 def load_env() if not File.exists?("project.yaml") error "Missing project.yaml" exit 1 end OpenStruct.new YAML.load(File.read("project.yaml")) end |
#pipe(*cmds) ⇒ Object
Accepts multiple arrays of commands and pipes each one to the next, failing if any command exits with an error.
262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/pmgmt.rb', line 262 def pipe(*cmds) s = cmds.map { |x| x.join(" ") } s = s.join(" | ") STDERR.puts "+ #{s}" Open3.pipeline(*cmds).each do |status| unless status.success? error "Piped command failed" exit 1 end end end |
#print_usage ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/pmgmt.rb', line 124 def print_usage() STDERR.puts "\nUsage: #{$PROGRAM_NAME} <command> <options>\n\n" if !@@commands.empty? STDERR.puts "COMMANDS\n\n" @@commands.each do |command| STDERR.puts bold_term_text(command[:invocation]) STDERR.puts command[:description] || "[No description provided.]" STDERR.puts end else STDERR.puts " >> No commands defined.\n\n" end end |
#put_command(cmd, redact: nil) ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/pmgmt.rb', line 180 def put_command(cmd, redact: nil) if cmd.is_a?(String) command_string = "+ #{cmd}" else command_string = "+ #{cmd.join(" ")}" end command_to_echo = command_string.clone if redact command_to_echo.sub! redact, "*" * redact.length end STDERR.puts command_to_echo end |
#red_term_text(text) ⇒ Object
146 147 148 |
# File 'lib/pmgmt.rb', line 146 def red_term_text(text) "\033[0;31m#{text}\033[0m" end |
#run(cmd) ⇒ Status
Runs a command without echoing.
253 254 255 256 257 258 |
# File 'lib/pmgmt.rb', line 253 def run(cmd) Open3.popen3(*cmd) do |i, o, e, t| i.close t.value end end |
#run_inline(cmd, redact: nil) ⇒ void
This method returns an undefined value.
Runs the given command “inline,” meaning that it will take over the terminal while running.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/pmgmt.rb', line 209 def run_inline(cmd, redact: nil) put_command(cmd, redact: redact) # `system`, by design (?!), hides stderr when the command fails. if ENV["PROJECTRB_USE_SYSTEM"] == "true" if not system(*cmd) exit $?.exitstatus end else pid = spawn(*cmd) Process.wait pid if $?.exited? if !$?.success? exit $?.exitstatus end else error "Command exited abnormally." exit 1 end end end |
#run_inline_swallowing_interrupt(cmd) ⇒ Object
Similar to #run_inline but will prevent exiting when an interrupt is encountered.
232 233 234 235 236 237 |
# File 'lib/pmgmt.rb', line 232 def run_inline_swallowing_interrupt(cmd) begin run_inline cmd rescue Interrupt end end |
#run_or_fail(cmd, redact: nil) ⇒ Object
Runs a command and fails on non-success exit code.
240 241 242 243 244 245 246 247 248 249 |
# File 'lib/pmgmt.rb', line 240 def run_or_fail(cmd, redact: nil) put_command(cmd, redact: redact) Open3.popen3(*cmd) do |i, o, e, t| i.close if not t.value.success? STDERR.write red_term_text(e.read) exit t.value.exitstatus end end end |
#status(text) ⇒ void
This method returns an undefined value.
Prints “status” text (blue) on STDERR.
164 165 166 |
# File 'lib/pmgmt.rb', line 164 def status(text) STDERR.puts blue_term_text(text) end |
#warning(text) ⇒ void
This method returns an undefined value.
Prints “warning” text (yellow) on STDERR.
170 171 172 |
# File 'lib/pmgmt.rb', line 170 def warning(text) STDERR.puts yellow_term_text(text) end |
#yellow_term_text(text) ⇒ Object
154 155 156 |
# File 'lib/pmgmt.rb', line 154 def yellow_term_text(text) "\033[0;33m#{text}\033[0m" end |