summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-07-03 20:06:32 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-07-03 20:06:32 +0000
commite57c5131aee017bd015e9419b5a1ceeb306677a7 (patch)
tree597984120e13b03bd96017afb84a050a728e17ea
parent25cf31b00057d552fcffde568049e37655c31fbc (diff)
Adding Ruby Gem support to packaging
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1354 980ebf18-57e1-0310-9a29-db15c13687c0
-rw-r--r--lib/puppet/type/package.rb48
-rwxr-xr-xlib/puppet/type/package/gem.rb119
-rw-r--r--test/types/package.rb80
3 files changed, 203 insertions, 44 deletions
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index ba0b307d1..58afe2c1c 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -60,6 +60,10 @@ module Puppet
mod.module_eval(&block)
+ class << mod
+ include Puppet::Util
+ end
+
# It's at least conceivable that a module would not define this method
# "module_function" makes the :list method private, so if the parent
# method also called module_function, then it's already private
@@ -575,50 +579,6 @@ module Puppet
end
end
end # Puppet.type(:package)
-
- # this is how we retrieve packages
- class PackageSource
- attr_accessor :uri
- attr_writer :retrieve
-
- @@sources = Hash.new(false)
-
- def PackageSource.get(file)
- type = file.sub(%r{:.+},'')
- source = nil
- if source = @@sources[type]
- return source.retrieve(file)
- else
- raise Puppet::Error, "Unknown package source: %s" % type
- end
- end
-
- def initialize(name)
- if block_given?
- yield self
- end
-
- @@sources[name] = self
- end
-
- def retrieve(path)
- @retrieve.call(path)
- end
-
- end
-
- PackageSource.new("file") { |obj|
- obj.retrieve = proc { |path|
- # this might not work for windows...
- file = path.sub(%r{^file://},'')
-
- if FileTest.exists?(file)
- return file
- else
- raise Puppet::Error, "File %s does not exist" % file
- end
- }
- }
end
# $Id$
diff --git a/lib/puppet/type/package/gem.rb b/lib/puppet/type/package/gem.rb
new file mode 100755
index 000000000..3763cf992
--- /dev/null
+++ b/lib/puppet/type/package/gem.rb
@@ -0,0 +1,119 @@
+module Puppet
+ Puppet.type(:package).newpkgtype(:gem) do
+ if gem = %x{which gem 2>/dev/null}.chomp and gem != ""
+ @@gem = gem
+ else
+ @@gem = nil
+ end
+
+ def self.extended(mod)
+ unless @@gem
+ raise Puppet::Error, "The gem command is missing; gems unavailable"
+ end
+ end
+
+ def gemlist(hash)
+ command = "#{@@gem} list "
+
+ if hash[:local]
+ command += "--local "
+ else
+ command += "--remote "
+ end
+
+ if hash[:justme]
+ command += self[:name]
+ end
+ begin
+ list = execute(command).split("\n\n").collect do |set|
+ if gemhash = gemsplit(set)
+ gemhash[:type] = :gem
+ gemhash[:ensure] = gemhash[:version][0]
+ gemhash
+ else
+ nil
+ end
+ end.reject { |p| p.nil? }
+ rescue ExecutionFailure => detail
+ raise Puppet::Error, "Could not list gems: %s" % detail
+ end
+
+ if hash[:justme]
+ return list.shift
+ else
+ return list
+ end
+ end
+
+ module_function :gemlist
+
+ def gemsplit(desc)
+ case desc
+ when /^\*\*\*/: return nil
+ when /^(\S+)\s+\((.+)\)\n/
+ name = $1
+ version = $2.split(/,\s*/)
+ return {
+ :name => name,
+ :version => version
+ }
+ else
+ Puppet.warning "Could not match %s" % desc
+ nil
+ end
+ end
+
+ module_function :gemsplit
+
+ def install(useversion = true)
+ command = "#{@@gem} install "
+ if self[:version] and useversion
+ command += "-v %s " % self[:version]
+ end
+ if source = self[:source]
+ command += source
+ else
+ command += self[:name]
+ end
+ begin
+ execute(command)
+ rescue ExecutionFailure => detail
+ raise Puppet::Error, "Could not install %s: %s" %
+ [self[:name], detail]
+ end
+ end
+
+ def latest
+ # This always gets the latest version available.
+ hash = gemlist(:justme => true)
+
+ return hash[:version][0]
+ end
+
+ def list(justme = false)
+ gemlist(:local => true).each do |hash|
+ Puppet::Type.type(:package).installedpkg(hash)
+ end
+ end
+
+ def query
+ gemlist(:justme => true, :local => true)
+ end
+
+ def uninstall
+ begin
+ # Remove everything, including the binaries.
+ execute("#{@@gem} uninstall -x -a #{self[:name]}")
+ rescue ExecutionFailure => detail
+ raise Puppet::Error, "Could not uninstall %s: %s" %
+ [self[:name], detail]
+ end
+ end
+
+ def update
+ self.install(false)
+ end
+ end
+end
+
+# $Id$
diff --git a/test/types/package.rb b/test/types/package.rb
index e52d2384f..c6758885e 100644
--- a/test/types/package.rb
+++ b/test/types/package.rb
@@ -385,6 +385,86 @@ class TestPackages < Test::Unit::TestCase
assert(FileTest.exists?("/tmp/pkgtesting/file"), "File did not get created")
end
end
+
+ # Yay, gems. They're special because any OS can test them.
+ if %x{which gem 2>/dev/null}.chomp != ""
+ def test_list_gems
+ gems = nil
+ assert_nothing_raised {
+ gems = Puppet::Type.type(:package).pkgtype(:gem).list
+ }
+
+ gems.each do |gem|
+ assert_equal(:gem, gem[:type],
+ "Type was not set correctly")
+ end
+ end
+
+ def test_install_gems
+ gem = nil
+ name = "wxrubylayouts"
+ assert_nothing_raised {
+ gem = Puppet::Type.newpackage(
+ :name => name,
+ :version => "0.0.2",
+ :ensure => "installed",
+ :type => :gem
+ )
+ }
+
+ assert_nothing_raised {
+ gem.retrieve
+ }
+
+ if gem.is(:ensure) == :installed
+ $stderr.puts "Cannot test gem installation; %s is already installed" %
+ name
+ end
+
+ assert_events([:package_created], gem)
+
+ assert_nothing_raised {
+ gem.retrieve
+ }
+
+ assert_equal("0.0.2", gem.is(:ensure),
+ "Incorrect version was installed")
+
+ latest = nil
+ assert_nothing_raised {
+ latest = gem.latest
+ }
+
+ assert(latest != gem[:version], "Did not correctly find latest value")
+
+ gem[:ensure] = :latest
+ assert_events([:package_changed], gem)
+
+ gem.retrieve
+
+ assert("0.0.2" != gem.is(:ensure),
+ "Package was not updated.")
+
+ gem[:ensure] = :absent
+
+ assert_events([:package_removed], gem)
+ end
+
+ else
+ def test_nogems_nofailures
+ obj = nil
+ assert_nothing_raised do
+ Puppet::Type.newpackage(
+ :name => "yayness",
+ :type => "gem",
+ :ensure => "installed"
+ )
+ end
+
+ assert_nil(Puppet::Type.type(:package)["yayness"],
+ "Invalid gem package got created")
+ end
+ end
end
if ["Fedora", "RedHat", "CentOS"].include?(Facter["operatingsystem"].value) and
FileTest.exists?("/home/luke/rpm/RPMS/i386/puppet-server-0.16.1-1.i386.rpm")