Commits

Martin Tournoij committed d909bb4

Hello, world

Comments (0)

Files changed (1)

+#!/usr/bin/env python
+#
+# You are free to use, modify, and distribute as you see fit. There are no
+# restrictions.
+#
+# Martin Tournoij <martin@arp242.net>
+# 
+# plist.py:
+# Make a pkg-plist file for a FreeBSD port, with as little (or none!) manual
+# intervention as possible.
+#
+
+import getopt
+import os
+import re
+import subprocess
+import sys
+
+mtree = ''
+options = ''
+
+def Usage():
+	print "plist.py 1.1 by Martin Tournoij <carpetsmoker@rwxrwxrwx.net>"
+	print ""
+	print "Usage: %s [-hdn] [-p portdir] [-x prefix]" % sys.argv[0]
+	print ""
+	print "\t-x, --prefix\tTemporary prefix to use (Default: /var/tmp/ptest)."
+	print "\t-h, --help\tPrint this help message and exit."
+	print "\t-p, --portdir\tPort directory (Default: current directory)."
+	print "\t-d, --noportdocs\tDo not prefix entries in %%DOCSDIR%% with %%PORTDOCS%%."
+	print "\t-e, --noportexamples\tDo not prefix entries in %%EXAMPLESSDIR%% with %%PORTEAMPLES%%."
+	print "\t-i, --ignoredoc\tIgnore all entries in %%DOCSDIR%% (if you use"
+	print "\t\t\tPORTDOCS in the Makefile)."
+	print "\t-s, --skip\tSkip these variables. Comma separated w/o spaces."
+	print ""
+	print "Basic usage:"
+	print "  1) Make your port, build it with PREFIX set to /var/tmp/ptest/ or"
+	print "     another *empty* directory of your choice."
+	print "  2) cd to your port's directory (i.e. /usr/ports/cat/port)"
+	print "  3) Run this."
+	print ""
+
+def GetOptions():
+	# Get options
+	try:
+		options, arguments = getopt.getopt(sys.argv[1:], 'hp:x:deis',
+			['help=', 'portdir=', 'prefix=', 'noportdocs', 'noportexamples',
+				'ignoredoc', 'skip'])
+	except getopt.GetoptError:
+		msg, opt = sys.exc_info()[1]
+		print msg + "\n"
+		Usage()
+		sys.exit()
+
+	# The default options
+	defaults = {
+		'portdir': os.getcwd(),
+		'prefix': '/var/tmp/ptest/',
+		'noportdocs': False,
+		'noportexamples': False,
+		'ignoreportdocs': False,
+		'skip': ['LIB32DIR', 'XAWVER', 'OSREL', 'PREFIX']
+	}
+
+	for opt, arg in options:
+		if opt == '-h' or opt == '--help':
+			Usage()
+			sys.exit()
+		if opt == '-p' or opt == '--portdir':
+			defaults['portdir'] = arg
+		if opt == '-x' or opt == '--prefix':
+			defaults['prefix'] = arg
+		if opt == '-d' or opt == '--noportdocs':
+			defaults['noportdocs'] = True
+		if opt == '-e' or opt == '--noportexamples':
+			defaults['noportexamples'] = True
+		if opt == '-i' or opt == '--ignoredoc':
+			defaults['ignoredoc'] = True
+		if opt == '-s' or opt == '--skip':
+			defaults['skip'].extend(arg.split(','))
+
+	# Check for a valid portdir and make prefix if needed
+	if not os.path.exists('%s/Makefile' % defaults['portdir']):
+		print 'Error: Unable to find a Makefile in the portdir "%s"' % defaults['portdir']
+		Usage()
+		sys.exit(1)
+
+	if not os.path.exists(defaults['prefix']):
+		try:
+			os.makedirs(defaults['prefix'])
+		except IOError:
+			print 'Error: Unable to create prefix directory "%s"\n%s' % (mkdir, sys.exc_info()[1])
+			sys.exit(1)
+
+	return defaults
+
+def GetMtree(mtree):
+	# Read mtree file 
+
+	retlist = [ ]
+	prev_prefix = ''
+	mtree = open(mtree)
+	regexp = re.compile('\s+[\w\=]*$')
+	
+	# Skip entries which are unimportant to us.
+	for line in mtree:
+		if line[0] == '#' or line[0] == '/' or line == '.\n' or line == '\n':
+			continue
+
+		# Remove all flags, we don't need them.
+		line = regexp.sub('', line.lstrip())
+		line = line.strip()
+
+		if line == '..':
+			(cur_prefix, a) = os.path.split(prev_prefix)
+			prev_prefix = cur_prefix
+		else:
+			cur_prefix = os.path.join(prev_prefix, line)
+			prev_prefix = cur_prefix
+			if cur_prefix[:2] == './':
+				cur_prefix = cur_prefix[2:]
+			retlist.append(cur_prefix)
+	
+	mtree.close()
+
+	return retlist
+
+def GetTree(prefix, prev, d, f):
+	# Return recursive list of files and dirs
+	global options
+
+	for file in os.listdir(os.path.join(prefix, prev)):
+		# Skip these files/dirs, they're added automatically
+		if prev[:3] == 'man':
+			continue
+		if options['ignoreportdocs'] and prev.find('share/doc') != -1:
+			continue
+
+		path = os.path.join(prev, file)
+		if os.path.isdir(os.path.join(prefix, path)):
+			if CheckDir(path):
+				d.append('@dirrm ' + path)
+			GetTree(prefix, path, d, f)
+		else:
+			f.append(path)
+	return d, f
+
+def CheckDir(path):
+	# Check if dir is in mtree
+
+	global mtree
+
+	for m in mtree:
+		if path == m:
+			return False
+		else:
+			continue
+	return True
+
+def GetVars():
+	# Get a list of substitution vars.
+	global options
+	
+	try:
+		plist_sub = subprocess.Popen(['make', '-V', 'PLIST_SUB'],
+			stdout=subprocess.PIPE).communicate()[0].strip()
+	except OSError:
+		print "Problems running make -V:\n%s" % sys.exc_info()[1]
+		sys.exit(1)
+
+	vars = []
+	for v in plist_sub.split(' '):
+		if not v:
+			continue
+		try:
+			key, val = v.split('=')
+		except:
+			continue
+
+		if val[0] == '"' and val[len(val)-1] == '"':
+			val = val[1:-1]
+		if val == '':
+			continue
+		try:
+			options['skip'].index(key)
+		except ValueError:
+			vars.append((val, key))
+
+	# XXX Try to sanitize the replacement order.
+	vars.sort()
+
+	return vars
+
+def ReplaceSub(path, vars, dir=False):
+	global options
+
+	for search, replace in vars:
+		path = path.replace(search, '%%' + replace + '%%')
+	
+	if not options['noportdocs']:
+		if path.find('%%DOCSDIR%%') != -1:
+			path = '%%PORTDOCS%%' + path
+
+	if not options['noportexamples']:
+		if path.find('%%EXAMPLESDIR%%') != -1:
+			path = '%%PORTEXAMPLES%%' + path
+
+	return path
+
+def main():
+	global mtree
+	global options
+
+	options = GetOptions()
+	os.chdir(options['portdir'])
+	vars = GetVars()
+	mtree = GetMtree('/usr/ports/Templates/BSD.local.dist')
+	
+	if os.path.exists('/usr/local/etc/mtree/BSD.gnome.dist'):
+		mtree.extend(GetMtree('/usr/local/etc/mtree/BSD.gnome.dist'))
+
+	#import pprint
+	#mtree.sort()
+	#pprint.pprint( mtree)
+
+	(dirlist, filelist) = GetTree(options['prefix'], '', [], [])
+	dirlist.reverse()
+
+	for f in filelist:
+		print ReplaceSub(f, vars)
+
+	for d in dirlist:
+		print ReplaceSub(d, vars, dir=True)
+
+if __name__ == '__main__':
+	main()