Include default options in option parser

Adds method to shared helpers for adding procs to be evaluated
which can add default modifications to the option parser used
by commands. Customized option parser class within Vagrant
handles processing defined procs to set options.
This commit is contained in:
Chris Roberts 2020-03-27 09:58:33 -07:00
parent 8c11489ea7
commit b8702ac889
6 changed files with 112 additions and 10 deletions

View File

@ -99,6 +99,17 @@ begin
$VERBOSE = nil
end
# Add any option flags defined within this file here
# so they are automatically propagated to all commands
Vagrant.add_default_cli_options(proc { |o|
o.on("--[no-]color", "Enable or disable color output")
o.on("--machine-readable", "Enable machine readable output")
o.on("-v", "--version", "Display Vagrant version")
o.on("--debug", "Enable debug output")
o.on("--timestamp", "Enable timestamps on log output")
o.on("--debug-timestamp", "Enable debug output with timestamps")
})
# Create a logger right away
logger = Log4r::Logger.new("vagrant::bin::vagrant")
logger.info("`vagrant` invoked: #{ARGV.inspect}")

View File

@ -9,6 +9,31 @@ class Log4r::BasicFormatter
end
end
require "optparse"
module Vagrant
# This is a customized OptionParser for Vagrant plugins. It
# will automatically add any default CLI options defined
# outside of command implementations to the local option
# parser instances in use
class OptionParser < ::OptionParser
def initialize(*_)
super
Vagrant.default_cli_options.each do |opt_proc|
opt_proc.call(self)
end
end
end
end
# Inject the option parser into the vagrant plugins
# module so it is automatically used when defining
# command options
module VagrantPlugins
OptionParser = Vagrant::OptionParser
end
require "vagrant/shared_helpers"
require "rubygems"
require "vagrant/util"

View File

@ -51,7 +51,7 @@ module Vagrant
argv = @argv.dup
# Default opts to a blank optionparser if none is given
opts ||= OptionParser.new
opts ||= Vagrant::OptionParser.new
# Add the help option, which must be on every command.
opts.on_tail("-h", "--help", "Print this help") do

View File

@ -186,4 +186,32 @@ module Vagrant
end
@_global_logger
end
# Add a new block of default CLI options which
# should be automatically added to all commands
#
# @param [Proc] block Proc instance containing OptParser configuration
# @return [nil]
def self.add_default_cli_options(block)
if !block.is_a?(Proc)
raise TypeError,
"Expecting type `Proc` but received `#{block.class}`"
end
if block.arity != 1 && block.arity != -1
raise ArgumentError,
"Proc must accept OptionParser argument"
end
@_default_cli_options = [] if !@_default_cli_options
@_default_cli_options << block
nil
end
# Array of default CLI options to automatically
# add to commands.
#
# @return [Array<Proc>] Default optparse options
def self.default_cli_options
@_default_cli_options = [] if !@_default_cli_options
@_default_cli_options.dup
end
end

View File

@ -93,6 +93,22 @@ describe "vagrant bin" do
end
end
context "default CLI flags" do
let(:argv) { ["--help"] }
before do
allow(env).to receive(:ui).and_return(ui)
allow(ARGV).to receive(:dup).and_return(argv)
allow(Kernel).to receive(:at_exit)
allow(Kernel).to receive(:exit)
allow(Vagrant::Environment).to receive(:new).and_call_original
end
it "should include default CLI flags in command help output" do
expect($stdout).to receive(:puts).with(/--debug/)
end
end
context "when not in installer" do
let(:warning) { "INSTALLER WARNING" }

View File

@ -8,14 +8,14 @@ describe Vagrant do
subject { described_class }
describe "#global_lock" do
describe ".global_lock" do
it "yields to the block" do
result = subject.global_lock { 42 }
expect(result).to eq(42)
end
end
describe "#in_installer?" do
describe ".in_installer?" do
it "is not if env is not set" do
with_temp_env("VAGRANT_INSTALLER_ENV" => nil) do
expect(subject.in_installer?).to be(false)
@ -29,7 +29,7 @@ describe Vagrant do
end
end
describe "#installer_embedded_dir" do
describe ".installer_embedded_dir" do
it "returns nil if not in an installer" do
allow(Vagrant).to receive(:in_installer?).and_return(false)
expect(subject.installer_embedded_dir).to be_nil
@ -44,7 +44,7 @@ describe Vagrant do
end
end
describe "#plugins_enabled?" do
describe ".plugins_enabled?" do
it "returns true if the env is not set" do
with_temp_env("VAGRANT_NO_PLUGINS" => nil) do
expect(subject.plugins_enabled?).to be(true)
@ -58,7 +58,7 @@ describe Vagrant do
end
end
describe "#server_url" do
describe ".server_url" do
it "defaults to the default value" do
with_temp_env("VAGRANT_SERVER_URL" => nil) do
expect(subject.server_url).to eq(
@ -92,7 +92,7 @@ describe Vagrant do
end
end
describe "#user_data_path" do
describe ".user_data_path" do
around do |example|
env = {
"USERPROFILE" => nil,
@ -132,7 +132,7 @@ describe Vagrant do
end
end
describe "#prerelease?" do
describe ".prerelease?" do
it "should return true when Vagrant version is development" do
stub_const("Vagrant::VERSION", "1.0.0.dev")
expect(subject.prerelease?).to be(true)
@ -144,7 +144,7 @@ describe Vagrant do
end
end
describe "#enable_resolv_replace" do
describe ".enable_resolv_replace" do
it "should not attempt to require resolv-replace by default" do
expect(subject).not_to receive(:require).with("resolv-replace")
subject.enable_resolv_replace
@ -163,7 +163,7 @@ describe Vagrant do
end
end
describe "#global_logger" do
describe ".global_logger" do
after{ subject.global_logger = nil }
it "should return a logger when none have been provided" do
@ -176,4 +176,26 @@ describe Vagrant do
expect(subject.global_logger).to eq(logger)
end
end
describe ".add_default_cli_options" do
it "should raise a type error when no provided with proc" do
expect { subject.add_default_cli_options(true) }.
to raise_error(TypeError)
end
it "should raise an argument error when proc does not accept argument" do
expect { subject.add_default_cli_options(proc{}) }.
to raise_error(ArgumentError)
end
it "should accept a proc type argument" do
expect(subject.add_default_cli_options(proc{|o|})).to be_nil
end
end
describe ".default_cli_options" do
it "should return array of items" do
expect(subject.default_cli_options).to be_a(Array)
end
end
end