diff --git a/plugins/commands/cap/command.rb b/plugins/commands/cap/command.rb new file mode 100644 index 000000000..43a80cfb5 --- /dev/null +++ b/plugins/commands/cap/command.rb @@ -0,0 +1,75 @@ +require 'optparse' + +module VagrantPlugins + module CommandCap + class Command < Vagrant.plugin("2", :command) + def self.synopsis + "checks and executes capability" + end + + def execute + options = {} + options[:check] = false + + opts = OptionParser.new do |o| + o.banner = "Usage: vagrant cap [options] TYPE NAME [args]" + o.separator "" + o.separator "This is an advanced command. If you don't know what this" + o.separator "does and you aren't explicitly trying to use it, you probably" + o.separator "don't want to use this." + o.separator "" + o.separator "This command checks or executes arbitrary capabilities that" + o.separator "Vagrant has for hosts, guests, and providers." + o.separator "" + o.separator "Options:" + o.separator "" + + o.on("--check", "Only checks for a capability, does not execute") do |f| + options[:check] = f + end + end + + # Parse the options + argv = parse_options(opts) + return if !argv + if argv.length < 2 + raise Vagrant::Errors::CLIInvalidUsage, + help: opts.help.chomp + end + + type = argv.shift.to_sym + name = argv.shift.to_sym + + # Get the proper capability host to check + cap_host = nil + if type == :host + cap_host = @env.host + else + with_target_vms([]) do |vm| + cap_host = case type + when :provider + vm.provider + when :guest + vm.guest + else + raise Vagrant::Errors::CLIInvalidUsage, + help: opts.help.chomp + end + end + end + + # If we're just checking, then just return exit codes + if options[:check] + return 0 if cap_host.capability?(name) + return 1 + end + + # Otherwise, call it + cap_host.capability(name, *argv) + + # Success, exit status 0 + 0 + end + end + end +end diff --git a/plugins/commands/cap/plugin.rb b/plugins/commands/cap/plugin.rb new file mode 100644 index 000000000..21199c9a9 --- /dev/null +++ b/plugins/commands/cap/plugin.rb @@ -0,0 +1,17 @@ +require "vagrant" + +module VagrantPlugins + module CommandCap + class Plugin < Vagrant.plugin("2") + name "cap command" + description <<-DESC + The `cap` command checks and executes arbitrary capabilities. + DESC + + command("cap", primary: false) do + require_relative "command" + Command + end + end + end +end diff --git a/test/unit/plugins/commands/cap/command_test.rb b/test/unit/plugins/commands/cap/command_test.rb new file mode 100644 index 000000000..9e3394fec --- /dev/null +++ b/test/unit/plugins/commands/cap/command_test.rb @@ -0,0 +1,51 @@ +require File.expand_path("../../../../base", __FILE__) + +require Vagrant.source_root.join("plugins/commands/cap/command") + +describe VagrantPlugins::CommandCap::Command do + include_context "unit" + + 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) { [] } + + subject { described_class.new(argv, iso_env) } + + before do + allow(subject).to receive(:with_target_vms) { |&block| block.call machine } + end + + describe "execute" do + context "--check provider foo (exists)" do + let(:argv) { ["--check", "provider", "foo"] } + let(:cap) { Class.new } + + before do + register_plugin do |p| + p.provider_capability(:dummy, :foo) { cap } + end + end + + it "exits with 0 if it exists" do + expect(subject.execute).to eq(0) + end + end + + context "--check provider foo (doesn't exists)" do + let(:argv) { ["--check", "provider", "foo"] } + + it "exits with 1" do + expect(subject.execute).to eq(1) + end + end + end +end