Add command deprecation helper module

This commit is contained in:
Chris Roberts 2017-02-24 06:22:39 -08:00
parent 899fc7fb82
commit e2acb5250a
5 changed files with 173 additions and 0 deletions

View File

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

View File

@ -1,6 +1,7 @@
module Vagrant
module Util
autoload :Busy, 'vagrant/util/busy'
autoload :CommandDeprecation, 'vagrant/util/command_deprecation'
autoload :Counter, 'vagrant/util/counter'
autoload :CredentialScrubber, 'vagrant/util/credential_scrubber'
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

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

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