#!/usr/bin/env ruby # == Synopsis # # uninstall: uninstalls pkgs from OSX # # == Usage # # uninstall --pkgpath /Library/Receipts/SomPackage-x.y.z.pkg [--prefix backup-prefix] # # -p, --pkgpath # path to package info # # -o, --prefix # location for backup dir # require 'Fileutils' require 'getoptlong' require 'rdoc/usage' class LsBomParser attr_reader :path, :mode, :uid, :gid, :size, :type def initialize(line) @line = line (@path,@mode,tmp,@size) = line.split(/\s+/, 5) (@uid, @gid) = tmp.split('/',2) if @size.empty? @type = 'd' else @type = 'f' end @path = '/' + @path end def to_s return @path end end class OSXPkg def initialize(pkgpath) @pkgpath = pkgpath end def get_contents() lsbom = IO.popen('/usr/bin/lsbom \'' + @pkgpath + '/Contents/Archive.bom\'') contents = Array.new lsbom.readlines.each do |l| contents.push(LsBomParser.new(l)) end tmp = Hash.new contents.each do |item| index = item.path.split('/').length tmp[index] = Array.new if tmp[index].nil? tmp[index].push(item) end ret = Array.new tmp.keys.sort.reverse.each do |index| ret.concat(tmp[index]) end return ret end end opts = GetoptLong.new( [ '--help', '-h', GetoptLong::NO_ARGUMENT ], [ '--pkgpath', '-p', GetoptLong::REQUIRED_ARGUMENT ], [ '--prefix', '-o', GetoptLong::REQUIRED_ARGUMENT ] ) pkgpath = nil prefix = nil opts.each do |opt, arg| case opt when '--help' RDoc::usage when '--pkgpath' pkgpath = arg.to_s when '--prefix' prefix = arg.to_s end end if pkgpath == nil puts "Missing pkgpath argument (try --help)" exit 0 end if prefix == nil prefix = ENV['HOME'] + '/' + File.basename(pkgpath) end OSXPkg.new(pkgpath).get_contents.each do |e| if e.type == 'f' dirname = File.dirname(e.path) FileUtils.mkdir_p("#{prefix}/#{dirname}") FileUtils.mv(e.path, "#{prefix}/#{e.path}") #FileUtils.rm "#{e.path}", :force => true puts "mkdir -p '#{prefix}/#{dirname}'" puts "mv '#{e.path}' '#{prefix}/#{e.path}'" #puts "rm -f -- '#{e.path}'" elsif e.type == 'd' and (Dir.entries(e.path).nitems == 2) Dir.unlink(e.path) puts "rmdir -- '#{e.path}'" end end # Move pkginfo folder to backup dir FileUtils.mkdir_p("#{prefix}/Library/Receipts") FileUtils.mv(pkgpath, "#{prefix}/Library/Receipts/#{File.basename(pkgpath)}") puts "mkdir -p #{prefix}/Library/Receipts" puts "mv #{pkgpath} #{prefix}/Library/Receipts/#{File.basename(pkgpath)}"