#!/usr/local/bin/ruby # pkg-plist generator by Brian Fundakowski Feldman # (public domain) # $FreeBSD$ class Plist def initialize(no_manpages = true, mtree = []) @no_manpages = no_manpages @mtree = mtree self end def make(dir) @root = dir.to_s + '/' imake('', 0, '') end private def imake(dir, level, prevwd) thiswd = prevwd + dir # always ends in '/' rootedwd = @root + thiswd subs = [] Dir.foreach(rootedwd) {|dirent| next if dirent =~ /^\.\.?$/ if test(?d, rootedwd + dirent) subs.concat(imake(dirent + '/', level + 1, thiswd)) else if thiswd !~ /^man\// || !@no_manpages subs.push(thiswd + dirent) end end } thiswd.chop! # Strip mtree-created directories if level > 0 && !@mtree.find {|x| x == thiswd} subs.push('@dirrm ' + thiswd) end return subs end end class Mtree def initialize(strip = 1) @paths = [] @curlevel = [] @strip = strip.to_i @cont = false self end def parse_line(line) line.chomp! spline = line.split oldcont = @cont @cont = line[-1, 1] == "\\" case spline[0] when nil when /^[\/#]/ # ignore "command" lines and comments when '..' if oldcont raise 'continued line has a .. directive?!' end if @curlevel.pop.nil? raise '".." with no previous directory' end else if !oldcont @curlevel.push(spline[0]) @paths.push(@curlevel.dup) end end self end def Mtree.read(filename) m = Mtree.new open(filename, 'r') {|file| file.each_line {|line| m.parse_line(line)} } m end def paths(strip = @strip) @paths.collect {|path| path[strip..-1].join('/')} end end if __FILE__ == $0 require 'getopts' if !getopts('Md', 'm:') || ARGV.size != 1 $stderr.print <<-USAGE_EOF usage: #{$0} [-Md] [-m mtree] somepath Generate a pkg-plist to stdout given a previously empty somepath which a port has been installed into (PREFIX=somepath). The mtree file is consulted to prevent base directories from being added to the plist. The -M argument allows manpages to be added to the plist. The -d argument puts all @dirrm commands at the end of the plist. USAGE_EOF exit 1 end mtree = $OPT_m || '/etc/mtree/BSD.local.dist' pl = Plist.new(!$OPT_M, Mtree.read(mtree).paths).make(ARGV[0]) if $OPT_d plnotdirrm = [] pldirrm = [] pl.each {|ent| if ent =~ /^@dirrm / pldirrm.push(ent) else plnotdirrm.push(ent) end plnotdirrm.sort! pldirrm.sort! pl = plnotdirrm + pldirrm.reverse } else pl.sort! end puts(pl.join("\n")) end