commands/box: outdated command to find outdated boxes

This commit is contained in:
Mitchell Hashimoto 2014-01-24 14:14:05 -08:00
parent b81686e2c9
commit f2509f5c65
7 changed files with 125 additions and 2 deletions

View File

@ -1,8 +1,11 @@
require 'fileutils'
require "tempfile"
require "json"
require "log4r"
require "vagrant/box_metadata"
require "vagrant/util/downloader"
require "vagrant/util/platform"
require "vagrant/util/safe_chdir"
require "vagrant/util/subprocess"
@ -82,6 +85,25 @@ module Vagrant
return true
end
# Loads the metadata URL and returns the latest metadata associated
# with this box.
#
# @return [BoxMetadata]
def load_metadata
tf = Tempfile.new("vagrant")
tf.close
url = @metadata_url
if File.file?(url) || url !~ /^[a-z0-9]+:.*$/i
url = File.expand_path(url)
url = Util::Platform.cygwin_windows_path(url)
url = "file:#{url}"
end
Util::Downloader.new(url, tf.path).download!
BoxMetadata.new(File.open(tf.path, "r"))
end
# This repackages this box and outputs it to the given path.
#
# @param [Pathname] path The full path (filename included) of where
@ -110,7 +132,7 @@ module Vagrant
# Comparison is done by composing the name and provider
"#{@name}-#{@version}-#{@provider}" <=>
"#{other.name}-#{other.version}-#{other.provider}"
"#{other.name}-#{other.version}-#{other.provider}"
end
end
end

View File

@ -208,6 +208,8 @@ module Vagrant
# Otherwise, traverse the subdirectories and see what versions
# we have.
child.children(true).each do |versiondir|
next if !versiondir.directory?
version = versiondir.basename.to_s
versiondir.children(true).each do |provider|

View File

@ -29,7 +29,7 @@ module Vagrant
@name = @raw["name"]
@description = @raw["description"]
@version_map = @raw["versions"].map do |v|
@version_map = (@raw["versions"] || []).map do |v|
[Gem::Version.new(v["version"]), v]
end
@version_map = Hash[@version_map]

View File

@ -0,0 +1,59 @@
require 'optparse'
module VagrantPlugins
module CommandBox
module Command
class Outdated < Vagrant.plugin("2", :command)
def execute
OptionParser.new do |o|
o.banner = "Usage: vagrant box outdated"
end
boxes = {}
@env.boxes.all.reverse.each do |name, version, provider|
next if boxes[name]
boxes[name] = @env.boxes.find(name, provider, version)
end
boxes.values.each do |box|
if !box.metadata_url
@env.ui.output(I18n.t(
"vagrant.box_outdated_no_metadata",
name: box.name))
next
end
md = nil
begin
md = box.load_metadata
rescue Vagrant::Errors::DownloaderError => e
@env.ui.error(I18n.t(
"vagrant.box_outdated_metadata_error",
name: box.name,
message: e.extra_data[:message]))
next
end
current = Gem::Version.new(box.version)
latest = Gem::Version.new(md.versions.last)
if latest <= current
@env.ui.success(I18n.t(
"vagrant.box_up_to_date",
name: box.name,
version: box.version))
else
@env.ui.warn(I18n.t(
"vagrant.box_outdated",
name: box.name,
current: box.version,
latest: latest.to_s,))
end
end
# Success, exit status 0
0
end
end
end
end
end

View File

@ -24,6 +24,11 @@ module VagrantPlugins
List
end
@subcommands.register(:outdated) do
require_relative "outdated"
Outdated
end
@subcommands.register(:remove) do
require File.expand_path("../remove", __FILE__)
Remove

View File

@ -28,6 +28,14 @@ en:
URL: %{url}
box_loading_metadata: |-
Loading metadata for box '%{name}'
box_outdated: |-
* '%{name}' is outdated! Current: %{current}. Latest: %{latest}
box_outdated_metadata_error: |-
* '%{name}': Error loading metadata: %{message}
box_outdated_no_metadata: |-
* '%{name}' wasn't added from a catalog, no version information
box_up_to_date: |-
* '%{name}' (v%{version}) is up to date
cfengine_bootstrapping: |-
Bootstrapping CFEngine with policy server: %{policy_server}...
cfengine_bootstrapping_policy_hub: |-

View File

@ -1,6 +1,7 @@
require File.expand_path("../../base", __FILE__)
require "pathname"
require "tempfile"
describe Vagrant::Box do
include_context "unit"
@ -75,6 +76,32 @@ describe Vagrant::Box do
end
end
context "#load_metadata" do
let(:metadata_url) do
Tempfile.new("vagrant").tap do |f|
f.write(<<-RAW)
{
"name": "foo",
"description": "bar"
}
RAW
f.close
end
end
subject do
described_class.new(
name, provider, version, directory,
metadata_url: metadata_url.path)
end
it "loads the url and returns the data" do
result = subject.load_metadata
expect(result.name).to eq("foo")
expect(result.description).to eq("bar")
end
end
describe "destroying" do
it "should destroy an existing box" do
# Verify that our "box" exists