From 38becdf97cdbd060027776a551aad333fbddcd5a Mon Sep 17 00:00:00 2001 From: Xabier de Zuazo Date: Mon, 4 Mar 2013 15:05:54 +0100 Subject: [CHEF-3919] cookbook version specific code factored out from Chef::Version, new classes created: Chef::Version::Cookbook and Chef::VersionConstraint::Cookbook --- lib/chef/client.rb | 2 +- lib/chef/cookbook/metadata.rb | 4 +-- lib/chef/cookbook_version.rb | 8 +++--- lib/chef/environment.rb | 4 +-- lib/chef/exceptions.rb | 1 + lib/chef/knife/cookbook_download.rb | 4 +-- lib/chef/knife/cookbook_upload.rb | 4 +-- lib/chef/platform.rb | 2 +- lib/chef/run_list/versioned_recipe_list.rb | 8 +++--- lib/chef/version/cookbook.rb | 39 ++++++++++++++++++++++++++++++ lib/chef/version_class.rb | 6 ++--- lib/chef/version_constraint.rb | 9 ++++--- lib/chef/version_constraint/cookbook.rb | 26 ++++++++++++++++++++ spec/unit/cookbook_version_spec.rb | 2 +- spec/unit/environment_spec.rb | 1 + spec/unit/version_class_spec.rb | 6 ++--- spec/unit/version_constraint_spec.rb | 2 +- 17 files changed, 98 insertions(+), 30 deletions(-) create mode 100644 lib/chef/version/cookbook.rb create mode 100644 lib/chef/version_constraint/cookbook.rb diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 010f08acac..969b8e6d1a 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -292,7 +292,7 @@ class Chef # # Convert @expanded_run_list, which is an # Array of Hashes of the form - # {:name => NAME, :version_constraint => Chef::VersionConstraint }, + # {:name => NAME, :version_constraint => Chef::VersionConstraint::Cookbook }, # into @expanded_run_list_with_versions, an # Array of Strings of the form # "#{NAME}@#{VERSION}" diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb index 18368bd99f..b42a8df3fd 100644 --- a/lib/chef/cookbook/metadata.rb +++ b/lib/chef/cookbook/metadata.rb @@ -209,7 +209,7 @@ class Chef # version:: Returns the current version def version(arg=nil) if arg - @version = Chef::Version.new(arg) + @version = Chef::Version::Cookbook.new(arg) end @version.to_s @@ -516,7 +516,7 @@ OBSOLETED end def validate_version_constraint(caller_name, dep_name, constraint_str) - Chef::VersionConstraint.new(constraint_str) + Chef::VersionConstraint::Cookbook.new(constraint_str) rescue Chef::Exceptions::InvalidVersionConstraint => e Log.debug(e) diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index a70c892e1b..61917fc889 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -25,7 +25,7 @@ require 'chef/resource_definition_list' require 'chef/recipe' require 'chef/cookbook/file_vendor' require 'chef/cookbook/metadata' -require 'chef/version_class' +require 'chef/version/cookbook' class Chef @@ -669,9 +669,9 @@ class Chef def <=>(o) raise Chef::Exceptions::CookbookVersionNameMismatch if self.name != o.name # FIXME: can we change the interface to the Metadata class such - # that metadata.version returns a Chef::Version instance instead - # of a string? - Chef::Version.new(self.version) <=> Chef::Version.new(o.version) + # that metadata.version returns a Chef::Version::Cookbook instance + # instead of a string? + Chef::Version.new(self.version) <=> Chef::Version::Cookbook.new(o.version) end private diff --git a/lib/chef/environment.rb b/lib/chef/environment.rb index 00cc253083..7439be0304 100644 --- a/lib/chef/environment.rb +++ b/lib/chef/environment.rb @@ -22,7 +22,7 @@ require 'chef/config' require 'chef/mash' require 'chef/mixin/params_validate' require 'chef/mixin/from_file' -require 'chef/version_constraint' +require 'chef/version_constraint/cookbook' class Chef class Environment @@ -276,7 +276,7 @@ class Chef def self.validate_cookbook_version(version) begin - Chef::VersionConstraint.new version + Chef::VersionConstraint::Cookbook.new version true rescue ArgumentError false diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index 40dec4dc2a..3b2a75eb01 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -107,6 +107,7 @@ class Chef class CookbookVersionConflict < ArgumentError ; end # does not follow X.Y.Z format. ArgumentError? + class InvalidVersion < ArgumentError; end class InvalidCookbookVersion < ArgumentError; end # version constraint should be a string or array, or it doesn't diff --git a/lib/chef/knife/cookbook_download.rb b/lib/chef/knife/cookbook_download.rb index 1da1121b22..58f61cb561 100644 --- a/lib/chef/knife/cookbook_download.rb +++ b/lib/chef/knife/cookbook_download.rb @@ -98,7 +98,7 @@ class Chef if available_versions.size == 1 @version = available_versions.first elsif config[:latest] - @version = available_versions.map { |v| Chef::Version.new(v) }.sort.last + @version = available_versions.map { |v| Chef::Version::Cookbook.new(v) }.sort.last else ask_which_version end @@ -107,7 +107,7 @@ class Chef def available_versions @available_versions ||= begin versions = Chef::CookbookVersion.available_versions(@cookbook_name).map do |version| - Chef::Version.new(version) + Chef::Version::Cookbook.new(version) end versions.sort! versions diff --git a/lib/chef/knife/cookbook_upload.rb b/lib/chef/knife/cookbook_upload.rb index f50296509b..37535734e9 100644 --- a/lib/chef/knife/cookbook_upload.rb +++ b/lib/chef/knife/cookbook_upload.rb @@ -274,7 +274,7 @@ WARNING versions = @server_side_cookbooks[cookbook_name]['versions'].collect {|versions| versions["version"]} Log.debug "Versions of cookbook '#{cookbook_name}' returned by the server: #{versions.join(", ")}" @server_side_cookbooks[cookbook_name]["versions"].each do |versions_hash| - if Chef::VersionConstraint.new(version).include?(versions_hash["version"]) + if Chef::VersionConstraint::Cookbook.new(version).include?(versions_hash["version"]) Log.debug "Matched cookbook '#{cookbook_name}' with constraint '#{version}' to cookbook version '#{versions_hash['version']}' on the server" return true end @@ -284,7 +284,7 @@ WARNING end def check_uploading_cookbooks(cookbook_name, version) - if (! cookbooks_to_upload[cookbook_name].nil?) && Chef::VersionConstraint.new(version).include?(cookbooks_to_upload[cookbook_name].version) + if (! cookbooks_to_upload[cookbook_name].nil?) && Chef::VersionConstraint::Cookbook.new(version).include?(cookbooks_to_upload[cookbook_name].version) Log.debug "Matched cookbook '#{cookbook_name}' with constraint '#{version}' to a local cookbook." return true end diff --git a/lib/chef/platform.rb b/lib/chef/platform.rb index 4c407673e2..bca003d35a 100644 --- a/lib/chef/platform.rb +++ b/lib/chef/platform.rb @@ -345,7 +345,7 @@ class Chef end platform_versions.each do |platform_version, provider| begin - version_constraint = Chef::VersionConstraint.new(platform_version) + version_constraint = Chef::VersionConstraint::Cookbook.new(platform_version) if version_constraint.include?(version) Chef::Log.debug("Platform #{name.to_s} version #{version} found") provider_map.merge!(provider) diff --git a/lib/chef/run_list/versioned_recipe_list.rb b/lib/chef/run_list/versioned_recipe_list.rb index 0eefded964..9339985207 100644 --- a/lib/chef/run_list/versioned_recipe_list.rb +++ b/lib/chef/run_list/versioned_recipe_list.rb @@ -15,7 +15,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require 'chef/version_class' +require 'chef/version/cookbook' require 'chef/version_constraint' # Why does this class exist? @@ -31,7 +31,7 @@ class Chef def add_recipe(name, version=nil) if version && @versions.has_key?(name) - unless Chef::Version.new(@versions[name]) == Chef::Version.new(version) + unless Chef::Version::Cookbook.new(@versions[name]) == Chef::Version::Cookbook.new(version) raise Chef::Exceptions::CookbookVersionConflict, "Run list requires #{name} at versions #{@versions[name]} and #{version}" end end @@ -44,10 +44,10 @@ class Chef end # Return an Array of Hashes, each of the form: - # {:name => RECIPE_NAME, :version_constraint => Chef::VersionConstraint } + # {:name => RECIPE_NAME, :version_constraint => Chef::VersionConstraint::Cookbook } def with_version_constraints self.map do |recipe_name| - constraint = Chef::VersionConstraint.new(@versions[recipe_name]) + constraint = Chef::VersionConstraint::Cookbook.new(@versions[recipe_name]) { :name => recipe_name, :version_constraint => constraint } end end diff --git a/lib/chef/version/cookbook.rb b/lib/chef/version/cookbook.rb new file mode 100644 index 0000000000..391d46563c --- /dev/null +++ b/lib/chef/version/cookbook.rb @@ -0,0 +1,39 @@ +# Author:: Xabier de Zuazo () +# Copyright:: Copyright (c) 2013 Onddo Labs, SL. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'chef/version_class' + +class Chef + class Version + class Cookbook < Chef::Version + + protected + + def parse(str='') + msg = "'#{str.to_s}' does not match 'x.y.z' or 'x.y'" + begin + super + rescue Chef::Exceptions::InvalidVersion => e + raise Chef::Exceptions::InvalidCookbookVersion.new( msg ) + end + if str.to_s =~ /^(\d+)$/ + raise Chef::Exceptions::InvalidCookbookVersion.new( msg ) + end + end + + end + end +end diff --git a/lib/chef/version_class.rb b/lib/chef/version_class.rb index 36ff05a46d..25b393854b 100644 --- a/lib/chef/version_class.rb +++ b/lib/chef/version_class.rb @@ -51,7 +51,7 @@ class Chef other.is_a?(Version) && self == other end - private + protected def parse(str="") @major, @minor, @patch = @@ -63,8 +63,8 @@ class Chef when /^(\d+)$/ [ $1.to_i, 0, 0 ] else - msg = "'#{str.to_s}' does not match 'x.y.z' or 'x.y'" - raise Chef::Exceptions::InvalidCookbookVersion.new( msg ) + msg = "'#{str.to_s}' does not match 'x.y.z', 'x.y' or 'x'" + raise Chef::Exceptions::InvalidVersion.new( msg ) end end diff --git a/lib/chef/version_constraint.rb b/lib/chef/version_constraint.rb index b6f1f08757..15ae993b67 100644 --- a/lib/chef/version_constraint.rb +++ b/lib/chef/version_constraint.rb @@ -22,6 +22,7 @@ class Chef STANDARD_OPS = %w(< > <= >=) OPS = %w(< > = <= >= ~>) PATTERN = /^(#{OPS.join('|')}) (.+)$/ + VERSION_CLASS = Chef::Version attr_reader :op, :version @@ -41,9 +42,9 @@ class Chef def include?(v) version = if v.respond_to? :version # a CookbookVersion-like object - Chef::Version.new(v.version.to_s) + self.class::VERSION_CLASS.new(v.version.to_s) else - Chef::Version.new(v.to_s) + self.class::VERSION_CLASS.new(v.to_s) end do_op(version) end @@ -98,12 +99,12 @@ class Chef @missing_patch_level = false if str.index(" ").nil? && str =~ /^[0-9]/ # try for lone version, implied '=' - @version = Chef::Version.new(str) + @version = self.class::VERSION_CLASS.new(str) @op = "=" elsif PATTERN.match str @op = $1 raw_version = $2 - @version = Chef::Version.new(raw_version) + @version = self.class::VERSION_CLASS.new(raw_version) if raw_version.split('.').size == 2 @missing_patch_level = true end diff --git a/lib/chef/version_constraint/cookbook.rb b/lib/chef/version_constraint/cookbook.rb new file mode 100644 index 0000000000..2ed6ef2872 --- /dev/null +++ b/lib/chef/version_constraint/cookbook.rb @@ -0,0 +1,26 @@ +# Author:: Xabier de Zuazo () +# Copyright:: Copyright (c) 2013 Onddo Labs, SL. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +require 'chef/version_constraint' +require 'chef/version/cookbook' + +class Chef + class VersionConstraint + class Cookbook < Chef::VersionConstraint + VERSION_CLASS = Chef::Version::Cookbook + + end + end +end diff --git a/spec/unit/cookbook_version_spec.rb b/spec/unit/cookbook_version_spec.rb index 7244f47557..85e1db1fae 100644 --- a/spec/unit/cookbook_version_spec.rb +++ b/spec/unit/cookbook_version_spec.rb @@ -294,7 +294,7 @@ describe Chef::CookbookVersion do end it "should raise InvalidVersion for bad cookbook versions" do - bad_versions = ["1.2.3.4", "1.2.a4", "a", "1.2 3", "1.2 a", + bad_versions = ["1.2.3.4", "1.2.a4", "1", "a", "1.2 3", "1.2 a", "1 2 3", "1-2-3", "1_2_3", "1.2_3", "1.2-3"] the_error = Chef::Exceptions::InvalidCookbookVersion bad_versions.each do |v| diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb index 9c3cc2c424..99232dff08 100644 --- a/spec/unit/environment_spec.rb +++ b/spec/unit/environment_spec.rb @@ -270,6 +270,7 @@ describe Chef::Environment do it "should return false when an invalid version is given" do Chef::Environment.validate_cookbook_version(Chef::CookbookVersion.new("meta")).should == false Chef::Environment.validate_cookbook_version("= 1.2.3a").should == false + Chef::Environment.validate_cookbook_version("= 1").should == false Chef::Environment.validate_cookbook_version("= a").should == false Chef::Environment.validate_cookbook_version("= 1.2.3.4").should == false end diff --git a/spec/unit/version_class_spec.rb b/spec/unit/version_class_spec.rb index 285588b031..f95bfa1293 100644 --- a/spec/unit/version_class_spec.rb +++ b/spec/unit/version_class_spec.rb @@ -44,7 +44,7 @@ describe Chef::Version do end describe "when creating valid Versions" do - good_versions = %w(1.2 1.2.3 1000.80.50000 0.300.25 001.02.00003) + good_versions = %w(1 1.2 1.2.3 1000.80.50000 0.300.25 001.02.00003) good_versions.each do |v| it "should accept '#{v}'" do Chef::Version.new v @@ -53,9 +53,9 @@ describe Chef::Version do end describe "when given bogus input" do - bad_versions = ["1.2.3.4", "1.2.a4", "1", "a", "1.2 3", "1.2 a", + bad_versions = ["1.2.3.4", "1.2.a4", "a", "1.2 3", "1.2 a", "1 2 3", "1-2-3", "1_2_3", "1.2_3", "1.2-3"] - the_error = Chef::Exceptions::InvalidCookbookVersion + the_error = Chef::Exceptions::InvalidVersion bad_versions.each do |v| it "should raise #{the_error} when given '#{v}'" do lambda { Chef::Version.new v }.should raise_error(the_error) diff --git a/spec/unit/version_constraint_spec.rb b/spec/unit/version_constraint_spec.rb index aea7001f2b..fe9c57c8f5 100644 --- a/spec/unit/version_constraint_spec.rb +++ b/spec/unit/version_constraint_spec.rb @@ -23,7 +23,7 @@ describe Chef::VersionConstraint do bad_version = ["> >", ">= 1.2.z", "> 1.2.3 < 5.0", "> 1.2.3, < 5.0"] bad_op = ["<3.0.1", ">$ 1.2.3", "! 3.4"] o_error = Chef::Exceptions::InvalidVersionConstraint - v_error = Chef::Exceptions::InvalidCookbookVersion + v_error = Chef::Exceptions::InvalidVersion bad_version.each do |s| it "should raise #{v_error} when given #{s}" do lambda { Chef::VersionConstraint.new s }.should raise_error(v_error) -- cgit v1.2.1