summaryrefslogtreecommitdiff
path: root/lib/un.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/un.rb')
-rw-r--r--lib/un.rb148
1 files changed, 120 insertions, 28 deletions
diff --git a/lib/un.rb b/lib/un.rb
index e06e0e759b..8fb3c61a93 100644
--- a/lib/un.rb
+++ b/lib/un.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: false
#
# = un.rb
#
@@ -21,18 +22,20 @@
# ruby -run -e touch -- [OPTION] FILE
# ruby -run -e wait_writable -- [OPTION] FILE
# ruby -run -e mkmf -- [OPTION] EXTNAME [OPTION]
-# ruby -run -e httpd -- [OPTION] DocumentRoot
+# ruby -run -e httpd -- [OPTION] [DocumentRoot]
+# ruby -run -e colorize -- [FILE]
# ruby -run -e help [COMMAND]
require "fileutils"
require "optparse"
module FileUtils
-# @fileutils_label = ""
@fileutils_output = $stdout
end
+# :nodoc:
def setup(options = "", *long_options)
+ caller = caller_locations(1, 1)[0].label
opt_hash = {}
argv = []
OptionParser.new do |o|
@@ -44,7 +47,7 @@ def setup(options = "", *long_options)
end
long_options.each do |s|
opt_name, arg_name = s.split(/(?=[\s=])/, 2)
- opt_name.sub!(/\A--/, '')
+ opt_name.delete_prefix!('--')
s = "--#{opt_name.gsub(/([A-Z]+|[a-z])([A-Z])/, '\1-\2').downcase}#{arg_name}"
puts "#{opt_name}=>#{s}" if $DEBUG
opt_name = opt_name.intern
@@ -53,6 +56,10 @@ def setup(options = "", *long_options)
end
end
o.on("-v") do opt_hash[:verbose] = true end
+ o.on("--help") do
+ UN.help([caller])
+ exit
+ end
o.order!(ARGV) do |x|
if /[*?\[{]/ =~ x
argv.concat(Dir[x])
@@ -71,17 +78,19 @@ end
#
# -p preserve file attributes if possible
# -r copy recursively
+# -l make hard link instead of copying (implies -r)
# -v verbose
#
def cp
- setup("pr") do |argv, options|
+ setup("prl") do |argv, options|
cmd = "cp"
cmd += "_r" if options.delete :r
+ cmd = "cp_lr" if options.delete :l
options[:preserve] = true if options.delete :p
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.send cmd, argv, dest, options
+ FileUtils.__send__ cmd, argv, dest, **options
end
end
@@ -102,7 +111,7 @@ def ln
options[:force] = true if options.delete :f
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.send cmd, argv, dest, options
+ FileUtils.__send__ cmd, argv, dest, **options
end
end
@@ -118,7 +127,7 @@ def mv
setup do |argv, options|
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.mv argv, dest, options
+ FileUtils.mv argv, dest, **options
end
end
@@ -137,7 +146,7 @@ def rm
cmd = "rm"
cmd += "_r" if options.delete :r
options[:force] = true if options.delete :f
- FileUtils.send cmd, argv, options
+ FileUtils.__send__ cmd, argv, **options
end
end
@@ -154,7 +163,7 @@ def mkdir
setup("p") do |argv, options|
cmd = "mkdir"
cmd += "_p" if options.delete :p
- FileUtils.send cmd, argv, options
+ FileUtils.__send__ cmd, argv, **options
end
end
@@ -170,7 +179,7 @@ end
def rmdir
setup("p") do |argv, options|
options[:parents] = true if options.delete :p
- FileUtils.rmdir argv, options
+ FileUtils.rmdir argv, **options
end
end
@@ -182,16 +191,20 @@ end
# -p apply access/modification times of SOURCE files to
# corresponding destination files
# -m set permission mode (as in chmod), instead of 0755
+# -o set owner user id, instead of the current owner
+# -g set owner group id, instead of the current group
# -v verbose
#
def install
- setup("pm:") do |argv, options|
- options[:mode] = (mode = options.delete :m) ? mode.oct : 0755
+ setup("pm:o:g:") do |argv, options|
+ (mode = options.delete :m) and options[:mode] = /\A\d/ =~ mode ? mode.oct : mode
options[:preserve] = true if options.delete :p
+ (owner = options.delete :o) and options[:owner] = owner
+ (group = options.delete :g) and options[:group] = group
dest = argv.pop
argv = argv[0] if argv.size == 1
- FileUtils.install argv, dest, options
+ FileUtils.install argv, dest, **options
end
end
@@ -205,8 +218,9 @@ end
def chmod
setup do |argv, options|
- mode = argv.shift.oct
- FileUtils.chmod mode, argv, options
+ mode = argv.shift
+ mode = /\A\d/ =~ mode ? mode.oct : mode
+ FileUtils.chmod mode, argv, **options
end
end
@@ -220,7 +234,7 @@ end
def touch
setup do |argv, options|
- FileUtils.touch argv, options
+ FileUtils.touch argv, **options
end
end
@@ -241,13 +255,15 @@ def wait_writable
wait = (wait = options[:w]) ? Float(wait) : 0.2
argv.each do |file|
begin
- open(file, "r+b")
+ File.open(file, "r+b") {}
rescue Errno::ENOENT
break
rescue Errno::EACCES => e
raise if n and (n -= 1) <= 0
- puts e
- STDOUT.flush
+ if verbose
+ puts e
+ STDOUT.flush
+ end
sleep wait
retry
end
@@ -290,7 +306,7 @@ end
##
# Run WEBrick HTTP server.
#
-# ruby -run -e httpd -- [OPTION] DocumentRoot
+# ruby -run -e httpd -- [OPTION] [DocumentRoot]
#
# --bind-address=ADDR address to bind
# --port=NUM listening port number
@@ -299,22 +315,54 @@ end
# --do-not-reverse-lookup disable reverse lookup
# --request-timeout=SECOND request timeout in seconds
# --http-version=VERSION HTTP version
+# --server-name=NAME name of the server host
+# --server-software=NAME name and version of the server
+# --ssl-certificate=CERT The SSL certificate file for the server
+# --ssl-private-key=KEY The SSL private key file for the server certificate
# -v verbose
#
def httpd
setup("", "BindAddress=ADDR", "Port=PORT", "MaxClients=NUM", "TempDir=DIR",
- "DoNotReverseLookup", "RequestTimeout=SECOND", "HTTPVersion=VERSION") do
+ "DoNotReverseLookup", "RequestTimeout=SECOND", "HTTPVersion=VERSION",
+ "ServerName=NAME", "ServerSoftware=NAME",
+ "SSLCertificate=CERT", "SSLPrivateKey=KEY") do
|argv, options|
- require 'webrick'
+ begin
+ require 'webrick'
+ rescue LoadError
+ abort "webrick is not found. You may need to `gem install webrick` to install webrick."
+ end
opt = options[:RequestTimeout] and options[:RequestTimeout] = opt.to_i
[:Port, :MaxClients].each do |name|
opt = options[name] and (options[name] = Integer(opt)) rescue nil
end
- unless argv.size == 1
- raise ArgumentError, "DocumentRoot is mandatory"
+ if cert = options[:SSLCertificate]
+ key = options[:SSLPrivateKey] or
+ raise "--ssl-private-key option must also be given"
+ require 'webrick/https'
+ options[:SSLEnable] = true
+ options[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read(cert))
+ options[:SSLPrivateKey] = OpenSSL::PKey.read(File.read(key))
+ options[:Port] ||= 8443 # HTTPS Alternate
end
- options[:DocumentRoot] = argv.shift
+ options[:Port] ||= 8080 # HTTP Alternate
+ options[:DocumentRoot] = argv.shift || '.'
+ s = nil
+ options[:StartCallback] = proc {
+ logger = s.logger
+ logger.info("To access this server, open this URL in a browser:")
+ s.listeners.each do |listener|
+ if options[:SSLEnable]
+ addr = listener.addr
+ addr[3] = "127.0.0.1" if addr[3] == "0.0.0.0"
+ addr[3] = "::1" if addr[3] == "::"
+ logger.info(" https://#{Addrinfo.new(addr).inspect_sockaddr}")
+ else
+ logger.info(" http://#{listener.connect_address.inspect_sockaddr}")
+ end
+ end
+ }
s = WEBrick::HTTPServer.new(options)
shut = proc {s.shutdown}
siglist = %w"TERM QUIT"
@@ -328,6 +376,29 @@ def httpd
end
##
+# Colorize ruby code.
+#
+# ruby -run -e colorize -- [FILE]
+#
+
+def colorize
+ begin
+ require "irb/color"
+ rescue LoadError
+ raise "colorize requires irb 1.1.0 or later"
+ end
+ setup do |argv, |
+ if argv.empty?
+ puts IRB::Color.colorize_code STDIN.read
+ return
+ end
+ argv.each do |file|
+ puts IRB::Color.colorize_code File.read(file)
+ end
+ end
+end
+
+##
# Display help message.
#
# ruby -run -e help [COMMAND]
@@ -335,15 +406,36 @@ end
def help
setup do |argv,|
+ UN.help(argv)
+ end
+end
+
+module UN # :nodoc:
+
+ VERSION = "0.3.0"
+
+ module_function
+ def help(argv, output: $stdout)
all = argv.empty?
- open(__FILE__) do |me|
+ cmd = nil
+ if all
+ store = proc {|msg| output << msg}
+ else
+ messages = {}
+ store = proc {|msg| messages[cmd] = msg}
+ end
+ File.open(__FILE__) do |me|
while me.gets("##\n")
if help = me.gets("\n\n")
- if all or argv.delete help[/-e \w+/].sub(/-e /, "")
- print help.gsub(/^# ?/, "")
+ if all or argv.include?(cmd = help[/^#\s*ruby\s.*-e\s+(\w+)/, 1])
+ store[help.gsub(/^# ?/, "")]
+ break unless all or argv.size > messages.size
end
end
end
end
+ if messages
+ argv.each {|arg| output << messages[arg]}
+ end
end
end