summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Turnbull <james@lovedthanlost.net>2008-07-08 08:53:42 +1000
committerJames Turnbull <james@lovedthanlost.net>2008-07-08 08:53:42 +1000
commit56525beb26d8371533a17667e6ebcae0cda9a6f6 (patch)
treef240643693d4180c0a8efd8961363e6e7015a03c
parent1fe0660f6b468b8637ac60cd73a033e7726ef838 (diff)
parent667fac18cc3682374de991bb740ae834d8c17bee (diff)
Merge branch 'tickets/0.24.x/1226' of git://github.com/lak/puppet into 0.24.x
-rw-r--r--CHANGELOG2
-rwxr-xr-xlib/puppet/provider/package/gem.rb45
-rw-r--r--spec/unit/provider/package/gem.rb87
3 files changed, 122 insertions, 12 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 88fd2ca8d..658784841 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,8 @@
looks up ldap groups, at this point; if you want to set an ldap
user's primary group to a local group, you have to specify the GID.
+ Fixed #1226 - gems can now specify source repositories.
+
Fixed #1232 - the rundir no longer specifies a user/group,
and there are now client- and server-specific yaml directories.
diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb
index bb09bc5b0..133243c86 100755
--- a/lib/puppet/provider/package/gem.rb
+++ b/lib/puppet/provider/package/gem.rb
@@ -1,9 +1,12 @@
require 'puppet/provider/package'
+require 'uri'
# Ruby gems support.
Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package do
- desc "Ruby Gem support. By default uses remote gems, but you can specify
- the path to a local gem via ``source``."
+ desc "Ruby Gem support. If a URL is passed via ``source``, then that URL is used as the
+ remote gem repository; if a source is present but is not a valid URL, it will be
+ interpreted as the path to a local gem file. If source is not present at all,
+ the gem will be installed from the default gem repositories."
has_feature :versionable
@@ -65,20 +68,38 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package d
end
def install(useversion = true)
- command = ["install"]
- if (! @resource.should(:ensure).is_a? Symbol) and useversion
- command << "-v" << @resource.should(:ensure)
+ command = [command(:gemcmd), "install"]
+ if (! resource[:ensure].is_a? Symbol) and useversion
+ command << "-v" << resource[:ensure]
end
# Always include dependencies
command << "--include-dependencies"
- if source = @resource[:source]
- command << source
+ if source = resource[:source]
+ begin
+ uri = URI.parse(source)
+ rescue => detail
+ fail "Invalid source '%s': %s" % [uri, detail]
+ end
+
+ case uri.scheme
+ when nil:
+ # no URI scheme => interpret the source as a local file
+ command << source
+ when /file/i
+ command << uri.path
+ when 'puppet'
+ # we don't support puppet:// URLs (yet)
+ raise Puppet::Error.new("puppet:// URLs are not supported as gem sources")
+ else
+ # interpret it as a gem repository
+ command << "--source" << "#{source}" << resource[:name]
+ end
else
- command << @resource[:name]
+ command << resource[:name]
end
- output = gemcmd(*command)
+ output = execute(command)
# Apparently some stupid gem versions don't exit non-0 on failure
if output.include?("ERROR")
self.fail "Could not install: %s" % output.chomp
@@ -87,17 +108,17 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package d
def latest
# This always gets the latest version available.
- hash = self.class.gemlist(:justme => @resource[:name])
+ hash = self.class.gemlist(:justme => resource[:name])
return hash[:ensure]
end
def query
- self.class.gemlist(:justme => @resource[:name], :local => true)
+ self.class.gemlist(:justme => resource[:name], :local => true)
end
def uninstall
- gemcmd "uninstall", "-x", "-a", @resource[:name]
+ gemcmd "uninstall", "-x", "-a", resource[:name]
end
def update
diff --git a/spec/unit/provider/package/gem.rb b/spec/unit/provider/package/gem.rb
new file mode 100644
index 000000000..3dc1fa347
--- /dev/null
+++ b/spec/unit/provider/package/gem.rb
@@ -0,0 +1,87 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:package).provider(:gem)
+
+describe provider_class do
+ it "should have an install method" do
+ @provider = provider_class.new
+ @provider.should respond_to(:install)
+ end
+
+ describe "when installing" do
+ before do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns nil
+
+ # We have to set a name, though
+ @resource.stubs(:[]).with(:name).returns "myresource"
+ @resource.stubs(:[]).with(:ensure).returns :installed
+
+ @provider = provider_class.new
+ @provider.stubs(:resource).returns @resource
+ end
+
+ it "should use the path to the gem" do
+ provider_class.stubs(:command).with(:gemcmd).returns "/my/gem"
+ @provider.expects(:execute).with { |args| args[0] == "/my/gem" }.returns ""
+ @provider.install
+ end
+
+ it "should specify that the gem is being installed" do
+ @provider.expects(:execute).with { |args| args[1] == "install" }.returns ""
+ @provider.install
+ end
+
+ it "should specify that dependencies should be included" do
+ @provider.expects(:execute).with { |args| args[2] == "--include-dependencies" }.returns ""
+ @provider.install
+ end
+
+ it "should specify the package name" do
+ @provider.expects(:execute).with { |args| args[3] == "myresource" }.returns ""
+ @provider.install
+ end
+
+ describe "when a source is specified" do
+ describe "as a normal file" do
+ it "should use the file name instead of the gem name" do
+ @resource.stubs(:[]).with(:source).returns "/my/file"
+ @provider.expects(:execute).with { |args| args[3] == "/my/file" }.returns ""
+ @provider.install
+ end
+ end
+ describe "as a file url" do
+ it "should use the file name instead of the gem name" do
+ @resource.stubs(:[]).with(:source).returns "file:///my/file"
+ @provider.expects(:execute).with { |args| args[3] == "/my/file" }.returns ""
+ @provider.install
+ end
+ end
+ describe "as a puppet url" do
+ it "should fail" do
+ @resource.stubs(:[]).with(:source).returns "puppet://my/file"
+ lambda { @provider.install }.should raise_error(Puppet::Error)
+ end
+ end
+ describe "as a non-file and non-puppet url" do
+ it "should treat the source as a gem repository" do
+ @resource.stubs(:[]).with(:source).returns "http://host/my/file"
+ @provider.expects(:execute).with { |args| args[3..5] == ["--source", "http://host/my/file", "myresource"] }.returns ""
+ @provider.install
+ end
+ end
+ describe "with an invalid uri" do
+ it "should fail" do
+ URI.expects(:parse).raises(ArgumentError)
+ @resource.stubs(:[]).with(:source).returns "http:::::uppet:/:/my/file"
+ lambda { @provider.install }.should raise_error(Puppet::Error)
+ end
+ end
+ end
+ end
+end