From b4d1ee6e83aa7b4de1365e72a614b36dc254f083 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 13 Apr 2010 15:34:26 -0700 Subject: [PATCH] Commands specify their option parsings in the `options_spec` method. Parent takes care of the rest. --- lib/vagrant/commands/base.rb | 36 ++++++++++++++------ lib/vagrant/commands/init.rb | 8 ++--- test/vagrant/commands/base_test.rb | 54 ++++++++++++++++-------------- 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/lib/vagrant/commands/base.rb b/lib/vagrant/commands/base.rb index 350123fb9..ed4779987 100644 --- a/lib/vagrant/commands/base.rb +++ b/lib/vagrant/commands/base.rb @@ -84,17 +84,31 @@ module Vagrant self.class.puts_help end - # Parse options out of the command-line. This method uses `optparse` - # to parse command line options. A block is required and will yield - # the `OptionParser` object along with a hash which can be used to - # store options and which will be returned as a result of the function. - def parse_options(args) - options = {} - @parser = OptionParser.new do |opts| - yield opts, options - end + # This method is called by the base class to get the `optparse` configuration + # for the command. + def options_spec(opts) + opts.banner = "Usage: vagrant SUBCOMMAND" + end - @parser.parse!(args) + # Returns the `OptionParser` instance to be used with this subcommand, + # based on the specs defined in {#options_spec}. + def option_parser(reload=false) + @option_parser = nil if reload + @option_parser ||= OptionParser.new do |opts| + options_spec(opts) + end + end + + # The options for the given command. This will just be an empty hash + # until {#parse_options} is called. + def options + @options ||= {} + end + + # Parse options out of the command-line. This method uses `optparse` + # to parse command line options. + def parse_options(args) + option_parser.parse!(args) options rescue OptionParser::InvalidOption show_help @@ -114,7 +128,7 @@ module Vagrant puts "Description: #{description}" end - puts @parser.help + puts option_parser.help exit end end diff --git a/lib/vagrant/commands/init.rb b/lib/vagrant/commands/init.rb index f64716801..c5cdd81cb 100644 --- a/lib/vagrant/commands/init.rb +++ b/lib/vagrant/commands/init.rb @@ -5,13 +5,13 @@ module Vagrant description "Initializes current folder for Vagrant usage" def execute(args) - parse_options(args) do |opts, options| - opts.banner = "Usage: vagrant init [name]" - end - create_vagrantfile(args[0]) end + def options_spec(opts) + opts.banner = "Usage: vagrant init [name]" + end + # Actually writes the initial Vagrantfile to the current working directory. # The Vagrantfile will contain the base box configuration specified, or # will just use "base" if none is specified. diff --git a/test/vagrant/commands/base_test.rb b/test/vagrant/commands/base_test.rb index c129b3896..5f0cba117 100644 --- a/test/vagrant/commands/base_test.rb +++ b/test/vagrant/commands/base_test.rb @@ -71,36 +71,40 @@ class CommandsBaseTest < Test::Unit::TestCase end end + context "getting the option parser" do + should "create it with the options spec if it hasn't been created yet" do + opts = mock("opts") + result = mock("result") + OptionParser.expects(:new).yields(opts).returns(result) + @instance.expects(:options_spec).with(opts) + + assert_equal result, @instance.option_parser(true) + end + + should "not create it once its been created" do + result = mock("result") + OptionParser.expects(:new).once.returns(result) + + assert_equal result, @instance.option_parser(true) + assert_equal result, @instance.option_parser + assert_equal result, @instance.option_parser + end + end + context "parsing options" do setup do @args = [] + + @options = mock("options") + @option_parser = mock("option_parser") + + @instance.stubs(:option_parser).returns(@option_parser) + @instance.stubs(:options).returns(@options) end - should "return the options hash" do - value = mock("foo") - result = @instance.parse_options(@args) do |opts, options| - options[:foo] = value - end - - assert_equal value, result[:foo] - end - - should "parse with the given args" do - parser = mock("parser") - - OptionParser.stubs(:new).returns(parser) - parser.expects(:parse!).with(@args) - @instance.parse_options(@args) do; end - end - - should "show help if an invalid options error is raised" do - parser = mock("parser") - - OptionParser.stubs(:new).returns(parser) - parser.expects(:parse!).raises(OptionParser::InvalidOption) - @instance.expects(:show_help).once - - @instance.parse_options(@args) do; end + should "parse the options with the args" do + @option_parser.expects(:parse!).with(@args).once + assert_equal @options, @instance.parse_options(@args) end end end