#!/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 @curline = '' @global_settings = {} self end def parse_line(line) line.chomp! if line.empty? || line[0, 1] == '#' return end if line[-1, 1] == "\\" @curline.concat(line[0..-2]) next end line = @curline + line @curline = '' case line[/\S.+/] when /^\/(\S+)/ case $1 when 'set' $'.split.each {|setting| key, value, = setting.split(/=/) @global_settings[key] = value } when 'unset' $'.split.each {|setting| @global_settings.delete(setting)} else raise "invalid command \"#{$1}\"" end when '..' if @curlevel.pop.nil? raise '".." with no previous directory' end else spline = line.split() path = spline[0] settings = @global_settings.dup if spline.size > 1 spline[1..-1].each {|setting| key, value, = setting.split(/=/) settings[key] = value } end @paths.push(@curlevel + [path]) if settings['type'] == nil || settings['type'] == 'dir' @curlevel.push(path) 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