Merge pull request #8300 from chrisroberts/enhancement/deprecation

Command deprecation module
This commit is contained in:
Chris Roberts 2017-02-24 07:26:55 -08:00 committed by GitHub
commit f32c12d426
7 changed files with 201 additions and 24 deletions

View File

@ -292,6 +292,10 @@ module Vagrant
error_key(:clone_machine_not_found) error_key(:clone_machine_not_found)
end end
class CommandDeprecated < VagrantError
error_key(:command_deprecated)
end
class CommandUnavailable < VagrantError class CommandUnavailable < VagrantError
error_key(:command_unavailable) error_key(:command_unavailable)
end end

View File

@ -1,6 +1,7 @@
module Vagrant module Vagrant
module Util module Util
autoload :Busy, 'vagrant/util/busy' autoload :Busy, 'vagrant/util/busy'
autoload :CommandDeprecation, 'vagrant/util/command_deprecation'
autoload :Counter, 'vagrant/util/counter' autoload :Counter, 'vagrant/util/counter'
autoload :CredentialScrubber, 'vagrant/util/credential_scrubber' autoload :CredentialScrubber, 'vagrant/util/credential_scrubber'
autoload :Env, 'vagrant/util/env' autoload :Env, 'vagrant/util/env'

View File

@ -0,0 +1,56 @@
module Vagrant
module Util
# Automatically add deprecation notices to commands
module CommandDeprecation
# @return [String] generated name of command
def deprecation_command_name
name_parts = self.class.name.split("::")
[
name_parts[1].sub('Command', ''),
name_parts[3]
].compact.map(&:downcase).join(" ")
end
def self.included(klass)
klass.class_eval do
class << self
if method_defined?(:synopsis)
alias_method :non_deprecated_synopsis, :synopsis
def synopsis
if !non_deprecated_synopsis.to_s.empty?
"#{non_deprecated_synopsis} [DEPRECATED]"
else
non_deprecated_synopsis
end
end
end
end
alias_method :non_deprecated_execute, :execute
def execute
@env[:ui].warn(I18n.t("vagrant.commands.deprecated",
name: deprecation_command_name
) + "\n")
non_deprecated_execute
end
end
end
# Mark command deprecation complete and fully disable
# the command's functionality
module Complete
def self.included(klass)
klass.include(CommandDeprecation)
klass.class_eval do
def execute
raise Vagrant::Errors::CommandDeprecated,
name: deprecation_command_name
end
end
end
end
end
end
end

View File

@ -70,6 +70,8 @@ module VagrantPlugins
return name return name
end end
include Vagrant::Util::CommandDeprecation::Complete
end end
end end
end end

View File

@ -664,6 +664,9 @@ en:
Additionally, the created environment must be started with a provider Additionally, the created environment must be started with a provider
matching this provider. For example, if you're using VirtualBox, matching this provider. For example, if you're using VirtualBox,
the clone environment must also be using VirtualBox. the clone environment must also be using VirtualBox.
command_deprecated: |-
The command 'vagrant %{name}' has been deprecated and is no longer functional
within Vagrant.
command_unavailable: |- command_unavailable: |-
The executable '%{file}' Vagrant is trying to run was not The executable '%{file}' Vagrant is trying to run was not
found in the PATH variable. This is an error. Please verify found in the PATH variable. This is an error. Please verify
@ -1568,6 +1571,9 @@ en:
# Translations for commands. e.g. `vagrant x` # Translations for commands. e.g. `vagrant x`
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
commands: commands:
deprecated: |-
[DEPRECATION WARNING]: The Vagrant command 'vagrant %{name}' is scheduled be
deprecated in an upcoming Vagrant release.
common: common:
vm_already_running: |- vm_already_running: |-
VirtualBox VM is already running. VirtualBox VM is already running.

View File

