Add experimental flag to guard development features

This commit introduces a special flag for enabling features that are not
ready for release. It can either be enabled by setting the
`VAGRANT_EXPERIMENTAL` flag to "1", or by setting it to a string of one
or more comma seperated values for specific features. It also adds a
couple of Vagrant developer focused methods for making it easier to
determine if the flag has been enabled, and if so, what features.
This commit is contained in:
Brian Cain 2018-12-05 16:28:10 -08:00
parent b781331e88
commit 212f6ce8bb
No known key found for this signature in database
GPG Key ID: 9FC4639B2E4510A0
4 changed files with 152 additions and 0 deletions

View File

@ -159,6 +159,31 @@ begin
env.ui.warn(I18n.t("vagrant.general.not_in_installer") + "\n", prefix: false)
end
# Acceptable experimental flag values include:
#
# Unset - Disables experimental features
# 0 - Disables experimental features
# 1 - Enables all features
# String - Enables one or more features, separated by commas
if ENV["VAGRANT_EXPERIMENTAL"]
experimental = ENV["VAGRANT_EXPERIMENTAL"].to_s
if experimental == "0"
logger.debug("Experimental flag is set but disabled")
else
ui = Vagrant::UI::Prefixed.new(env.ui, "vagrant")
if experimental != "1"
logger.debug("Experimental flag is enabled")
features = experimental.split(',')
ui.warn(I18n.t("vagrant.general.experimental.features", features: features.join(", ")), bold: true, prefix: true, channel: :error)
elsif experimental == "1"
logger.debug("Experimental flag is enabled")
ui.warn(I18n.t("vagrant.general.experimental.all"), bold: true, prefix: true, channel: :error)
else
logger.warn("Experimental flag is set to an unsupported value")
end
end
end
begin
# Execute the CLI interface, and exit with the proper error code
exit_status = env.cli(argv)

View File

@ -0,0 +1,48 @@
module Vagrant
module Util
class Experimental
VALID_FEATURES = [].freeze
class << self
# A method for determining if the experimental flag has been enabled
#
# @return [Boolean]
def enabled?
if !defined?(@_experimental)
experimental = ENV["VAGRANT_EXPERIMENTAL"].to_s
if experimental != "0" && !experimental.empty?
@_experimental = true
else
@_experimental = false
end
end
@_experimental
end
# A method for Vagrant internals to determine if a given feature
# has been abled and can be used.
#
# @param [String] - An array of strings of features to check against
# @return [Boolean] - A hash containing the original array and if it is valid
def feature_enabled?(feature)
experimental = ENV["VAGRANT_EXPERIMENTAL"].to_s.downcase
if experimental == "1"
return true
elsif VALID_FEATURES.include?(feature) &&
experimental.split(',').include?(feature)
return true
else
return false
end
end
# @private
# Reset the cached values for platform. This is not considered a public
# API and should only be used for testing.
def reset!
instance_variables.each(&method(:remove_instance_variable))
end
end
end
end
end

View File

@ -393,6 +393,18 @@ en:
shown below.
%{output}
experimental:
all: |-
You have enabled the experimental flag with all features enabled.
Please use with caution, as some of the features may not be fully
functional yet.
features: |-
You have requested to enabled the experimental flag with the following features:
Features: %{features}
Please use with caution, as some of the features may not be fully
functional yet.
not_in_installer: |-
You appear to be running Vagrant outside of the official installers.
Note that the installers are what ensure that Vagrant has all required

View File

@ -0,0 +1,67 @@
require File.expand_path("../../../base", __FILE__)
require "vagrant/util/experimental"
describe Vagrant::Util::Experimental do
include_context "unit"
before(:each) { described_class.reset! }
subject { described_class }
describe "#enabled?" do
it "returns true if enabled with '1'" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("1")
expect(subject.enabled?).to eq(true)
end
it "returns true if enabled with a list of features" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("list,of,features")
expect(subject.enabled?).to eq(true)
end
it "returns false if disabled" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("0")
expect(subject.enabled?).to eq(false)
end
it "returns false if not set" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return(nil)
expect(subject.enabled?).to eq(false)
end
end
describe "#feature_enabled?" do
before(:each) do
stub_const("Vagrant::Util::Experimental::VALID_FEATURES", ["secret_feature"])
end
it "returns true if flag set to 1" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("1")
expect(subject.feature_enabled?("anything")).to eq(true)
end
it "returns true if flag contains feature requested" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("secret_feature")
expect(subject.feature_enabled?("secret_feature")).to eq(true)
end
it "returns true if flag contains feature requested with other features 'enabled'" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("secret_feature,other_secret")
expect(subject.feature_enabled?("secret_feature")).to eq(true)
end
it "returns false if flag does not contain feature requested" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("secret_feature")
expect(subject.feature_enabled?("anything")).to eq(false)
end
it "returns false if flag set to 0" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return("0")
expect(subject.feature_enabled?("anything")).to eq(false)
end
it "returns false if flag is not set" do
allow(ENV).to receive(:[]).with("VAGRANT_EXPERIMENTAL").and_return(nil)
expect(subject.feature_enabled?("anything")).to eq(false)
end
end
end