bin/restfully in restfully-0.8.8 vs bin/restfully in restfully-1.0.0.rc1
- old
+ new
@@ -3,122 +3,172 @@
require 'restfully'
require 'optparse'
require 'logger'
require 'pp'
+require 'ripl'
+require 'ripl/multi_line'
# Behaviour of pp in IRB is different on ruby1.9:
# * pp(object) returns object#inspect.
# * we prefer the behaviour of ruby1.8 where pp returns nil.
-alias :old_pp :pp
+alias :old_pp :pp
def pp(*args)
old_pp(*args); nil
end
logger = Logger.new(STDERR)
logger.level = Logger::WARN
-@options = {"logger" => logger}
+OPTIONS = {"logger" => logger, "shell" => false}
+
+Ripl.config[:play_quiet] = true
+Ripl.config[:play_input] = false
+
option_parser = OptionParser.new do |opts|
opts.banner = <<BANNER
* Description
Restfully #{Restfully::VERSION} - Access REST APIs effortlessly
* Usage
- restfully [uri] [options]
-* Options
+ restfully [options] [FILE]
+
+ If FILE is given and is an HTTP URI or a local file, the content of that file will be executed in the context of the Restfully session. It can also be read from STDIN.
+ If no FILE is given, then an interactive shell will be launched in the context of the Restfully session.
BANNER
- opts.on("-u=", "--username=", "Sets the username") do |u|
- @options["username"] = u
+ opts.separator ""
+ opts.separator "* Common options"
+ opts.on("--uri=", "Sets the base URI") do |v|
+ OPTIONS["uri"] = v
end
- opts.on("-p=", "--password=", "Sets the user password") do |p|
- @options["password"] = p
+ opts.on("-u=", "--username=", "Sets the username (Basic Authentication)") do |u|
+ OPTIONS["username"] = u
end
- opts.on("-c=", "--config=", "Sets the various options based on a custom YAML configuration file") do |v|
- @options["configuration_file"] = v
+ opts.on("-p=", "--password=", "Sets the password (Basic Authentication)") do |p|
+ OPTIONS["password"] = p
end
+ opts.on("-c=", "--config=", "Load options from a custom YAML configuration file") do |v|
+ OPTIONS["configuration_file"] = v
+ end
opts.on("-r=", "--require=", "Require an additional media-type") do |v|
- @options["require"] ||= []
- @options["require"].push(v)
+ OPTIONS["require"] ||= []
+ OPTIONS["require"].push(v)
end
- opts.on("--log=", "Outputs log messages to the given file. Defaults to stdout") do |v|
+ opts.on("--log=", "Outputs log messages to the given file. Defaults to STDERR") do |v|
original_logger_level = logger.level
- logger = Logger.new(File.expand_path(v))
+ @log_file = File.open(File.expand_path(v), "w+")
+ STDERR.sync = true
+ STDERR.reopen(@log_file)
+ logger = Logger.new(@log_file)
logger.level = original_logger_level
- @options["logger"] = logger
+ OPTIONS["logger"] = logger
end
opts.on("--no-cache", "Disable client-side caching") do |v|
- @options["cache"] = false
+ OPTIONS["cache"] = false
end
+ opts.on("--color", "Color output") do |v|
+ require 'ripl/color_streams'
+ require 'ripl/color_result'
+ end
+ opts.on("--record [SESSION_FILE]", "Record interactive session into SESSION_FILE (default=#{Restfully::DEFAULT_TAPE}), to be replayed later. This option is ignored if FILE is given.") do |v|
+ OPTIONS["record"] = v || Restfully::DEFAULT_TAPE
+ end
opts.on("-v", "--verbose", "Run verbosely") do |v|
- @options["logger"].level = Logger::INFO
+ OPTIONS["logger"].level = Logger::INFO
end
opts.on("--debug", "Run in debug mode") do |v|
- @options["logger"].level = Logger::DEBUG
+ OPTIONS["logger"].level = Logger::DEBUG
end
+
+ opts.separator ""
+ opts.separator "* Options specific to FILE"
+ opts.on("--replay", "Display the FILE input line by line, and the result of each command") do |v|
+ Ripl.config[:play_input] = true
+ Ripl.config[:play_quiet] = false
+ end
+ opts.on("--shell", "Start an interactive session even after FILE content has been executed") do |v|
+ OPTIONS["shell"] = true
+ end
+ opts.on("-i", "--install", "Ask to install any gem that might be required in FILE") do |v|
+ Ripl.config[:play_install] = true
+ end
+
+ opts.separator ""
+ opts.separator "* Other"
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
-
-end
+ opts.on_tail("--version", "Show version") do
+ puts Restfully::VERSION
+ exit
+ end
+end.parse!
-option_parser.parse!
+# Declare original Restfully::Session
+@session = Restfully::Session.new(OPTIONS)
-if given_uri = ARGV.shift
- @options["uri"] = given_uri
-end
+if $stdin.tty? && !ARGV[0]
+ # Interactive session
+ puts "Restfully/#{Restfully::VERSION} - The root resource is available in the 'root' variable."
+ if OPTIONS["record"]
+ # Recording requested
+ require 'ripl/record'
+ Ripl.config[:play] = OPTIONS["record"]
+ end
+else
+ # Replayed session
+ @session.logger.warn "--record option valid only with interactive session. Ignoring." if OPTIONS["record"]
+ require 'ripl/play'
-@session = Restfully::Session.new(@options)
-
-def session; @session; end
-
-def root
- @root ||= session.root
+ module Ripl::Play
+ # Overwrite #get_input so that it does not display the input if not
+ # required.
+ def get_input
+ puts(prompt + @play_input) if Ripl.config[:play_input]
+ @play_input
+ end
+ end
+
+ module Ripl::PlayWithoutWhitespace
+ # Remove empty lines when replaying
+ def play_back_string(str)
+ str.gsub!(/^\s*\n+/, '')
+ super(str)
+ end
+ end
+ Ripl::Shell.include Ripl::PlayWithoutWhitespace
+
+ unless OPTIONS["shell"]
+ # Use readline-rb to avoid error message 'Bond has detected EditLine and
+ # may not work with it. See the README's Limitations section.' when no
+ # shell is requested after execution of FILE.
+ Ripl.config[:readline] = 'readline-rb'
+ Ripl.config[:completion] = {:readline => :ruby }
+ module Ripl::Exit
+ def before_loop; super; exit; end
+ end
+ Ripl::Shell.include Ripl::Exit
+ end
+
+ Ripl.config[:play] = ARGV[0].dup if ARGV[0]
end
-puts "Restfully/#{Restfully::VERSION} - The root resource is available in the 'root' variable."
-
-require 'irb'
-require 'irb/completion'
-require 'irb/ext/save-history'
-
-HOME = ENV['HOME'] || ENV['HOMEPATH']
-# Keep history of your last commands.
-# Taken from <http://blog.nicksieger.com/articles/2006/04/23/tweaking-irb>
-IRB.conf[:SAVE_HISTORY] = 100
-IRB.conf[:HISTORY_FILE] = "#{HOME}/.irb-save-history"
-
-# Raises an error on Windows, so disabling it.
-if RUBY_PLATFORM !~ /(win|w)32$/
- module Readline
- module History
- LOG = "#{HOME}/.irb-history"
-
- def self.write_log(line)
- File.open(LOG, 'ab') {|f|
- f << "#{line}\n"
- }
- end
-
- def self.start_session_log
- write_log("\n")
- end
+module Restfully
+ class Session
+ alias :old_initialize :initialize
+ # Overwrite Restfully::Session.new calls that might occur in replayed
+ # scripts, so that they preferably take the configuration given with the
+ # restfully command-line tool.
+ def initialize(options = {}, &block)
+ old_opts = Configuration.new(options).expand
+ new_opts = Configuration.new(OPTIONS).expand
+ old_initialize(old_opts.merge(new_opts).to_hash, &block)
end
-
- alias :old_readline :readline
- def readline(*args)
- ln = old_readline(*args)
- begin
- History.write_log(ln)
- rescue
- end
- ln
- end
end
- Readline::History.start_session_log
end
+# Ensure to close the log file, if any, when exiting.
+at_exit{ @log_file && @log_file.close }
+
ARGV.clear
-ARGV.concat [ "--readline", "--prompt-mode", "simple" ]
-IRB.start
-exit!
\ No newline at end of file
+Ripl.start :binding => @session.instance_eval{ binding }