@ -33,35 +33,37 @@ describe VagrantPlugins::CommandPush::Command do
allow(env).to receive(:push) allow(env).to receive(:push)
end end
it "validates the pushes" do # NOTE: Disabled due to deprecation
expect(subject).to receive(:validate_pushes!).once #
subject.execute # it "validates the pushes" do
end # expect(subject).to receive(:validate_pushes!).once
# subject.execute
# end
it "delegates to Environment#push" do # it "delegates to Environment#push" do
expect(env).to receive(:push).once # expect(env).to receive(:push).once
subject.execute # subject.execute
end # end
it "validates the configuration" do # it "validates the configuration" do
iso_env.vagrantfile <<-EOH # iso_env.vagrantfile <<-EOH
Vagrant.configure("2") do |config| # Vagrant.configure("2") do |config|
config.vm.box = "hashicorp/precise64" # config.vm.box = "hashicorp/precise64"
config.push.define "noop" do |push| # config.push.define "noop" do |push|
push.bad = "ham" # push.bad = "ham"
end # end
end # end
EOH # EOH
subject = described_class.new(argv, iso_env.create_vagrant_env) # subject = described_class.new(argv, iso_env.create_vagrant_env)
allow(subject).to receive(:validate_pushes!) # allow(subject).to receive(:validate_pushes!)
.and_return(:noop) # .and_return(:noop)
expect { subject.execute }.to raise_error(Vagrant::Errors::ConfigInvalid) { |err| # expect { subject.execute }.to raise_error(Vagrant::Errors::ConfigInvalid) { |err|
expect(err.message).to include("The following settings shouldn't exist: bad") # expect(err.message).to include("The following settings shouldn't exist: bad")
} # }
end # end
end end
describe "#validate_pushes!" do describe "#validate_pushes!" do

View File

@ -0,0 +1,106 @@
require File.expand_path("../../../base", __FILE__)
require "vagrant/util/command_deprecation"
describe Vagrant::Util do
include_context "unit"
let(:app){ lambda{|env|} }
let(:argv){[]}
let(:env){ {ui: Vagrant::UI::Silent.new} }
let(:command_class) do
Class.new(Vagrant.plugin("2", :command)) do
def self.synopsis
"base synopsis"
end
def self.name
"VagrantPlugins::CommandTest::Command"
end
def execute
@env[:ui].info("COMMAND CONTENT")
0
end
end
end
let(:command){ command_class.new(app, env) }
describe Vagrant::Util::CommandDeprecation do
before{ command_class.include(Vagrant::Util::CommandDeprecation) }
it "should add deprecation warning to synopsis" do
expect(command_class.synopsis).to include('[DEPRECATED]')
command.class.synopsis
end
it "should add deprecation warning to #execute" do
expect(env[:ui]).to receive(:warn).with(/DEPRECATION WARNING/)
command.execute
end
it "should execute original command" do
expect(env[:ui]).to receive(:info).with("COMMAND CONTENT")
command.execute
end
it "should return with a 0 value" do
expect(command.execute).to eq(0)
end
context "with custom name defined" do
before do
command_class.class_eval do
def deprecation_command_name
"custom-name"
end
end
end
it "should use custom name within warning message" do
expect(env[:ui]).to receive(:warn).with(/custom-name/)
command.execute
end
end
context "with deprecated subcommand" do
let(:command_class) do
Class.new(Vagrant.plugin("2", :command)) do
def self.name
"VagrantPlugins::CommandTest::Command::Action"
end
def execute
@env[:ui].info("COMMAND CONTENT")
0
end
end
end
it "should not modify empty synopsis" do
expect(command_class.synopsis.to_s).to be_empty
end
it "should extract command name and subname" do
expect(command.deprecation_command_name).to eq("test action")
end
end
end
describe Vagrant::Util::CommandDeprecation::Complete do
before{ command_class.include(Vagrant::Util::CommandDeprecation::Complete) }
it "should add deprecation warning to synopsis" do
expect(command_class.synopsis).to include('[DEPRECATED]')
command.class.synopsis
end
it "should raise a deprecation error when executed" do
expect{ command.execute }.to raise_error(Vagrant::Errors::CommandDeprecated)
end
it "should not run original command" do
expect(env[:ui]).not_to receive(:info).with("COMMAND CONTENT")
expect{ command.execute }.to raise_error(Vagrant::Errors::CommandDeprecated)
end
end
end