YARD and some documentation

This commit is contained in:
Mitchell Hashimoto 2010-09-22 09:43:30 -06:00
parent 85bbb5dd87
commit c8d7e6601d
7 changed files with 146 additions and 13 deletions

1
.yardopts Normal file
View File

@ -0,0 +1 @@
-m markdown

View File

@ -12,7 +12,10 @@ group :test do
gem "rake" gem "rake"
gem "contest", ">= 0.1.2" gem "contest", ">= 0.1.2"
gem "mocha" gem "mocha"
gem "yard"
# For documentation
gem "yard", "~> 0.6.1"
gem "bluecloth"
platforms :mri_18 do platforms :mri_18 do
gem "ruby-debug" gem "ruby-debug"

View File

@ -24,6 +24,7 @@ GEM
specs: specs:
abstract (1.0.0) abstract (1.0.0)
archive-tar-minitar (0.5.2) archive-tar-minitar (0.5.2)
bluecloth (2.0.7)
columnize (0.3.1) columnize (0.3.1)
contest (0.1.2) contest (0.1.2)
erubis (2.6.6) erubis (2.6.6)
@ -64,6 +65,7 @@ PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
bluecloth
contest (>= 0.1.2) contest (>= 0.1.2)
mocha mocha
rake rake
@ -71,4 +73,4 @@ DEPENDENCIES
ruby-debug19 ruby-debug19
vagrant! vagrant!
virtualbox! virtualbox!
yard yard (~> 0.6.1)

View File

@ -4,7 +4,7 @@ module Vagrant
# virtual machine, at the least. They are created with `vagrant package` # virtual machine, at the least. They are created with `vagrant package`
# and may contain additional files if specified by the creator. This # and may contain additional files if specified by the creator. This
# class serves to help manage these boxes, although most of the logic # class serves to help manage these boxes, although most of the logic
# is kicked out to actions. # is kicked out to middlewares.
class Box class Box
# The name of the box. # The name of the box.
attr_accessor :name attr_accessor :name
@ -46,6 +46,8 @@ module Vagrant
# virtual machine file which contains specifications of the exported # virtual machine file which contains specifications of the exported
# virtual machine this box contains. # virtual machine this box contains.
# #
# This will only be valid once the box is imported.
#
# @return [String] # @return [String]
def ovf_file def ovf_file
directory.join(env.config.vm.box_ovf) directory.join(env.config.vm.box_ovf)
@ -53,12 +55,12 @@ module Vagrant
# Begins the process of adding a box to the vagrant installation. This # Begins the process of adding a box to the vagrant installation. This
# method requires that `name` and `uri` be set. The logic of this method # method requires that `name` and `uri` be set. The logic of this method
# is kicked out to the {Actions::Box::Add add box} action. # is kicked out to the `box_add` registered middleware.
def add def add
env.actions.run(:box_add, { "box" => self }) env.actions.run(:box_add, { "box" => self })
end end
# Begins the process of destroying this box. # Begins the process of destroying this box. This cannot be undone!
def destroy def destroy
env.actions.run(:box_remove, { "box" => self }) env.actions.run(:box_remove, { "box" => self })
end end
@ -69,14 +71,16 @@ module Vagrant
end end
# Returns the directory to the location of this boxes content in the local # Returns the directory to the location of this boxes content in the local
# filesystem. # filesystem. Note that if the box isn't imported yet, then the path may not
# yet exist, but still represents where the box will be imported to.
# #
# @return [String] # @return [String]
def directory def directory
env.boxes_path.join(name) env.boxes_path.join(name)
end end
# Implemented for comparison with other boxes. # Implemented for comparison with other boxes. Comparison is implemented
# by simply comparing name.
def <=>(other) def <=>(other)
return super if !other.is_a?(self.class) return super if !other.is_a?(self.class)
name <=> other.name name <=> other.name

View File

