diff --git a/lib/vagrant/box_collection.rb b/lib/vagrant/box_collection.rb index 17b0eb405..bbcf10161 100644 --- a/lib/vagrant/box_collection.rb +++ b/lib/vagrant/box_collection.rb @@ -246,7 +246,10 @@ module Vagrant end end end - + # Sort the list to group like providers and properly ordered versions + results.sort_by! do |box_result| + [box_result[0], box_result[2], Gem::Version.new(box_result[1])] + end results end diff --git a/test/unit/vagrant/box_collection_test.rb b/test/unit/vagrant/box_collection_test.rb index 9537f235e..f012be2ad 100644 --- a/test/unit/vagrant/box_collection_test.rb +++ b/test/unit/vagrant/box_collection_test.rb @@ -43,6 +43,75 @@ describe Vagrant::BoxCollection, :skip_windows do expect { subject.all }.to_not raise_error end end + + context "with multiple versions of the same box" do + before do + environment.box3("foo", "1.0", :virtualbox) + environment.box3("foo", "2.0.3", :virtualbox) + environment.box3("foo", "2.0.4", :virtualbox) + environment.box3("foo", "10.3", :virtualbox) + environment.box3("foo", "1.0", :vmware) + environment.box3("foo", "0.4.3", :vmware) + environment.box3("foo", "2.0.1", :vmware) + environment.box3("foo", "2.0.2.dev", :vmware) + environment.box3("foo", "2.0.2", :vmware) + environment.box3("bar", "20161203.2", :ec2) + environment.box3("bar", "20161203.2.3", :ec2) + environment.box3("bar", "20151102.0.0", :ec2) + environment.box3("foo-VAGRANTSLASH-bar", "1.0", :virtualbox) + environment.box3("foo-VAGRANTCOLON-colon", "1.0", :virtualbox) + end + + it "should sort boxes by name" do + result = subject.all.map(&:first).uniq + expect(result).to eq(["bar", "foo", "foo/bar", "foo:colon"]) + end + + it "should group boxes by provider" do + expect do + current = "" + seen_pairs = {} + subject.all.each do |box_info| + box_key = "#{box_info[0]}_#{box_info[2]}" + if current != box_key + if seen_pairs[box_key] + raise KeyError.new("Box/provider pair already seen. Invalid sort!") + else + current = box_key + seen_pairs[box_key] = true + end + end + end + end.not_to raise_error + end + + it "should sort boxes by version" do + box_list = subject.all.find_all do |box_info| + box_info[0] == "foo" && box_info[2].to_s == "virtualbox" + end + result = box_list.map{|box_info| box_info[1]} + expect(result).to eq([ + "1.0", + "2.0.3", + "2.0.4", + "10.3" + ]) + end + + it "should sort boxes with pre-release versions" do + box_list = subject.all.find_all do |box_info| + box_info[0] == "foo" && box_info[2].to_s == "vmware" + end + result = box_list.map{|box_info| box_info[1]} + expect(result).to eq([ + "0.4.3", + "1.0", + "2.0.1", + "2.0.2.dev", + "2.0.2" + ]) + end + end end describe "#clean" do @@ -218,6 +287,35 @@ describe Vagrant::BoxCollection, :skip_windows do result = subject.find("foo", :virtualbox, "> 1.0, < 1.5") expect(result).to be_nil end + + context "with multiple versions of the same box" do + before do + environment.box3("foo", "1.0", :virtualbox) + environment.box3("foo", "2.0.3", :virtualbox) + environment.box3("foo", "2.0.4", :virtualbox) + environment.box3("foo", "10.3", :virtualbox) + environment.box3("foo", "1.0", :vmware) + environment.box3("foo", "0.4.3", :vmware) + environment.box3("foo", "2.0.1", :vmware) + environment.box3("foo", "2.0.2.dev", :vmware) + environment.box3("foo", "2.0.2", :vmware) + environment.box3("bar", "20161203.2", :ec2) + environment.box3("bar", "20161203.2.3", :ec2) + environment.box3("bar", "20151102.0.0", :ec2) + environment.box3("foo-VAGRANTSLASH-bar", "1.0", :virtualbox) + environment.box3("foo-VAGRANTCOLON-colon", "1.0", :virtualbox) + end + + it "should return expected latest version" do + result = subject.find("foo", :virtualbox, "> 2, < 3") + expect(result.version).to eq("2.0.4") + end + + it "should sort boxes with pre-release versions" do + result = subject.find("foo", :vmware, "> 2, < 3") + expect(result.version).to eq("2.0.2") + end + end end describe "#add" do