diff --git a/lib/puppet/provider/package/macports.rb b/lib/puppet/provider/package/macports.rb index 659c0d98a..6a1066bb9 100755 --- a/lib/puppet/provider/package/macports.rb +++ b/lib/puppet/provider/package/macports.rb @@ -1,101 +1,101 @@ require 'puppet/provider/package' Puppet::Type.type(:package).provide :macports, :parent => Puppet::Provider::Package do desc "Package management using MacPorts on OS X. Supports MacPorts versions and revisions, but not variants. Variant preferences may be specified using [the MacPorts variants.conf file](http://guide.macports.org/chunked/internals.configuration-files.html#internals.configuration-files.variants-conf). When specifying a version in the Puppet DSL, only specify the version, not the revision. Revisions are only used internally for ensuring the latest version/revision of a port. " confine :operatingsystem => :darwin commands :port => "/opt/local/bin/port" has_feature :installable has_feature :uninstallable has_feature :upgradeable has_feature :versionable def self.parse_installed_query_line(line) regex = /(\S+)\s+@(\S+)_(\S+)\s+\(active\)/ fields = [:name, :ensure, :revision] hash_from_line(line, regex, fields) end def self.parse_info_query_line(line) regex = /(\S+)\s+(\S+)/ fields = [:version, :revision] hash_from_line(line, regex, fields) end def self.hash_from_line(line, regex, fields) hash = {} if match = regex.match(line) fields.zip(match.captures) { |field, value| hash[field] = value } hash[:provider] = self.name return hash end nil end def self.instances packages = [] - port("-q", :installed).each do |line| + port("-q", :installed).each_line do |line| if hash = parse_installed_query_line(line) packages << new(hash) end end packages end def install should = @resource.should(:ensure) if [:latest, :installed, :present].include?(should) output = port("-q", :install, @resource[:name]) else output = port("-q", :install, @resource[:name], "@#{should}") end # MacPorts now correctly exits non-zero with appropriate errors in # situations where a port cannot be found or installed. end def query return self.class.parse_installed_query_line(port("-q", :installed, @resource[:name])) end def latest # We need both the version and the revision to be confident # we've got the latest revision of a specific version # Note we're still not doing anything with variants here. info_line = port("-q", :info, "--line", "--version", "--revision", @resource[:name]) return nil if info_line == "" if newest = self.class.parse_info_query_line(info_line) current = query # We're doing some fiddling behind the scenes here to cope with updated revisions. # If we're already at the latest version/revision, then just return the version # so the current and desired values match. Otherwise return version and revision # to trigger an upgrade to the latest revision. if newest[:version] == current[:ensure] and newest[:revision] == current[:revision] return current[:ensure] else return "#{newest[:version]}_#{newest[:revision]}" end end nil end def uninstall port("-q", :uninstall, @resource[:name]) end def update install end end diff --git a/spec/unit/provider/package/macports_spec.rb b/spec/unit/provider/package/macports_spec.rb index 765cc00d0..63c4b03f5 100755 --- a/spec/unit/provider/package/macports_spec.rb +++ b/spec/unit/provider/package/macports_spec.rb @@ -1,122 +1,122 @@ require 'spec_helper' provider_class = Puppet::Type.type(:package).provider(:macports) describe provider_class do let :resource_name do "foo" end let :resource do Puppet::Type.type(:package).new(:name => resource_name, :provider => :macports) end let :provider do prov = resource.provider prov.expects(:execute).never prov end let :current_hash do {:name => resource_name, :ensure => "1.2.3", :revision => "1", :provider => :macports} end describe "provider features" do subject { provider } it { should be_installable } it { should be_uninstallable } it { should be_upgradeable } it { should be_versionable } end - describe "when listing all instances", :'fails_on_ruby_1.9.2' => true do + describe "when listing all instances" do it "should call port -q installed" do provider_class.expects(:port).with("-q", :installed).returns("") provider_class.instances end it "should create instances from active ports" do provider_class.expects(:port).returns("foo @1.234.5_2 (active)") provider_class.instances.size.should == 1 end it "should ignore ports that aren't activated" do provider_class.expects(:port).returns("foo @1.234.5_2") provider_class.instances.size.should == 0 end end describe "when installing" do it "should not specify a version when ensure is set to latest" do resource[:ensure] = :latest provider.expects(:port).with { |flag, method, name, version| version.should be_nil } provider.install end it "should not specify a version when ensure is set to present" do resource[:ensure] = :present provider.expects(:port).with { |flag, method, name, version| version.should be_nil } provider.install end it "should specify a version when ensure is set to a version" do resource[:ensure] = "1.2.3" provider.expects(:port).with { |flag, method, name, version| version.should be } provider.install end end describe "when querying for the latest version" do let :new_info_line do "1.2.3 2" end let :infoargs do ["-q", :info, "--line", "--version", "--revision", resource_name] end it "should return nil when the package cannot be found" do resource[:name] = resource_name provider.expects(:port).returns("") provider.latest.should == nil end it "should return the current version if the installed port has the same revision" do current_hash[:revision] = "2" provider.expects(:port).with(*infoargs).returns(new_info_line) provider.expects(:query).returns(current_hash) provider.latest.should == current_hash[:ensure] end it "should return the new version_revision if the installed port has a lower revision" do current_hash[:revision] = "1" provider.expects(:port).with(*infoargs).returns(new_info_line) provider.expects(:query).returns(current_hash) provider.latest.should == "1.2.3_2" end end describe "when updating a port" do it "should execute port install if the port is installed" do resource[:name] = resource_name resource[:ensure] = :present provider.stubs(:query).returns(current_hash) provider.expects(:port).with("-q", :install, resource_name) provider.update end - it "should execute port install if the port is not installed", :'fails_on_ruby_1.9.2' => true do + it "should execute port install if the port is not installed" do resource[:name] = resource_name resource[:ensure] = :present provider.stubs(:query).returns("") provider.expects(:port).with("-q", :install, resource_name) provider.update end end end