Add force flag for package command
- when the package output file already exists and force flag is not specified, the user is prompted for overwrite when the package output file exists and force flag is specified, the output file is overwritten without prompting the user
This commit is contained in:
parent
7e0e7ff7e9
commit
38f7bf25e0
|
@ -15,6 +15,7 @@ module Vagrant
|
|||
autoload :Confirm, "vagrant/action/builtin/confirm"
|
||||
autoload :ConfigValidate, "vagrant/action/builtin/config_validate"
|
||||
autoload :DestroyConfirm, "vagrant/action/builtin/destroy_confirm"
|
||||
autoload :PackageOutputOverwriteConfirm, "vagrant/action/builtin/package_output_overwrite_confirm"
|
||||
autoload :EnvSet, "vagrant/action/builtin/env_set"
|
||||
autoload :GracefulHalt, "vagrant/action/builtin/graceful_halt"
|
||||
autoload :HandleBox, "vagrant/action/builtin/handle_box"
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
require_relative "confirm"
|
||||
|
||||
module Vagrant
|
||||
module Action
|
||||
module Builtin
|
||||
class PackageOutputOverwriteConfirm < Confirm
|
||||
def initialize(app, env)
|
||||
force_key = "package.force_output_overwrite"
|
||||
message = I18n.t("vagrant.actions.general.package.output_exists.overwrite_confirmation",
|
||||
name: env["package.output"])
|
||||
|
||||
super(app, env, message, force_key, allowed: %w(y n Y N))
|
||||
end
|
||||
|
||||
def call(env)
|
||||
output = File.expand_path(env["package.output"], Dir.pwd)
|
||||
|
||||
if File.exist?(output)
|
||||
super
|
||||
else
|
||||
env[:result] = true
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,17 +31,12 @@ module Vagrant
|
|||
# @param [String] output path to the output file
|
||||
# @param [String] directory path to a directory containing the files
|
||||
def self.validate!(output, directory)
|
||||
filename = File.basename(output.to_s)
|
||||
output = fullpath(output)
|
||||
|
||||
if File.directory?(output)
|
||||
raise Vagrant::Errors::PackageOutputDirectory
|
||||
end
|
||||
|
||||
if File.exist?(output)
|
||||
raise Vagrant::Errors::PackageOutputExists, filename: filename
|
||||
end
|
||||
|
||||
if !Vagrant::Util::Presence.present?(directory) || !File.directory?(directory)
|
||||
raise Vagrant::Errors::PackageRequiresDirectory
|
||||
end
|
||||
|
@ -101,7 +96,7 @@ module Vagrant
|
|||
@env = env
|
||||
|
||||
# There are certain exceptions that we don't delete the file for.
|
||||
ignore_exc = [Errors::PackageOutputDirectory, Errors::PackageOutputExists]
|
||||
ignore_exc = [Errors::PackageOutputDirectory]
|
||||
ignore_exc.each do |exc|
|
||||
return if env["vagrant.error"].is_a?(exc)
|
||||
end
|
||||
|
|
|
@ -552,10 +552,6 @@ module Vagrant
|
|||
error_key(:output_is_directory, "vagrant.actions.general.package")
|
||||
end
|
||||
|
||||
class PackageOutputExists < VagrantError
|
||||
error_key(:output_exists, "vagrant.actions.general.package")
|
||||
end
|
||||
|
||||
class PackageRequiresDirectory < VagrantError
|
||||
error_key(:requires_directory, "vagrant.actions.general.package")
|
||||
end
|
||||
|
|
|
@ -32,6 +32,10 @@ module VagrantPlugins
|
|||
o.on("--vagrantfile FILE", "Vagrantfile to package with the box") do |v|
|
||||
options[:vagrantfile] = v
|
||||
end
|
||||
|
||||
o.on("-f", "--force", "Vagrantfile to package with the box") do |f|
|
||||
options[:force_output_overwrite] = f
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
|
|
@ -79,10 +79,16 @@ module VagrantPlugins
|
|||
b2.use PackageSetupFiles
|
||||
b2.use action_halt
|
||||
b2.use SyncedFolderCleanup
|
||||
b2.use Package
|
||||
b2.use PackageVagrantfile
|
||||
b2.use PackageMetadataJson
|
||||
b2.use Export
|
||||
b2.use Call, PackageOutputOverwriteConfirm do |env2, b3|
|
||||
if env2[:result]
|
||||
b3.use Package
|
||||
b3.use PackageVagrantfile
|
||||
b3.use PackageMetadataJson
|
||||
b3.use Export
|
||||
else
|
||||
b3.use MessageWillNotOverwritePackageOutput
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,6 +30,7 @@ module VagrantPlugins
|
|||
autoload :MessageNotCreated, File.expand_path("../action/message_not_created", __FILE__)
|
||||
autoload :MessageNotRunning, File.expand_path("../action/message_not_running", __FILE__)
|
||||
autoload :MessageWillNotDestroy, File.expand_path("../action/message_will_not_destroy", __FILE__)
|
||||
autoload :MessageWillNotOverwritePackageOutput, File.expand_path("../action/message_will_not_overwrite_package_output", __FILE__)
|
||||
autoload :Network, File.expand_path("../action/network", __FILE__)
|
||||
autoload :NetworkFixIPv6, File.expand_path("../action/network_fix_ipv6", __FILE__)
|
||||
autoload :Package, File.expand_path("../action/package", __FILE__)
|
||||
|
@ -163,11 +164,18 @@ module VagrantPlugins
|
|||
b2.use ClearForwardedPorts
|
||||
b2.use PrepareNFSValidIds
|
||||
b2.use SyncedFolderCleanup
|
||||
b2.use Package
|
||||
b2.use Export
|
||||
b2.use PackageVagrantfile
|
||||
b2.use Call, PackageOutputOverwriteConfirm do |env2, b3|
|
||||
if env2[:result]
|
||||
b3.use Package
|
||||
b3.use Export
|
||||
b3.use PackageVagrantfile
|
||||
else
|
||||
b3.use MessageWillNotOverwritePackageOutput
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# This action just runs the provisioners on the machine.
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
module VagrantPlugins
|
||||
module ProviderVirtualBox
|
||||
module Action
|
||||
class MessageWillNotOverwritePackageOutput
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].info I18n.t("vagrant.actions.general.package.output_exists.will_not_overwrite",
|
||||
name: env[:machine].name)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2426,9 +2426,11 @@ en:
|
|||
packaging: "Packaging additional file: %{file}"
|
||||
compressing: "Compressing package to: %{fullpath}"
|
||||
box_folder: "Creating new folder: %{folder_path}"
|
||||
output_exists: |-
|
||||
The specified file '%{filename}' to save the package as already exists. Please
|
||||
remove this file or specify a different file name for outputting.
|
||||
output_exists:
|
||||
overwrite_confirmation: "Are you sure you want to overwrite '%{name}'? [y/N] "
|
||||
will_not_overwrite: |-
|
||||
The VM '%{name}' will not be packaged, since the confirmation
|
||||
was declined.
|
||||
output_is_directory: |-
|
||||
The specified output is a directory. Please specify a path including
|
||||
a filename.
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
require File.expand_path("../../../../base", __FILE__)
|
||||
|
||||
describe Vagrant::Action::Builtin::PackageOutputOverwriteConfirm do
|
||||
let(:app) {lambda {|env|}}
|
||||
let(:output) {"output.box"}
|
||||
let(:env) {{"package.output" => output, ui: double("ui")}}
|
||||
let(:message) {"Are you sure you want to overwrite 'output.box'? [y/N] "}
|
||||
|
||||
context "when package output file exist" do
|
||||
before do
|
||||
allow(File).to receive(:expand_path).with(output, any_args).and_return(output)
|
||||
allow(File).to receive(:exist?).with(output).and_return(true)
|
||||
end
|
||||
|
||||
%w(y Y).each do |valid|
|
||||
it "should set the result to true if '#{valid}' is given" do
|
||||
expect(env[:ui]).to receive(:ask).with(message).and_return(valid)
|
||||
described_class.new(app, env).call(env)
|
||||
expect(env[:result]).to be
|
||||
end
|
||||
end
|
||||
|
||||
%w(n N).each do |valid|
|
||||
it "should set the result to true if '#{valid}' is given" do
|
||||
expect(env[:ui]).to receive(:ask).with(message).and_return(valid)
|
||||
described_class.new(app, env).call(env)
|
||||
expect(env[:result]).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when package output file don't exist" do
|
||||
before do
|
||||
allow(File).to receive(:expand_path).with(output, any_args).and_return(output)
|
||||
allow(File).to receive(:exist?).with(output).and_return(false)
|
||||
end
|
||||
|
||||
it "should set the result to true" do
|
||||
described_class.new(app, env).call(env)
|
||||
expect(env[:result]).to be
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,7 +26,6 @@ describe Vagrant::Action::General::Package do
|
|||
allow(described_class).to receive(:fullpath).and_return(output)
|
||||
allow(File).to receive(:directory?).with(output).and_return(false)
|
||||
allow(File).to receive(:directory?).with(directory).and_return(true)
|
||||
allow(File).to receive(:exist?).and_return(false)
|
||||
allow(Vagrant::Util::Presence).to receive(:present?).with(directory).and_return(true)
|
||||
end
|
||||
|
||||
|
@ -34,20 +33,13 @@ describe Vagrant::Action::General::Package do
|
|||
expect { described_class.validate!(output, directory) }.not_to raise_error
|
||||
end
|
||||
|
||||
it "should raise error when output directory exists" do
|
||||
it "should raise error when output is a directory" do
|
||||
expect(File).to receive(:directory?).with(output).and_return(true)
|
||||
expect {
|
||||
described_class.validate!(output, directory)
|
||||
}.to raise_error(Vagrant::Errors::PackageOutputDirectory)
|
||||
end
|
||||
|
||||
it "should raise error if output path exists" do
|
||||
expect(File).to receive(:exist?).with(output).and_return(true)
|
||||
expect {
|
||||
described_class.validate!(output, directory)
|
||||
}.to raise_error(Vagrant::Errors::PackageOutputExists)
|
||||
end
|
||||
|
||||
it "should raise error if directory value not provided" do
|
||||
expect(Vagrant::Util::Presence).to receive(:present?).and_call_original
|
||||
expect {
|
||||
|
@ -131,16 +123,6 @@ describe Vagrant::Action::General::Package do
|
|||
subject.recover(env)
|
||||
end
|
||||
end
|
||||
|
||||
context "when vagrant error is PackageOutputExists" do
|
||||
let(:error) { Vagrant::Errors::PackageOutputExists.new }
|
||||
|
||||
it "should not do anything" do
|
||||
expect(File).not_to receive(:exist?)
|
||||
expect(File).not_to receive(:delete)
|
||||
subject.recover(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#copy_include_files" do
|
||||
|
|
Loading…
Reference in New Issue