@ -4,9 +4,32 @@ module Vagrant
# Entrypoint for the Vagrant CLI. This class should never be # Entrypoint for the Vagrant CLI. This class should never be
# initialized directly (like a typical Thor class). Instead, # initialized directly (like a typical Thor class). Instead,
# use {Environment#cli} to invoke the CLI. # use {Environment#cli} to invoke the CLI.
#
# # Defining Custom CLI Commands
#
# If you're looking to define custom CLI commands, then look at
# one of the two following classes:
#
# * {Command::Base} - Implementing a single command such as `vagrant up`, e.g.
# one without subcommands. Also take a look at {Command::NamedBase}.
# * {Command::GroupBase} - Implementing a command with subcommands, such as
# `vagrant box`, which has the `list`, `add`, etc. subcommands.
#
# The above linked classes contain the main documentation for each
# type of command.
class CLI < Thor class CLI < Thor
# Registers the given class with the CLI so it can be accessed. # Registers the given class with the CLI so it can be accessed.
# The class must be a subclass of either {Command} or {GroupCommand}. # The class must be a subclass of either {Command::Base} or {Command::GroupBase}.
# Don't call this method directly, instead call the {Command::Base.register}
# or {Command::GroupBase.register} methods.
#
# @param [Class] klass Command class
# @param [String] name Command name, accessed at `vagrant NAME`
# @param [String] usage Command usage, such as "vagrant NAME [--option]"
# @param [String] description Description of the command shown during the
# command listing.
# @param [Hash] opts Other options (not gone into detail here, look at
# the source instead).
def self.register(klass, name, usage, description, opts=nil) def self.register(klass, name, usage, description, opts=nil)
opts ||= {} opts ||= {}

View File

@ -3,7 +3,7 @@ require 'thor/actions'
module Vagrant module Vagrant
module Command module Command
# A CLI command is the subclass for all commands which are single # A {Base} is the superclass for all commands which are single
# commands, e.g. `vagrant init`, `vagrant up`. Not commands like # commands, e.g. `vagrant init`, `vagrant up`. Not commands like
# `vagrant box add`. For commands which have more subcommands, use # `vagrant box add`. For commands which have more subcommands, use
# a {GroupBase}. # a {GroupBase}.
@ -15,7 +15,50 @@ module Vagrant
# the command is invoked, it must be made `protected` or `private`. # 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 # The best way to get examples of how to create your own command is to
# view the various Vagrant commands, which are relatively simple. # view the various Vagrant commands, which are relatively simple, and
# can be found in the Vagrant source tree at `lib/vagrant/command/`.
#
# # Defining a New Command
#
# To define a new single command, create a new class which inherits
# from this class, then call {register} to register the command. That's
# it! When the command is invoked, _all public methods_ will be called.
# Below is an example `SayHello` class:
#
# class SayHello < Vagrant::Command::Base
# register "hello", "Says hello"
#
# def hello
# env.ui.info "Hello"
# end
# end
#
# In this case, the above class is invokable via `vagrant hello`. To give
# this a try, just copy and paste the above into a Vagrantfile somewhere.
# The command will be available for that project!
#
# Also note that the above example uses `env.ui` to output. It is recommended
# you use this instead of raw "puts" since it is configurable and provides
# additional functionality, such as colors and asking for user input. See
# the {UI} class for more information.
#
# ## Defining Command-line Options
#
# Most command line actions won't be as simple as `vagrant hello`, and will
# probably require parameters or switches. Luckily, Thor makes adding these
# easy:
#
# class SayHello < Vagrant::Command::Base
# register "hello", "Says hello"
# argument :name, :type => :string
#
# def hello
# env.ui.info "Hello, #{name}"
# end
# end
#
# Then, the above can be invoked with `vagrant hello Mitchell` which would
# output "Hello, Mitchell"
class Base < Thor::Group class Base < Thor::Group
include Thor::Actions include Thor::Actions
include Helpers include Helpers

View File

