Merge pull request #2807 from mitchellh/f-non-primary-commands
Non-primary subcommands This enables plugins to define commands that are "non-primary": they won't be listed in the `vagrant -h` output, and are therefore somewhat hidden. The utility in this is that uncommon commands or commands that aren't friendly to beginners can be hidden. The full list of commands can be seen by executing `vagrant list-commands`. As of this PR, no command uses this functionality (except `list-commands`). In the future, I'm going to introduce some non-primary commands for specialized tasks such as forcing a re-rsync.
This commit is contained in:
commit
a241c9ac59
|
@ -23,15 +23,17 @@ module Vagrant
|
||||||
|
|
||||||
# If we reached this far then we must have a subcommand. If not,
|
# If we reached this far then we must have a subcommand. If not,
|
||||||
# then we also just print the help and exit.
|
# then we also just print the help and exit.
|
||||||
command_class = nil
|
command_plugin = nil
|
||||||
if @sub_command
|
if @sub_command
|
||||||
command_class = Vagrant.plugin("2").manager.commands[@sub_command.to_sym]
|
command_plugin = Vagrant.plugin("2").manager.commands[@sub_command.to_sym]
|
||||||
end
|
end
|
||||||
|
|
||||||
if !command_class || !@sub_command
|
if !command_plugin || !@sub_command
|
||||||
help
|
help
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
command_class = command_plugin[0].call
|
||||||
@logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
|
@logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
|
||||||
|
|
||||||
# Initialize and execute the command class, returning the exit status.
|
# Initialize and execute the command class, returning the exit status.
|
||||||
|
@ -51,14 +53,19 @@ module Vagrant
|
||||||
o.on("-v", "--version", "Print the version and exit.")
|
o.on("-v", "--version", "Print the version and exit.")
|
||||||
o.on("-h", "--help", "Print this help.")
|
o.on("-h", "--help", "Print this help.")
|
||||||
o.separator ""
|
o.separator ""
|
||||||
o.separator "Available subcommands:"
|
o.separator "Common subcommands:"
|
||||||
|
|
||||||
# Add the available subcommands as separators in order to print them
|
# Add the available subcommands as separators in order to print them
|
||||||
# out as well.
|
# out as well.
|
||||||
commands = {}
|
commands = {}
|
||||||
longest = 0
|
longest = 0
|
||||||
Vagrant.plugin("2").manager.commands.each do |key, klass|
|
Vagrant.plugin("2").manager.commands.each do |key, data|
|
||||||
|
# Skip non-primary commands. These only show up in extended
|
||||||
|
# help output.
|
||||||
|
next if !data[1][:primary]
|
||||||
|
|
||||||
key = key.to_s
|
key = key.to_s
|
||||||
|
klass = data[0].call
|
||||||
commands[key] = klass.synopsis
|
commands[key] = klass.synopsis
|
||||||
longest = key.length if key.length > longest
|
longest = key.length if key.length > longest
|
||||||
end
|
end
|
||||||
|
@ -70,6 +77,10 @@ module Vagrant
|
||||||
|
|
||||||
o.separator ""
|
o.separator ""
|
||||||
o.separator "For help on any individual command run `vagrant COMMAND -h`"
|
o.separator "For help on any individual command run `vagrant COMMAND -h`"
|
||||||
|
o.separator ""
|
||||||
|
o.separator "Additional subcommands are available, but are either more advanced"
|
||||||
|
o.separator "or not commonly used. To see all subcommands, run the command"
|
||||||
|
o.separator "`vagrant list-commands`."
|
||||||
end
|
end
|
||||||
|
|
||||||
@env.ui.info(opts.help, :prefix => false)
|
@env.ui.info(opts.help, :prefix => false)
|
||||||
|
|
|
@ -11,6 +11,13 @@ module Vagrant
|
||||||
# @return [Hash<Symbol, Array>]
|
# @return [Hash<Symbol, Array>]
|
||||||
attr_reader :action_hooks
|
attr_reader :action_hooks
|
||||||
|
|
||||||
|
# This contains all the command plugins by name, and returns
|
||||||
|
# the command class and options. The command class is wrapped
|
||||||
|
# in a Proc so that it can be lazy loaded.
|
||||||
|
#
|
||||||
|
# @return [Registry<Symbol, Array<Proc, Hash>>]
|
||||||
|
attr_reader :commands
|
||||||
|
|
||||||
# This contains all the configuration plugins by scope.
|
# This contains all the configuration plugins by scope.
|
||||||
#
|
#
|
||||||
# @return [Hash<Symbol, Registry>]
|
# @return [Hash<Symbol, Registry>]
|
||||||
|
@ -51,6 +58,7 @@ module Vagrant
|
||||||
# The action hooks hash defaults to []
|
# The action hooks hash defaults to []
|
||||||
@action_hooks = Hash.new { |h, k| h[k] = [] }
|
@action_hooks = Hash.new { |h, k| h[k] = [] }
|
||||||
|
|
||||||
|
@commands = Registry.new
|
||||||
@configs = Hash.new { |h, k| h[k] = Registry.new }
|
@configs = Hash.new { |h, k| h[k] = Registry.new }
|
||||||
@guests = Registry.new
|
@guests = Registry.new
|
||||||
@guest_capabilities = Hash.new { |h, k| h[k] = Registry.new }
|
@guest_capabilities = Hash.new { |h, k| h[k] = Registry.new }
|
||||||
|
|
|
@ -30,11 +30,11 @@ module Vagrant
|
||||||
|
|
||||||
# This returns all the registered commands.
|
# This returns all the registered commands.
|
||||||
#
|
#
|
||||||
# @return [Hash]
|
# @return [Registry<Symbol, Array<Proc, Hash>>]
|
||||||
def commands
|
def commands
|
||||||
Registry.new.tap do |result|
|
Registry.new.tap do |result|
|
||||||
@registered.each do |plugin|
|
@registered.each do |plugin|
|
||||||
result.merge!(plugin.command)
|
result.merge!(plugin.components.commands)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -81,21 +81,21 @@ module Vagrant
|
||||||
# "vagrant foo" becomes available.
|
# "vagrant foo" becomes available.
|
||||||
#
|
#
|
||||||
# @param [String] name Subcommand key.
|
# @param [String] name Subcommand key.
|
||||||
def self.command(name=UNSET_VALUE, &block)
|
def self.command(name, **opts, &block)
|
||||||
data[:command] ||= Registry.new
|
|
||||||
|
|
||||||
if name != UNSET_VALUE
|
|
||||||
# Validate the name of the command
|
# Validate the name of the command
|
||||||
if name.to_s !~ /^[-a-z0-9]+$/i
|
if name.to_s !~ /^[-a-z0-9]+$/i
|
||||||
raise InvalidCommandName, "Commands can only contain letters, numbers, and hyphens"
|
raise InvalidCommandName, "Commands can only contain letters, numbers, and hyphens"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register a new command class only if a name was given.
|
# By default, the command is primary
|
||||||
data[:command].register(name.to_sym, &block)
|
opts[:primary] = true if !opts.has_key?(:primary)
|
||||||
|
|
||||||
|
# Register the command
|
||||||
|
components.commands.register(name.to_sym) do
|
||||||
|
[block, opts]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return the registry
|
nil
|
||||||
data[:command]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines additional communicators to be available. Communicators
|
# Defines additional communicators to be available. Communicators
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
require "optparse"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommandListCommands
|
||||||
|
class Command < Vagrant.plugin("2", :command)
|
||||||
|
def self.synopsis
|
||||||
|
"outputs all available Vagrant subcommands, even non-primary ones"
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute
|
||||||
|
opts = OptionParser.new do |o|
|
||||||
|
o.banner = "Usage: vagrant list-commands"
|
||||||
|
end
|
||||||
|
|
||||||
|
argv = parse_options(opts)
|
||||||
|
return if !argv
|
||||||
|
|
||||||
|
# Add the available subcommands as separators in order to print them
|
||||||
|
# out as well.
|
||||||
|
commands = {}
|
||||||
|
longest = 0
|
||||||
|
Vagrant.plugin("2").manager.commands.each do |key, data|
|
||||||
|
key = key.to_s
|
||||||
|
klass = data[0].call
|
||||||
|
commands[key] = klass.synopsis
|
||||||
|
longest = key.length if key.length > longest
|
||||||
|
end
|
||||||
|
|
||||||
|
command_output = []
|
||||||
|
commands.keys.sort.each do |key|
|
||||||
|
command_output << "#{key.ljust(longest+2)} #{commands[key]}"
|
||||||
|
@env.ui.machine("cli-command", key.dup)
|
||||||
|
end
|
||||||
|
|
||||||
|
@env.ui.info(
|
||||||
|
I18n.t("vagrant.list_commands", list: command_output.join("\n")))
|
||||||
|
|
||||||
|
# Success, exit status 0
|
||||||
|
0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,18 @@
|
||||||
|
require "vagrant"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommandListCommands
|
||||||
|
class Plugin < Vagrant.plugin("2")
|
||||||
|
name "list-commands command"
|
||||||
|
description <<-DESC
|
||||||
|
The `list-commands` command will list all commands that Vagrant
|
||||||
|
understands, even hidden ones.
|
||||||
|
DESC
|
||||||
|
|
||||||
|
command("list-commands", primary: false) do
|
||||||
|
require_relative "command"
|
||||||
|
Command
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -61,6 +61,11 @@ en:
|
||||||
Key inserted! Disconnecting and reconnecting using new SSH key...
|
Key inserted! Disconnecting and reconnecting using new SSH key...
|
||||||
inserting_insecure_key: |-
|
inserting_insecure_key: |-
|
||||||
Inserting Vagrant public key within guest...
|
Inserting Vagrant public key within guest...
|
||||||
|
list_commands: |-
|
||||||
|
Below is a listing of all available Vagrant commands and a brief
|
||||||
|
description of what they do.
|
||||||
|
|
||||||
|
%{list}
|
||||||
plugin_needs_reinstall: |-
|
plugin_needs_reinstall: |-
|
||||||
The following plugins were installed with a version of Vagrant
|
The following plugins were installed with a version of Vagrant
|
||||||
that had different versions of underlying components. Because
|
that had different versions of underlying components. Because
|
||||||
|
|
|
@ -15,6 +15,7 @@ require "unit/support/dummy_provider"
|
||||||
require "unit/support/shared/base_context"
|
require "unit/support/shared/base_context"
|
||||||
require "unit/support/shared/action_synced_folders_context"
|
require "unit/support/shared/action_synced_folders_context"
|
||||||
require "unit/support/shared/capability_helpers_context"
|
require "unit/support/shared/capability_helpers_context"
|
||||||
|
require "unit/support/shared/plugin_command_context"
|
||||||
require "unit/support/shared/virtualbox_context"
|
require "unit/support/shared/virtualbox_context"
|
||||||
|
|
||||||
# Do not buffer output
|
# Do not buffer output
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
require File.expand_path("../../../../base", __FILE__)
|
||||||
|
|
||||||
|
require Vagrant.source_root.join("plugins/commands/list-commands/command")
|
||||||
|
|
||||||
|
describe VagrantPlugins::CommandListCommands::Command do
|
||||||
|
include_context "unit"
|
||||||
|
include_context "command plugin helpers"
|
||||||
|
|
||||||
|
let(:iso_env) do
|
||||||
|
# We have to create a Vagrantfile so there is a root path
|
||||||
|
env = isolated_environment
|
||||||
|
env.vagrantfile("")
|
||||||
|
env.create_vagrant_env
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:argv) { [] }
|
||||||
|
let(:commands) { {} }
|
||||||
|
|
||||||
|
subject { described_class.new(argv, iso_env) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Vagrant.plugin("2").manager.stub(commands: commands)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "execute" do
|
||||||
|
it "includes all subcommands" do
|
||||||
|
commands[:foo] = [command_lambda("foo", 0), { primary: true }]
|
||||||
|
commands[:bar] = [command_lambda("bar", 0), { primary: true }]
|
||||||
|
commands[:baz] = [command_lambda("baz", 0), { primary: false }]
|
||||||
|
|
||||||
|
iso_env.ui.should_receive(:info).with do |message, opts|
|
||||||
|
expect(message).to include("foo")
|
||||||
|
expect(message).to include("bar")
|
||||||
|
expect(message).to include("baz")
|
||||||
|
end
|
||||||
|
|
||||||
|
subject.execute
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,14 +1,23 @@
|
||||||
require File.expand_path("../../../../base", __FILE__)
|
require File.expand_path("../../../../base", __FILE__)
|
||||||
|
|
||||||
describe "VagrantPlugins::CommandSSHConfig::Command" do
|
require Vagrant.source_root.join("plugins/commands/ssh_config/command")
|
||||||
|
|
||||||
|
describe VagrantPlugins::CommandSSHConfig::Command do
|
||||||
include_context "unit"
|
include_context "unit"
|
||||||
include_context "virtualbox"
|
include_context "virtualbox"
|
||||||
|
|
||||||
let(:described_class) { Vagrant.plugin("2").manager.commands[:"ssh-config"] }
|
let(:iso_env) do
|
||||||
|
# We have to create a Vagrantfile so there is a root path
|
||||||
|
env = isolated_environment
|
||||||
|
env.vagrantfile("")
|
||||||
|
env.create_vagrant_env
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:guest) { double("guest") }
|
||||||
|
let(:host) { double("host") }
|
||||||
|
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
|
||||||
|
|
||||||
let(:argv) { [] }
|
let(:argv) { [] }
|
||||||
let(:env) { Vagrant::Environment.new }
|
|
||||||
let(:machine) { double("Vagrant::Machine", :name => nil) }
|
|
||||||
let(:ssh_info) {{
|
let(:ssh_info) {{
|
||||||
:host => "testhost.vagrant.dev",
|
:host => "testhost.vagrant.dev",
|
||||||
:port => 1234,
|
:port => 1234,
|
||||||
|
@ -18,17 +27,17 @@ describe "VagrantPlugins::CommandSSHConfig::Command" do
|
||||||
:forward_x11 => false
|
:forward_x11 => false
|
||||||
}}
|
}}
|
||||||
|
|
||||||
subject { described_class.new(argv, env) }
|
subject { described_class.new(argv, iso_env) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
machine.stub(ssh_info: ssh_info)
|
||||||
subject.stub(:with_target_vms) { |&block| block.call machine }
|
subject.stub(:with_target_vms) { |&block| block.call machine }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "execute" do
|
describe "execute" do
|
||||||
it "prints out the ssh config for the given machine" do
|
it "prints out the ssh config for the given machine" do
|
||||||
machine.stub(:ssh_info) { ssh_info }
|
|
||||||
subject.should_receive(:safe_puts).with(<<-SSHCONFIG)
|
subject.should_receive(:safe_puts).with(<<-SSHCONFIG)
|
||||||
Host vagrant
|
Host #{machine.name}
|
||||||
HostName testhost.vagrant.dev
|
HostName testhost.vagrant.dev
|
||||||
User testuser
|
User testuser
|
||||||
Port 1234
|
Port 1234
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
shared_context "command plugin helpers" do
|
||||||
|
def command_lambda(name, result)
|
||||||
|
lambda do
|
||||||
|
Class.new(Vagrant.plugin("2", "command")) do
|
||||||
|
define_method(:execute) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,29 +1,50 @@
|
||||||
|
require_relative "../base"
|
||||||
|
|
||||||
|
require "vagrant/cli"
|
||||||
|
|
||||||
describe Vagrant::CLI do
|
describe Vagrant::CLI do
|
||||||
describe "parsing options" do
|
include_context "unit"
|
||||||
let(:klass) do
|
include_context "command plugin helpers"
|
||||||
Class.new(described_class)
|
|
||||||
|
let(:commands) { {} }
|
||||||
|
let(:iso_env) { isolated_environment }
|
||||||
|
let(:env) { iso_env.create_vagrant_env }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Vagrant.plugin("2").manager.stub(commands: commands)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:environment) do
|
describe "#execute" do
|
||||||
ui = double("UI::Silent")
|
it "invokes help and exits with 1 if invalid command" do
|
||||||
ui.stub(:machine => "bar")
|
subject = described_class.new(["i-dont-exist"], env)
|
||||||
ui.stub(:info => "bar")
|
subject.should_receive(:help).once
|
||||||
env = double("Vagrant::Environment")
|
expect(subject.execute).to eql(1)
|
||||||
env.stub(:active_machines => [])
|
|
||||||
env.stub(:ui => ui)
|
|
||||||
env.stub(:root_path => "foo")
|
|
||||||
env.stub(:machine_names => [])
|
|
||||||
env
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a non-zero exit status if an invalid command is given" do
|
it "invokes command and returns its exit status if the command is valid" do
|
||||||
result = klass.new(["destroypp"], environment).execute
|
commands[:destroy] = [command_lambda("destroy", 42), {}]
|
||||||
result.should_not == 0
|
|
||||||
|
subject = described_class.new(["destroy"], env)
|
||||||
|
subject.should_not_receive(:help)
|
||||||
|
expect(subject.execute).to eql(42)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns an exit status of zero if a valid command is given" do
|
describe "#help" do
|
||||||
result = klass.new(["destroy"], environment).execute
|
subject { described_class.new([], env) }
|
||||||
result.should == 0
|
|
||||||
|
it "includes all primary subcommands" do
|
||||||
|
commands[:foo] = [command_lambda("foo", 0), { primary: true }]
|
||||||
|
commands[:bar] = [command_lambda("bar", 0), { primary: true }]
|
||||||
|
commands[:baz] = [command_lambda("baz", 0), { primary: false }]
|
||||||
|
|
||||||
|
env.ui.should_receive(:info).with do |message, opts|
|
||||||
|
expect(message).to include("foo")
|
||||||
|
expect(message).to include("bar")
|
||||||
|
expect(message.include?("baz")).to be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
subject.help
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -53,7 +53,28 @@ describe Vagrant::Plugin::V2::Plugin do
|
||||||
command("foo") { "bar" }
|
command("foo") { "bar" }
|
||||||
end
|
end
|
||||||
|
|
||||||
plugin.command[:foo].should == "bar"
|
expect(plugin.components.commands.keys).to be_include(:foo)
|
||||||
|
expect(plugin.components.commands[:foo][0].call).to eql("bar")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should register command classes with options" do
|
||||||
|
plugin = Class.new(described_class) do
|
||||||
|
command("foo", opt: :bar) { "bar" }
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(plugin.components.commands.keys).to be_include(:foo)
|
||||||
|
expect(plugin.components.commands[:foo][0].call).to eql("bar")
|
||||||
|
expect(plugin.components.commands[:foo][1][:opt]).to eql(:bar)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should register commands as primary by default" do
|
||||||
|
plugin = Class.new(described_class) do
|
||||||
|
command("foo") { "bar" }
|
||||||
|
command("bar", primary: false) { "bar" }
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(plugin.components.commands[:foo][1][:primary]).to be_true
|
||||||
|
expect(plugin.components.commands[:bar][1][:primary]).to be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
["spaces bad", "sym^bols"].each do |bad|
|
["spaces bad", "sym^bols"].each do |bad|
|
||||||
|
@ -79,8 +100,8 @@ describe Vagrant::Plugin::V2::Plugin do
|
||||||
# Now verify when we actually get the command key that
|
# Now verify when we actually get the command key that
|
||||||
# a proper error is raised.
|
# a proper error is raised.
|
||||||
expect {
|
expect {
|
||||||
plugin.command[:foo]
|
plugin.components.commands[:foo][0].call
|
||||||
}.to raise_error(StandardError)
|
}.to raise_error(StandardError, "FAIL!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,7 @@
|
||||||
<li<%= sidebar_current("cli-status") %>><a href="/v2/cli/status.html">status</a></li>
|
<li<%= sidebar_current("cli-status") %>><a href="/v2/cli/status.html">status</a></li>
|
||||||
<li<%= sidebar_current("cli-suspend") %>><a href="/v2/cli/suspend.html">suspend</a></li>
|
<li<%= sidebar_current("cli-suspend") %>><a href="/v2/cli/suspend.html">suspend</a></li>
|
||||||
<li<%= sidebar_current("cli-up") %>><a href="/v2/cli/up.html">up</a></li>
|
<li<%= sidebar_current("cli-up") %>><a href="/v2/cli/up.html">up</a></li>
|
||||||
|
<li<%= sidebar_current("cli-nonprimary") %>><a href="/v2/cli/non-primary.html">More Commands</a></li>
|
||||||
<li<%= sidebar_current("cli-machinereadable") %>><a href="/v2/cli/machine-readable.html">Machine Readable Output</a></li>
|
<li<%= sidebar_current("cli-machinereadable") %>><a href="/v2/cli/machine-readable.html">Machine Readable Output</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
page_title: "More Vagrant Commands - Command-Line Interface"
|
||||||
|
sidebar_current: "cli-nonprimary"
|
||||||
|
---
|
||||||
|
|
||||||
|
# More Commands
|
||||||
|
|
||||||
|
In addition to the commands listed in the sidebar and shown in `vagrant -h`,
|
||||||
|
Vagrant comes with some more commands that are hidden from basic help output.
|
||||||
|
These commands are hidden because they're not useful to beginners or they're
|
||||||
|
not commonly used. We call these commands "non-primary subcommands".
|
||||||
|
|
||||||
|
You can view all subcommands, including the non-primary subcommands,
|
||||||
|
by running `vagrant list-commands`, which itself is a non-primary subcommand!
|
||||||
|
|
||||||
|
Note that while you have to run a special command to list the non-primary
|
||||||
|
subcommands, you don't have to do anything special to actually _run_ the
|
||||||
|
non-primary subcommands. They're executed just like any other subcommand:
|
||||||
|
`vagrant COMMAND`.
|
|
@ -32,7 +32,23 @@ end
|
||||||
Commands are defined with the `command` method, which takes as an argument
|
Commands are defined with the `command` method, which takes as an argument
|
||||||
the name of the command, in this case "foo." This means the command will be
|
the name of the command, in this case "foo." This means the command will be
|
||||||
invokable via `vagrant foo`. Then the block argument returns a class that
|
invokable via `vagrant foo`. Then the block argument returns a class that
|
||||||
implements the `Vagrant.plugin(2, :command)` interface.
|
implements the `Vagrant.plugin(2, "command")` interface.
|
||||||
|
|
||||||
|
You can also define _non-primary commands_. These commands do not show
|
||||||
|
up in the `vagrant -h` output. They only show up if the user explicitly
|
||||||
|
does a `vagrant list-commands` which shows the full listing of available
|
||||||
|
commands. This is useful for highly specific commands or plugins that a
|
||||||
|
beginner to Vagrant would not be using anyways. Vagrant itself uses non-primary
|
||||||
|
commands to expose some internal functions, as well.
|
||||||
|
|
||||||
|
To define a non-primary command:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
command("foo", primary: false) do
|
||||||
|
require_relative "command"
|
||||||
|
Command
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue