Remove references to the removed _scons_sets15.py module.
[scons.git] / src / test_strings.py
1 #!/usr/bin/env python
2 #
3 # __COPYRIGHT__
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #
24
25 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
26
27 """
28 Verify that we have proper strings like Copyright notices on all the
29 right files in our distributions.
30
31 Note that this is a source file and packaging test, not a functional test,
32 so the name of this script doesn't end in *Tests.py.
33 """
34
35 import fnmatch
36 import os
37 import os.path
38 import re
39
40 import TestCmd
41 import TestSCons
42
43 # Use TestCmd, not TestSCons, so we don't chdir to a temporary directory.
44 test = TestCmd.TestCmd()
45
46 scons_version = TestSCons.SConsVersion
47
48 def build_path(*args):
49     return os.path.join('build', *args)
50
51 build_scons     = build_path('scons')
52 build_local     = build_path('scons-local', 'scons-local-'+scons_version)
53 build_src       = build_path('scons-src')
54
55 class Checker:
56     def __init__(self, directory,
57                  search_list = [],
58                  remove_list = [],
59                  remove_patterns = []):
60         self.directory = directory
61         self.search_list = search_list
62         self.remove_dict = {}
63         for r in remove_list:
64             self.remove_dict[os.path.join(directory, r)] = 1
65         self.remove_patterns = remove_patterns
66
67     def directory_exists(self):
68         return os.path.exists(self.directory)
69
70     def remove_this(self, name, path):
71         if self.remove_dict.get(path):
72             return 1
73         else:
74             for pattern in self.remove_patterns:
75                 if fnmatch.fnmatch(name, pattern):
76                     return 1
77         return 0
78
79     def search_this(self, path):
80         if self.search_list:
81             for pattern in self.search_list:
82                 if fnmatch.fnmatch(path, pattern):
83                     return 1
84             return None
85         else:
86             return os.path.isfile(path)
87
88     def visit(self, result, dirname, names):
89         for name, path in [(n, os.path.join(dirname, n)) for n in names]:
90             if self.remove_this(name, path):
91                 names.remove(name)
92             elif self.search_this(path):
93                 body = open(path, 'r').read()
94                 for expr in self.expressions:
95                     if not expr.search(body):
96                         msg = '%s: missing %s' % (path, repr(expr.pattern))
97                         result.append(msg)
98
99     def find_missing(self):
100         result = []
101         os.path.walk(self.directory, self.visit, result)
102         return result
103
104 class CheckUnexpandedStrings(Checker):
105     expressions = [
106         re.compile('__COPYRIGHT__'),
107         re.compile('__FILE__ __REVISION__ __DATE__ __DEVELOPER__'),
108     ]
109     def must_be_built(self):
110         return None
111
112 class CheckPassTest(Checker):
113     expressions = [
114         re.compile(r'\.pass_test()'),
115     ]
116     def must_be_built(self):
117         return None
118
119 class CheckExpandedCopyright(Checker):
120     expressions = [
121         re.compile('Copyright.*The SCons Foundation'),
122     ]
123     def must_be_built(self):
124         return 1
125
126 check_list = [
127
128     CheckUnexpandedStrings(
129         'src',
130         search_list = [ '*.py' ],
131         remove_list = [
132             'engine/SCons/compat/_scons_optparse.py',
133             'engine/SCons/compat/_scons_sets.py',
134             'engine/SCons/compat/_scons_shlex.py',
135             'engine/SCons/compat/_scons_subprocess.py',
136             'engine/SCons/compat/_scons_textwrap.py',
137             'engine/SCons/Conftest.py',
138             'engine/SCons/dblite.py',
139         ],
140     ),
141
142     CheckUnexpandedStrings(
143         'test',
144         search_list = [ '*.py' ],
145     ),
146
147     CheckPassTest(
148         'test',
149         search_list = [ '*.py' ],
150         remove_list = [
151             'Fortran/common.py',
152         ],
153     ),
154
155     CheckExpandedCopyright(
156         build_scons,
157         remove_list = [
158             'build',
159             'build-stamp',
160             'configure-stamp',
161             'debian',
162             'dist',
163             'gentoo',
164             'engine/SCons/compat/_scons_optparse.py',
165             'engine/SCons/compat/_scons_sets.py',
166             'engine/SCons/compat/_scons_shlex.py',
167             'engine/SCons/compat/_scons_subprocess.py',
168             'engine/SCons/compat/_scons_textwrap.py',
169             'engine/SCons/Conftest.py',
170             'engine/SCons/dblite.py',
171             'MANIFEST',
172             'os_spawnv_fix.diff',
173             'setup.cfg',
174         ],
175         # We run epydoc on the *.py files, which generates *.pyc files.
176         remove_patterns = [
177             '*.pyc',
178         ]
179     ),
180
181     CheckExpandedCopyright(
182         build_local,
183         remove_list = [
184             'SCons/compat/_scons_optparse.py',
185             'SCons/compat/_scons_sets.py',
186             'SCons/compat/_scons_shlex.py',
187             'SCons/compat/_scons_subprocess.py',
188             'SCons/compat/_scons_textwrap.py',
189             'SCons/Conftest.py',
190             'SCons/dblite.py',
191             'scons-%s.egg-info' % scons_version,
192         ],
193     ),
194
195     CheckExpandedCopyright(
196         build_src,
197         remove_list = [
198             'bench/timeit.py',
199             'bin',
200             'config',
201             'debian',
202             'gentoo',
203             'doc/design',
204             'doc/MANIFEST',
205             'doc/python10',
206             'doc/reference',
207             'doc/developer/MANIFEST',
208             'doc/man/MANIFEST',
209             'doc/user/cons.pl',
210             'doc/user/MANIFEST',
211             'doc/user/SCons-win32-install-1.jpg',
212             'doc/user/SCons-win32-install-2.jpg',
213             'doc/user/SCons-win32-install-3.jpg',
214             'doc/user/SCons-win32-install-4.jpg',
215             'examples',
216             'gentoo',
217             'QMTest/classes.qmc',
218             'QMTest/configuration',
219             'QMTest/TestCmd.py',
220             'QMTest/TestCommon.py',
221             'QMTest/unittest.py',
222             'src/os_spawnv_fix.diff',
223             'src/MANIFEST.in',
224             'src/setup.cfg',
225             'src/engine/MANIFEST.in',
226             'src/engine/MANIFEST-xml.in',
227             'src/engine/setup.cfg',
228             'src/engine/SCons/compat/_scons_optparse.py',
229             'src/engine/SCons/compat/_scons_sets.py',
230             'src/engine/SCons/compat/_scons_shlex.py',
231             'src/engine/SCons/compat/_scons_subprocess.py',
232             'src/engine/SCons/compat/_scons_textwrap.py',
233             'src/engine/SCons/Conftest.py',
234             'src/engine/SCons/dblite.py',
235             'src/script/MANIFEST.in',
236             'src/script/setup.cfg',
237             'test/Fortran/.exclude_tests',
238             'timings/changelog.html',
239             'timings/graph.html',
240             'timings/index.html',
241         ],
242         remove_patterns = [
243             '*.js',
244         ]
245     ),
246
247 ]
248
249 missing_strings = []
250 not_built = []
251
252 for collector in check_list:
253     if collector.directory_exists():
254         missing_strings.extend(collector.find_missing())
255     elif collector.must_be_built():
256         not_built.append(collector.directory)
257
258 if missing_strings:
259     print "Found the following files with missing strings:"
260     print "\t" + "\n\t".join(missing_strings)
261     test.fail_test(1)
262
263 if not_built:
264     print "Cannot check all strings, the following have apparently not been built:"
265     print "\t" + "\n\t".join(not_built)
266     test.no_result(1)
267
268 test.pass_test()
269
270 # Local Variables:
271 # tab-width:4
272 # indent-tabs-mode:nil
273 # End:
274 # vim: set expandtab tabstop=4 shiftwidth=4: