d7e662de4c
thus fixing the extra-@dirrm-problem once the base mtree files document the extra symlinks that are part of the local/etc. trees.
139 lines
3.0 KiB
Ruby
Executable File
139 lines
3.0 KiB
Ruby
Executable File
#!/usr/local/bin/ruby
|
|
# pkg-plist generator by Brian Fundakowski Feldman <green@FreeBSD.org>
|
|
# (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
|