Init command. Tests for the base command.
This commit is contained in:
parent
2691b0493c
commit
48b7596357
|
@ -3,6 +3,15 @@ require 'virtualbox'
|
|||
require "vagrant/util/glob_loader"
|
||||
|
||||
module Vagrant
|
||||
# TODO: Move more classes over to the autoload model. We'll
|
||||
# start small, but slowly move everything over.
|
||||
|
||||
autoload :CLI, 'vagrant/cli'
|
||||
|
||||
module Command
|
||||
autoload :Base, 'vagrant/command/base'
|
||||
end
|
||||
|
||||
class << self
|
||||
attr_writer :ui
|
||||
|
||||
|
@ -31,7 +40,7 @@ end
|
|||
# Load them up. One day we'll convert this to autoloads. Today
|
||||
# is not that day. Low hanging fruit for anyone wishing to do it.
|
||||
libdir = File.expand_path("lib/vagrant", Vagrant.source_root)
|
||||
Vagrant::GlobLoader.glob_require(libdir, %w{util util/stacked_proc_runner cli
|
||||
Vagrant::GlobLoader.glob_require(libdir, %w{util util/stacked_proc_runner
|
||||
downloaders/base config provisioners/base provisioners/chef systems/base
|
||||
action/exception_catcher hosts/base})
|
||||
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
require 'thor'
|
||||
|
||||
module Vagrant
|
||||
# Entrypoint for the Vagrant CLI. This class should never be
|
||||
# initialized directly (like a typical Thor class). Instead,
|
||||
# use {Environment#cli} to invoke the CLI.
|
||||
class CLI < Thor
|
||||
attr_reader :env
|
||||
|
||||
def initialize(args=[], options={}, config={})
|
||||
super
|
||||
|
||||
# Set the UI to a shell based UI using the shell object which
|
||||
# Thor sets up.
|
||||
Vagrant.ui = UI::Shell.new(shell) if !Vagrant.ui.is_a?(UI::Shell)
|
||||
|
||||
# The last argument must _always_ be a Vagrant Environment class.
|
||||
raise CLIMissingEnvironment.new("This command requires that a Vagrant environment be properly passed in as the last parameter.") if !config[:env]
|
||||
@env = config[:env]
|
||||
# Registers the given class with the CLI so it can be accessed.
|
||||
# The class must be a subclass of either {Command} or {GroupCommand}.
|
||||
def self.register(klass, name, usage, description)
|
||||
if klass <= Thor # TODO: make Command::GroupBase
|
||||
# A subclass of Thor is a subcommand, since it contains
|
||||
# many smaller commands within it.
|
||||
desc usage, description
|
||||
subcommand name, klass
|
||||
elsif klass <= Command::Base
|
||||
# A subclass of Thor::Group is a single command, since it
|
||||
# is invoked as a whole.
|
||||
desc usage, description
|
||||
define_method(name) { |*args| invoke klass, args }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
require 'thor/group'
|
||||
require 'thor/actions'
|
||||
|
||||
module Vagrant
|
||||
module Command
|
||||
# A CLI command is the subclass for all commands which are single
|
||||
# commands, e.g. `vagrant init`, `vagrant up`. Not commands like
|
||||
# `vagrant box add`. For commands which have more subcommands, use
|
||||
# a {GroupBase}.
|
||||
#
|
||||
# A {Base} is a subclass of `Thor::Group`, so view the documentation
|
||||
# there on how to add arguments, descriptions etc. The important note
|
||||
# about this is that when invoked, _all public methods_ will be called
|
||||
# in the order they are defined. If you don't want a method called when
|
||||
# the command is invoked, it must be made `protected` or `private`.
|
||||
#
|
||||
# The best way to get examples of how to create your own command is to
|
||||
# view the various Vagrant commands, which are relatively simple.
|
||||
class Base < Thor::Group
|
||||
include Thor::Actions
|
||||
|
||||
# Register the command with the main Vagrant CLI under the
|
||||
# given name. The name will be used for accessing it from the CLI,
|
||||
# so if you name it "lamp", then the command to invoke this
|
||||
# will be `vagrant lamp`.
|
||||
#
|
||||
# The description added to the class via the `desc` method will be
|
||||
# used as a description for the command.
|
||||
def self.register(usage)
|
||||
# Extracts the name out of the usage string. So `init [foo] [bar]`
|
||||
# becomes "init"
|
||||
_, name = /^([a-zA-Z0-9]+)(\s+(.+?))?$/.match(usage).to_a
|
||||
CLI.register(self, name, usage, desc)
|
||||
end
|
||||
|
||||
def initialize(args=[], options={}, config={})
|
||||
super
|
||||
|
||||
# Set the UI to a shell based UI using the shell object which
|
||||
# Thor sets up.
|
||||
Vagrant.ui = UI::Shell.new(shell) if !Vagrant.ui.is_a?(UI::Shell)
|
||||
|
||||
# The last argument must _always_ be a Vagrant Environment class.
|
||||
raise CLIMissingEnvironment.new("This command requires that a Vagrant environment be properly passed in as the last parameter.") if !config[:env]
|
||||
@env = config[:env]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
module Vagrant
|
||||
module Command
|
||||
class InitCommand < Base
|
||||
desc "Initializes the current folder for Vagrant usage"
|
||||
argument :box_name, :type => :string, :optional => true, :default => "base"
|
||||
argument :box_url, :type => :string, :optional => true
|
||||
source_root File.expand_path("templates/commands/init", Vagrant.source_root)
|
||||
register "init [box_name] [box_url]"
|
||||
|
||||
def execute
|
||||
template "Vagrantfile.erb", "Vagrantfile"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
Vagrant::Config.run do |config|
|
||||
# All Vagrant configuration is done here. For a detailed explanation
|
||||
# and listing of configuration options, please view the documentation
|
||||
# online.
|
||||
|
||||
# Every Vagrant virtual environment requires a box to build off of.
|
||||
config.vm.box = "<%= box_name %>"
|
||||
<% if !box_url.nil? %>
|
||||
|
||||
# The url from where the 'config.vm.box' box will be fetched if it
|
||||
# doesn't already exist on the user's system
|
||||
config.vm.box_url = "<%= box_url %>"<% end %>
|
||||
end
|
|
@ -3,40 +3,14 @@ require "test_helper"
|
|||
class CLITest < Test::Unit::TestCase
|
||||
setup do
|
||||
@klass = Vagrant::CLI
|
||||
@env = mock_environment
|
||||
end
|
||||
|
||||
context "setting up a UI" do
|
||||
setup do
|
||||
Vagrant.ui = nil
|
||||
end
|
||||
|
||||
should "setup a shell UI" do
|
||||
silence_stream(STDOUT) { @klass.start([], :env => @env) }
|
||||
assert Vagrant.ui.is_a?(Vagrant::UI::Shell)
|
||||
end
|
||||
|
||||
should "setup a shell UI only once" do
|
||||
silence_stream(STDOUT) { @klass.start([], :env => @env) }
|
||||
ui = Vagrant.ui
|
||||
silence_stream(STDOUT) { @klass.start([], :env => @env) }
|
||||
assert Vagrant.ui.equal?(ui)
|
||||
end
|
||||
end
|
||||
|
||||
context "requiring an environment" do
|
||||
should "raise an exception if the environment is not sent in" do
|
||||
assert_raises(Vagrant::CLIMissingEnvironment) {
|
||||
@klass.start([])
|
||||
}
|
||||
end
|
||||
|
||||
should "not raise an exception if the environment is properly sent in" do
|
||||
silence_stream(STDOUT) do
|
||||
assert_nothing_raised {
|
||||
@klass.start([], :env => @env)
|
||||
}
|
||||
end
|
||||
context "registering" do
|
||||
should "register a base command as a single invokable" do
|
||||
base = Class.new(Vagrant::Command::Base)
|
||||
name = "__test_registering_single_subcommand"
|
||||
@klass.register(base, name, name, "A description")
|
||||
assert @klass.tasks[name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
require "test_helper"
|
||||
|
||||
class CommandBaseTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@klass = Vagrant::Command::Base
|
||||
@env = mock_environment
|
||||
end
|
||||
|
||||
context "setting up a UI" do
|
||||
setup do
|
||||
Vagrant.ui = nil
|
||||
end
|
||||
|
||||
should "setup a shell UI" do
|
||||
silence_stream(STDOUT) { @klass.start([], :env => @env) }
|
||||
assert Vagrant.ui.is_a?(Vagrant::UI::Shell)
|
||||
end
|
||||
|
||||
should "setup a shell UI only once" do
|
||||
silence_stream(STDOUT) { @klass.start([], :env => @env) }
|
||||
ui = Vagrant.ui
|
||||
silence_stream(STDOUT) { @klass.start([], :env => @env) }
|
||||
assert Vagrant.ui.equal?(ui)
|
||||
end
|
||||
end
|
||||
|
||||
context "requiring an environment" do
|
||||
should "raise an exception if the environment is not sent in" do
|
||||
assert_raises(Vagrant::CLIMissingEnvironment) {
|
||||
@klass.start([])
|
||||
}
|
||||
end
|
||||
|
||||
should "not raise an exception if the environment is properly sent in" do
|
||||
silence_stream(STDOUT) do
|
||||
assert_nothing_raised {
|
||||
@klass.start([], :env => @env)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue