-
Notifications
You must be signed in to change notification settings - Fork 20
/
clib.py
183 lines (140 loc) · 5.11 KB
/
clib.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/usr/bin/env python
# encoding: utf-8
# Willem-Hendrik Thiart, 2014
from waflib.Configure import conf
import json
import os
import itertools
# TODO
# Add exception for instances where there are multiple packages with same name
class PackageNotFoundException(Exception):
pass
class ClibPackage(object):
pass
def build(ctx):
ctx.clib_index()
def unionsets_if_list(func):
def func_wrapper(self, package, **kwargs):
if isinstance(package, list):
s = set()
for p in package:
s.update(func(self, p, **kwargs))
return list(s)
else:
return func(self, package, **kwargs)
return func_wrapper
@unionsets_if_list
def _clib_h_files(self, package, include_deps=True):
files = filter(lambda x: x.endswith(".h"), self.clib_manifest(package)['src'])
files = map(lambda x: '{0}{1}'.format(self.clib_path(package), os.path.basename(x)), files)
if include_deps:
deps = self.clib_dependencies(package)
files.extend(itertools.chain.from_iterable([self.clib_h_files(pkg) for pkg in deps]))
return list(set(files))
@unionsets_if_list
def _clib_c_files(self, package, include_deps=True):
files = filter(lambda x: x.endswith(".c"), self.clib_manifest(package)['src'])
files = map(lambda x: '{0}{1}'.format(self.clib_path(package), os.path.basename(x)), files)
if include_deps:
deps = self.clib_dependencies(package)
files.extend(itertools.chain.from_iterable([self.clib_c_files(pkg) for pkg in deps]))
return list(set(files))
@conf
def clib_h_files(self, package, include_deps=True):
""" Return all header files from package
Parameters
----------
package : string or list of strings
The package (repo or name) to get header files from.
This can be a list of packages.
include_deps: boolean
Whether or not to include package depedencies
"""
return _clib_h_files(self, package, include_deps=include_deps)
@conf
def clib_c_files(self, package, include_deps=True):
""" Return all c files from package
Parameters
----------
package : string or list of strings
The package (repo or name) to get c files from.
This can be a list of packages.
include_deps: boolean
Whether or not to include package depedencies
"""
return _clib_c_files(self, package, include_deps=include_deps)
@unionsets_if_list
def _clib_h_paths(self, package, include_deps=True):
paths = set([self.clib_path(package)])
if include_deps:
deps = self.clib_dependencies(package)
paths.update(itertools.chain.from_iterable([self.clib_paths(pkg) for pkg in deps]))
return paths
@conf
def clib_h_paths(self, package, include_deps=True):
""" Return all paths that contain h files from package
Parameters
----------
package : string or list of strings
The package (repo or name) to get h paths from.
This can be a list of packages.
include_deps: boolean
Whether or not to include package depedencies
"""
return list(set([h[:h.rfind('/')]
for h in self.clib_h_files(package, include_deps=include_deps)]))
@conf
def clib_path(self, package):
""" Return package path
Parameters
----------
package : string
The package (repo or name) to get the path from.
"""
#return '{0}/{1}/'.format(os.getcwd(), self.clib_get(package).path)
return '{0}/'.format(self.clib_get(package).path)
@conf
def clib_index(self):
""" Read package.json files inside deps folder """
self.packages_by_name = {}
self.packages_by_repo = {}
for dirname, dirnames, filenames in os.walk('deps/'):
if 'package.json' in filenames:
pkg = ClibPackage()
pkg.path = dirname
json_data = open("{0}/package.json".format(pkg.path))
pkg.manifest = json.load(json_data)
json_data.close()
self.packages_by_repo[pkg.manifest['repo']] = pkg
self.packages_by_name[pkg.manifest['name']] = pkg
@conf
def clib_manifest(self, package):
""" Return the dictionary contents of package.json file
Parameters
----------
package : string
The package (repo or name) to get the manifset from.
"""
return self.clib_get(package).manifest
@conf
def clib_dependencies(self, package):
""" Return a package's dependecies (repo name)
Parameters
----------
package : string
The package (repo or name) to get the depedencies from.
"""
deps = set()
for dep in self.clib_manifest(package).get('dependencies', {}).iterkeys():
deps.add(dep)
for d in self.clib_dependencies(dep):
deps.add(d)
return deps
@conf
def clib_get(self, package):
""" Return package object """
if package in self.packages_by_name:
return self.packages_by_name[package]
elif package in self.packages_by_repo:
return self.packages_by_repo[package]
raise PackageNotFoundException(package)