-
-
Save anonymous/1bc5bf908b41d2c47072b5114391a330 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'optparse' | |
require 'ostruct' | |
# The purpose of the program is to confirm if the user actually wanted to | |
# execute a program. | |
# | |
# Example: | |
# $ confirm poweroff | |
# confirm: are you sure you want to run poweroff? [Y/n] | |
class String | |
def black; "\033[30m#{self}\033[0m" end | |
def red; "\033[31m#{self}\033[0m" end | |
def green; "\033[32m#{self}\033[0m" end | |
def brown; "\033[33m#{self}\033[0m" end | |
def blue; "\033[34m#{self}\033[0m" end | |
def magenta; "\033[35m#{self}\033[0m" end | |
def cyan; "\033[36m#{self}\033[0m" end | |
def gray; "\033[37m#{self}\033[0m" end | |
end | |
# Splits ARGV into the options meant for confirm (like -n) and the command were | |
# supposed to be executing. | |
def split_argv argv | |
arguments = Struct.new(:options, :command).new([], []) | |
ignore_options = false | |
for argument in argv do | |
if argument == "--" | |
ignore_options = true | |
elsif !ignore_options && argument[0] == "-" | |
arguments.options.push argument | |
else | |
ignore_options = true | |
arguments.command.push argument | |
end | |
end | |
return arguments | |
end | |
# Ask the user if it really want to run `command` | |
def verify? command, default = :yes | |
hint = default == :yes ? "[Y/n]" : "[y/N]" | |
print "confirm: are you sure you want to run #{command.green}? #{hint} " | |
begin | |
answer = STDIN.gets.strip | |
rescue Interrupt | |
puts | |
exit 127 | |
end | |
if answer == '' | |
if default == :yes | |
return true | |
else | |
return false | |
end | |
elsif answer.downcase == 'y' || answer.downcase == 'yes' | |
return true | |
elsif answer.downcase == 'n' || answer.downcase == 'no' | |
return false | |
else | |
puts "please answer with 'y' or 'n'" | |
return verify? command, default | |
end | |
end | |
settings = Struct.new(:default).new(:yes) | |
optionParser = OptionParser.new do |opts| | |
opts.banner = "Usage: confirm [options] command" | |
opts.on "-n", "--no", "set the default to no instead of yes" do | |
settings.default = :no | |
end | |
opts.on "-v", "--version" do | |
puts "confirm 0.0.1" | |
puts | |
puts "Written by [REDACTED]" | |
exit | |
end | |
end | |
# Split the arguments | |
arguments = split_argv ARGV | |
begin | |
# Parse the options that are meant for our program | |
optionParser.parse(arguments.options) | |
rescue OptionParser::InvalidOption => e | |
puts "confirm: #{e.to_s}" | |
puts "Try 'confirm --help' for more information." | |
exit 127 | |
end | |
if arguments.command.any? | |
# Ask the user if he really want to run the specified command | |
if verify?(arguments.command.join(" "), settings.default) | |
begin | |
# Execute the specified command | |
exec *arguments.command | |
rescue Errno::ENOENT | |
puts "confirm: command not found: #{arguments.command[0]}" | |
exit 127 | |
end | |
else | |
exit 127 | |
end | |
else | |
# We weren't given an command to execute, just print out the help text. | |
puts optionParser.help | |
exit 127 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment