Handle existing symlinks gracefully (but don't delete existing non-links to be safe).
[lv2.git] / lv2includegen / lv2includegen.py
bloba27f1cd2fbfc04673c2bc562b3ff157361ca5a98
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
4 # lv2includegen, a tool to generate directory trees for including
5 # extension headers from source code.
7 __authors__ = 'David Robillard'
8 __license = 'GNU GPL v3 or later <http://www.gnu.org/licenses/gpl.html>'
9 __contact__ = 'devel@lists.lv2plug.in'
10 __date__ = '2010-10-05'
12 import errno
13 import glob
14 import os
15 import stat
16 import sys
18 import RDF
20 rdf = RDF.NS('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
21 lv2 = RDF.NS('http://lv2plug.in/ns/lv2core#')
23 def lv2_path():
24 "Return the LV2 search path (LV2_PATH)."
25 if 'LV2_PATH' in os.environ:
26 return os.environ['LV2_PATH']
27 else:
28 ret = '/usr/lib/lv2' + os.pathsep + '/usr/local/lib/lv2'
29 print 'LV2_PATH unset, using default ' + ret
30 return ret
32 def lv2_bundles(search_path):
33 "Return a list of all LV2 bundles found in a search path."
34 dirs = search_path.split(os.pathsep)
35 bundles = []
36 for dir in dirs:
37 bundles += glob.glob(os.path.join(dir, '*.lv2'))
38 return bundles
40 def usage():
41 script = os.path.basename(sys.argv[0])
42 print """Usage:
43 %s OUTDIR
45 OUTDIR : Directory to build include tree
47 Example:
48 %s /usr/local/include/lv2
49 """ % (script, script)
51 def mkdir_p(path):
52 "Equivalent of UNIX mkdir -p"
53 try:
54 os.makedirs(path)
55 except OSError as e:
56 if e.errno == errno.EEXIST:
57 pass
58 else:
59 raise
61 def lv2includegen(bundles):
62 """Build a directory tree of symlinks to LV2 extension bundles
63 for including header files using URI-like paths."""
64 for bundle in bundles:
65 # Load manifest into model
66 manifest = RDF.Model()
67 parser = RDF.Parser(name="guess")
68 parser.parse_into_model(manifest, 'file://' + os.path.join(bundle, 'manifest.ttl'))
70 # Query extension URI
71 results = manifest.find_statements(RDF.Statement(None, rdf.type, lv2.Specification))
72 for r in results:
73 ext_uri = str(r.subject.uri)
74 ext_path = os.path.normpath(ext_uri[ext_uri.find(':') + 1:].lstrip('/'))
75 ext_dir = os.path.join(outdir, ext_path)
77 # Make parent directories
78 mkdir_p(os.path.dirname(ext_dir))
80 # Remove existing symlink if necessary
81 if os.access(ext_dir, os.F_OK):
82 mode = os.lstat(ext_dir)[stat.ST_MODE]
83 if stat.S_ISLNK(mode):
84 os.remove(ext_dir)
85 else:
86 raise Exception(ext_dir + " exists and is not a link")
88 # Make symlink to bundle directory
89 os.symlink(bundle, ext_dir)
91 if __name__ == "__main__":
92 args = sys.argv[1:]
93 if len(args) != 1:
94 usage()
95 sys.exit(1)
97 outdir = args[0]
98 print "Building LV2 include tree at", outdir
100 lv2includegen(lv2_bundles(lv2_path()))