@ -2,8 +2,27 @@ require 'vagrant/config/base'
require 'vagrant/config/error_recorder' require 'vagrant/config/error_recorder'
module Vagrant module Vagrant
# The config class is responsible for loading Vagrant configurations # The config class is responsible for loading Vagrant configurations, which
# (usually through Vagrantfiles). # are usually found in Vagrantfiles but may also be procs. The loading is done
# by specifying a queue of files or procs that are for configuration, and then
# executing them. The config loader will run each item in the queue, so that
# configuration from later items overwrite that from earlier items. This is how
# Vagrant "scoping" of Vagranfiles is implemented.
#
# If you're looking to create your own configuration classes, see {Base}.
#
# # Loading Configuration Files
#
# If you are in fact looking to load configuration files, then this is the
# class you are looking for. Loading configuration is quite easy. The following
# example assumes `env` is already a loaded instance of {Environment}:
#
# config = Vagrant::Config.new(env)
# config.queue << "/path/to/some/Vagrantfile"
# result = config.load!
#
# p "Your box is: #{result.vm.box}"
#
class Config class Config
extend Util::StackedProcRunner extend Util::StackedProcRunner
@ -12,6 +31,12 @@ module Vagrant
attr_reader :queue attr_reader :queue
class << self class << self
# Resets the current loaded config object to the specified environment.
# This clears the proc stack and initializes a new {Top} for loading.
# This method shouldn't be called directly, instead use an instance of this
# class for config loading.
#
# @param [Environment] env
def reset!(env=nil) def reset!(env=nil)
@@config = nil @@config = nil
proc_stack.clear proc_stack.clear
@ -20,14 +45,29 @@ module Vagrant
config(env) config(env)
end end
# Returns the current {Top} configuration object. While this is still
# here for implementation purposes, it shouldn't be called directly. Instead,
# use an instance of this class.
def config(env=nil) def config(env=nil)
@@config ||= Config::Top.new(env) @@config ||= Config::Top.new(env)
end end
# Adds the given proc/block to the stack of config procs which are all
# run later on a single config object. This is the main way to configure
# Vagrant, and is how all Vagrantfiles are formatted:
#
# Vagrant::Config.run do |config|
# # ...
# end
#
def run(&block) def run(&block)
push_proc(&block) push_proc(&block)
end end
# Executes all the config procs onto the currently loaded {Top} object,
# and returns the final configured object. This also validates the
# configuration by calling {Top#validate!} on every configuration
# class.
def execute!(config_object=nil) def execute!(config_object=nil)
config_object ||= config config_object ||= config
@ -37,6 +77,10 @@ module Vagrant
end end
end end
# Initialize a {Config} object for the given {Environment}.
#
# @param [Environment] env Environment which config object will be part
# of.
def initialize(env) def initialize(env)
@env = env @env = env
@queue = [] @queue = []
@ -65,14 +109,24 @@ module Vagrant
end end
class Config class Config
# This class is the "top" configure class, which handles registering
# other configuration classes as well as validation of all configured
# classes. This is the object which is returned by {Environment#config}
# and has accessors to all other configuration classes.
#
# If you're looking to create your own configuration class, see {Base}.
class Top < Base class Top < Base
@@configures = [] @@configures = []
class << self class << self
# The list of registered configuration classes as well as the key
# they're registered under.
def configures_list def configures_list
@@configures ||= [] @@configures ||= []
end end
# Registers a configuration class with the given key. This method shouldn't
# be called. Instead, inherit from {Base} and call {Base.configures}.
def configures(key, klass) def configures(key, klass)
configures_list << [key, klass] configures_list << [key, klass]
attr_reader key.to_sym attr_reader key.to_sym
@ -90,7 +144,10 @@ module Vagrant
end end
# Validates the configuration classes of this instance and raises an # Validates the configuration classes of this instance and raises an
# exception if they are invalid. # exception if they are invalid. If you are implementing a custom configuration
# class, the method you want to implement is {Base#validate}. This is
# the method that checks all the validation, not one which defines
# validation rules.
def validate! def validate!
# Validate each of the configured classes and store the results into # Validate each of the configured classes and store the results into
# a hash. # a hash.