]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/status/boost_check_library.py
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / status / boost_check_library.py
1 #!/usr/bin/env python
2
3 # Copyright Rene Rivera 2016
4 #
5 # Distributed under the Boost Software License, Version 1.0.
6 # (See accompanying file LICENSE_1_0.txt or copy at
7 # http://www.boost.org/LICENSE_1_0.txt)
8
9 import os
10 import inspect
11 import optparse
12 import sys
13 import glob
14 import fnmatch
15 import json
16
17 class check_library():
18 '''
19 This is a collection of checks for a library to test if a library
20 follows the Boost C++ Libraries requirements and guidelines. It also
21 checks for possible and likely errors in the library.
22 '''
23
24 def __init__(self):
25 self.main()
26
27 def check_organization(self):
28 self.run_batch('check_organization_')
29
30 def check_organization_build(self):
31 if os.path.isdir(os.path.join(self.library_dir, 'build')):
32 self.assert_file_exists(os.path.join(self.library_dir, 'build'), self.jamfile,
33 '''
34 Did not find a Boost Build file in the [project-root]/build directory.
35 The library needs to provide a Boost Build project that the user,
36 and the top level Boost project, can use to build the library if it
37 has sources to build.
38 ''',
39 'org-build-ok')
40 if os.path.isdir(os.path.join(self.library_dir, 'src')):
41 self.assert_dir_exists(os.path.join(self.library_dir,'build'),
42 '''
43 Missing [project-root]/build directory. The [project-root]/build directory
44 is required for libraries that have a [project-root]/src directory.
45 ''',
46 'org-build-src')
47
48 def check_organization_doc(self):
49 self.assert_file_exists(self.library_dir, ['index.html'],
50 '''
51 Did not find [project-root]/index.html file.
52
53 The file is required for all libraries. Redirection to HTML documentation.
54 ''',
55 'org-doc-redir')
56 self.assert_dir_exists(os.path.join(self.library_dir,'doc'),
57 '''
58 Missing [project-root]/doc directory. The [project-root]/doc directory
59 is required for all libraries.
60
61 Sources to build with and built documentation for the library. If the
62 library needs to build documentation from non-HTML files this location
63 must be buildable with Boost Build.
64 ''',
65 'org-doc-dir')
66
67 def check_organization_include(self):
68 if os.path.isdir(os.path.join(self.library_dir,'include','boost',self.library_name)):
69 self.warn_file_exists(os.path.join(self.library_dir,'include','boost'), ['*.h*'],
70 '''
71 Found extra files in [project-root]/include/boost directory.
72 ''',
73 'org-inc-extra',
74 negate = True,
75 globs_to_exclude = ['%s.h*'%(self.library_name)])
76 else:
77 self.warn_file_exists(os.path.join(self.library_dir,'include','boost'), ['%s.h*'%(self.library_name)],
78 '''
79 Did not find [project-root]/include/boost/[library].h* file.
80
81 A single header for the library is suggested at [project-root]/include/boost/[library].h*
82 if the library does not have a header directory at [project-root]/include/boost/[library].
83 ''',
84 'org-inc-one')
85
86 def check_organization_meta(self):
87 parent_dir = os.path.dirname(self.library_dir)
88 # If this is a sublibrary it's possible that the library information is the
89 # parent library's meta/libraries.json. Otherwise it's a regular library
90 # and structure.
91 if not self.test_dir_exists(os.path.join(self.library_dir,'meta')) \
92 and self.test_file_exists(os.path.join(parent_dir,'meta'),['libraries.json']):
93 if self.get_library_meta():
94 return
95 self.assert_file_exists(os.path.join(self.library_dir, 'meta'), ['libraries.json'],
96 '''
97 Did not find [project-root]/meta/libraries.json file, nor did
98 [super-project]/meta/libraries.json contain an entry for the sublibrary.
99
100 The file is required for all libraries. And contains information about
101 the library used to generate website and documentation for the
102 Boost C++ Libraries collection.
103 ''',
104 'org-meta-libs')
105 elif self.assert_dir_exists(os.path.join(self.library_dir,'meta'),
106 '''
107 Missing [project-root]/meta directory. The [project-root]/meta directory
108 is required for all libraries.
109 ''',
110 'org-meta-dir'):
111 self.assert_file_exists(os.path.join(self.library_dir, 'meta'), ['libraries.json'],
112 '''
113 Did not find [project-root]/meta/libraries.json file.
114
115 The file is required for all libraries. And contains information about
116 the library used to generate website and documentation for the
117 Boost C++ Libraries collection.
118 ''',
119 'org-meta-libs')
120
121 def check_organization_test(self):
122 if self.assert_dir_exists(os.path.join(self.library_dir,'test'),
123 '''
124 Missing [project-root]/test directory. The [project-root]/test directory
125 is required for all libraries.
126
127 Regression or other test programs or scripts. This is the only location
128 considered for automated testing. If you have additional locations that
129 need to be part of automated testing it is required that this location
130 refer to the additional test locations.
131 ''',
132 'org-test-dir'):
133 self.assert_file_exists(os.path.join(self.library_dir, 'test'), self.jamfile,
134 '''
135 Did not find a Boost Build file in the [project-root]/test directory.
136 ''',
137 'org-test-ok')
138
139 def main(self):
140 commands = [];
141 for method in inspect.getmembers(self, predicate=inspect.ismethod):
142 if method[0].startswith('check_'):
143 commands.append(method[0][6:].replace('_','-'))
144 commands = "commands: %s" % ', '.join(commands)
145
146 opt = optparse.OptionParser(
147 usage="%prog [options] [commands]",
148 description=commands)
149 opt.add_option('--boost-root')
150 opt.add_option('--library')
151 opt.add_option('--jamfile')
152 opt.add_option('--debug', action='store_true')
153 self.boost_root = None
154 self.library = None
155 self.jamfile = None
156 self.debug = False
157 ( _opt_, self.actions ) = opt.parse_args(None,self)
158
159 self.library_dir = os.path.join(self.boost_root, self.library)
160 self.error_count = 0;
161 self.jamfile = self.jamfile.split(';')
162 self.library_name = self.library.split('/',1)[1] #os.path.basename(self.library)
163 self.library_key = self.library.split('/',1)[1]
164
165 if self.debug:
166 print ">>> cwd: %s"%(os.getcwd())
167 print ">>> actions: %s"%(self.actions)
168 print ">>> boost_root: %s"%(self.boost_root)
169 print ">>> library: %s"%(self.library)
170 print ">>> jamfile: %s"%(self.jamfile)
171
172 for action in self.actions:
173 action_m = "check_"+action.replace('-','_')
174 if hasattr(self,action_m):
175 getattr(self,action_m)()
176
177 def run_batch(self, action_base, *args, **kargs):
178 for method in inspect.getmembers(self, predicate=inspect.ismethod):
179 if method[0].startswith(action_base):
180 getattr(self,method[0])(*args, **kargs)
181
182 def get_library_meta(self):
183 '''
184 Fetches the meta data for the current library. The data could be in
185 the superlib meta data file. If we can't find the data None is returned.
186 '''
187 parent_dir = os.path.dirname(self.library_dir)
188 if self.test_file_exists(os.path.join(self.library_dir,'meta'),['libraries.json']):
189 with open(os.path.join(self.library_dir,'meta','libraries.json'),'r') as f:
190 meta_data = json.load(f)
191 if isinstance(meta_data,list):
192 for lib in meta_data:
193 if lib['key'] == self.library_key:
194 return lib
195 elif 'key' in meta_data and meta_data['key'] == self.library_key:
196 return meta_data
197 if not self.test_dir_exists(os.path.join(self.library_dir,'meta')) \
198 and self.test_file_exists(os.path.join(parent_dir,'meta'),['libraries.json']):
199 with open(os.path.join(parent_dir,'meta','libraries.json'),'r') as f:
200 libraries_json = json.load(f)
201 if isinstance(libraries_json,list):
202 for lib in libraries_json:
203 if lib['key'] == self.library_key:
204 return lib
205 return None
206
207 def error(self, reason, message, key):
208 self.error_count += 1
209 print("%s: error: %s; %s <<%s>>"%(
210 self.library,
211 self.clean_message(reason),
212 self.clean_message(message),
213 key,
214 ))
215
216 def warn(self, reason, message, key):
217 print("%s: warning: %s; %s <<%s>>"%(
218 self.library,
219 self.clean_message(reason),
220 self.clean_message(message),
221 key,
222 ))
223
224 def info(self, message):
225 if self.debug:
226 print("%s: info: %s"%(self.library, self.clean_message(message)))
227
228 def clean_message(self, message):
229 return " ".join(message.strip().split())
230
231 def assert_dir_exists(self, dir, message, key, negate = False):
232 self.info("check directory '%s', negate = %s"%(dir,negate))
233 if os.path.isdir(dir):
234 if negate:
235 self.error("directory found", message, key)
236 return False
237 else:
238 if not negate:
239 self.error("directory not found", message, key)
240 return False
241 return True
242
243 def warn_dir_exists(self, dir, message, key, negate = False):
244 self.info("check directory '%s', negate = %s"%(dir,negate))
245 if os.path.isdir(dir):
246 if negate:
247 self.warn("directory found", message, key)
248 return False
249 else:
250 if not negate:
251 self.warn("directory not found", message, key)
252 return False
253 return True
254
255 def assert_file_exists(self, dir, globs_to_include, message, key, negate = False, globs_to_exclude = []):
256 found = self.test_file_exists(dir, globs_to_include = globs_to_include, globs_to_exclude = globs_to_exclude)
257 if negate:
258 if found:
259 self.error("file found", message, key)
260 return False
261 else:
262 if not found:
263 self.error("file not found", message, key)
264 return False
265 return True
266
267 def warn_file_exists(self, dir, globs_to_include, message, key, negate = False, globs_to_exclude = []):
268 found = self.test_file_exists(dir, globs_to_include = globs_to_include, globs_to_exclude = globs_to_exclude)
269 if negate:
270 if found:
271 self.warn("file found", message, key)
272 return False
273 else:
274 if not found:
275 self.warn("file not found", message, key)
276 return False
277 return True
278
279 def test_dir_exists(self, dir):
280 return os.path.isdir(dir)
281
282 def test_file_exists(self, dir, globs_to_include, globs_to_exclude = []):
283 self.info("test file(s) in dir '%s', include = '%s', exclude = %s"%(dir,globs_to_include,globs_to_exclude))
284 found = False
285 if os.path.isdir(dir):
286 for g in globs_to_include:
287 for f in glob.iglob(os.path.join(dir,g)):
288 exclude = False
289 for ge in globs_to_exclude:
290 if fnmatch.fnmatch(os.path.basename(f),ge):
291 exclude = True
292 found = not exclude
293 if found:
294 break
295 return found
296
297 if check_library().error_count > 0:
298 sys.exit(1)
299