Skip to content
Browse files

YARD and some documentation

  • Loading branch information...
1 parent 85bbb5d commit c8d7e6601ddd1b4c62bdbb3fa1804561d2ef0049 @mitchellh committed Sep 22, 2010
Showing with 146 additions and 13 deletions.
  1. +1 −0 .yardopts
  2. +4 −1 Gemfile
  3. +3 −1 Gemfile.lock
  4. +9 −5 lib/vagrant/box.rb
  5. +24 −1 lib/vagrant/cli.rb
  6. +45 −2 lib/vagrant/command/base.rb
  7. +60 −3 lib/vagrant/config.rb
View
1 .yardopts
@@ -0,0 +1 @@
+-m markdown
View
5 Gemfile
@@ -12,7 +12,10 @@ group :test do
gem "rake"
gem "contest", ">= 0.1.2"
gem "mocha"
- gem "yard"
+
+ # For documentation
+ gem "yard", "~> 0.6.1"
+ gem "bluecloth"
platforms :mri_18 do
gem "ruby-debug"
View
4 Gemfile.lock
@@ -24,6 +24,7 @@ GEM
specs:
abstract (1.0.0)
archive-tar-minitar (0.5.2)
+ bluecloth (2.0.7)
columnize (0.3.1)
contest (0.1.2)
erubis (2.6.6)
@@ -64,11 +65,12 @@ PLATFORMS
ruby
DEPENDENCIES
+ bluecloth
contest (>= 0.1.2)
mocha
rake
ruby-debug
ruby-debug19
vagrant!
virtualbox!
- yard
+ yard (~> 0.6.1)
View
14 lib/vagrant/box.rb
@@ -4,7 +4,7 @@ module Vagrant
# virtual machine, at the least. They are created with `vagrant package`
# and may contain additional files if specified by the creator. This
# class serves to help manage these boxes, although most of the logic
- # is kicked out to actions.
+ # is kicked out to middlewares.
class Box
# The name of the box.
attr_accessor :name
@@ -46,19 +46,21 @@ def initialize(env=nil, name=nil)
# virtual machine file which contains specifications of the exported
# virtual machine this box contains.
#
+ # This will only be valid once the box is imported.
+ #
# @return [String]
def ovf_file
directory.join(env.config.vm.box_ovf)
end
# 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
- # is kicked out to the {Actions::Box::Add add box} action.
+ # is kicked out to the `box_add` registered middleware.
def add
env.actions.run(:box_add, { "box" => self })
end
- # Begins the process of destroying this box.
+ # Begins the process of destroying this box. This cannot be undone!
def destroy
env.actions.run(:box_remove, { "box" => self })
end
@@ -69,14 +71,16 @@ def repackage(options=nil)
end
# 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]
def directory
env.boxes_path.join(name)
end
- # Implemented for comparison with other boxes.
+ # Implemented for comparison with other boxes. Comparison is implemented
+ # by simply comparing name.
def <=>(other)
return super if !other.is_a?(self.class)
name <=> other.name
View
25 lib/vagrant/cli.rb
@@ -4,9 +4,32 @@ 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.
+ #
+ # # 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
# 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)
opts ||= {}
View
47 lib/vagrant/command/base.rb
@@ -3,7 +3,7 @@
module Vagrant
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
# `vagrant box add`. For commands which have more subcommands, use
# a {GroupBase}.
@@ -15,7 +15,50 @@ module Command
# 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.
+ # 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
include Thor::Actions
include Helpers
View
63 lib/vagrant/config.rb
@@ -2,8 +2,27 @@
require 'vagrant/config/error_recorder'
module Vagrant
- # The config class is responsible for loading Vagrant configurations
- # (usually through Vagrantfiles).
+ # The config class is responsible for loading Vagrant configurations, which
+ # 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
extend Util::StackedProcRunner
@@ -12,6 +31,12 @@ class Config
attr_reader :queue
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)
@@config = nil
proc_stack.clear
@@ -20,14 +45,29 @@ def reset!(env=nil)
config(env)
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)
@@config ||= Config::Top.new(env)
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)
push_proc(&block)
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)
config_object ||= config
@@ -37,6 +77,10 @@ def execute!(config_object=nil)
end
end
+ # Initialize a {Config} object for the given {Environment}.
+ #
+ # @param [Environment] env Environment which config object will be part
+ # of.
def initialize(env)
@env = env
@queue = []
@@ -65,14 +109,24 @@ def load!
end
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
@@configures = []
class << self
+ # The list of registered configuration classes as well as the key
+ # they're registered under.
def configures_list
@@configures ||= []
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)
configures_list << [key, klass]
attr_reader key.to_sym
@@ -90,7 +144,10 @@ def initialize(env=nil)
end
# 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!
# Validate each of the configured classes and store the results into
# a hash.

0 comments on commit c8d7e66

Please sign in to comment.
Something went wrong with that request. Please try again.