23
23
# import system imports here
27
28
#import bzrlib specific imports here
28
from bzrlib.tests import TestCase
29
32
import bzrlib.branch
32
class TestApiUsage(TestCase):
33
from bzrlib.tests import TestCase, TestSkipped
36
# Files which are listed here will be skipped when testing for Copyright (or
38
COPYRIGHT_EXCEPTIONS = ['bzrlib/lsprof.py']
40
LICENSE_EXCEPTIONS = ['bzrlib/lsprof.py']
41
# Technically, 'bzrlib/lsprof.py' should be 'bzrlib/util/lsprof.py',
42
# (we do not check bzrlib/util/, since that is code bundled from elsewhere)
43
# but for compatibility with previous releases, we don't want to move it.
46
class TestSourceHelper(TestCase):
48
def source_file_name(self, package):
49
"""Return the path of the .py file for package."""
50
path = package.__file__
57
class TestApiUsage(TestSourceHelper):
34
59
def find_occurences(self, rule, filename):
35
60
"""Find the number of occurences of rule in a file."""
73
90
# drops, it is not given a buffer but rather this test updated
75
92
self.assertEqual(2, occurences)
95
class TestSource(TestSourceHelper):
97
def get_bzrlib_dir(self):
98
"""Get the path to the root of bzrlib"""
99
source = self.source_file_name(bzrlib)
100
source_dir = os.path.dirname(source)
102
# Avoid the case when bzrlib is packaged in a zip file
103
if not os.path.isdir(source_dir):
104
raise TestSkipped('Cannot find bzrlib source directory. Expected %s'
108
def get_source_files(self):
109
"""yield all source files for bzr and bzrlib"""
110
bzrlib_dir = self.get_bzrlib_dir()
112
# This is the front-end 'bzr' script
113
bzr_path = self.get_bzr_path()
116
for root, dirs, files in os.walk(bzrlib_dir):
118
if not f.endswith('.py'):
120
yield osutils.pathjoin(root, f)
122
def get_source_file_contents(self):
123
for fname in self.get_source_files():
124
f = open(fname, 'rb')
131
def is_copyright_exception(self, fname):
132
"""Certain files are allowed to be different"""
133
if '/util/' in fname:
134
# We don't require external utilities to be (C) Canonical Ltd
137
for exc in COPYRIGHT_EXCEPTIONS:
138
if fname.endswith(exc):
143
def is_license_exception(self, fname):
144
"""Certain files are allowed to be different"""
145
if '/util/' in fname:
146
# We don't require external utilities to be (C) Canonical Ltd
149
for exc in LICENSE_EXCEPTIONS:
150
if fname.endswith(exc):
155
def test_copyright(self):
156
"""Test that all .py files have a valid copyright statement"""
157
# These are files which contain a different copyright statement
161
copyright_re = re.compile('#\\s*copyright.*(?=\n)', re.I)
162
copyright_canonical_re = re.compile(
163
r'# Copyright \(C\) ' # Opening "# Copyright (C)"
164
r'(\d+)(, \d+)*' # Followed by a series of dates
165
r'.*Canonical Ltd' # And containing 'Canonical Ltd'
168
for fname, text in self.get_source_file_contents():
169
if self.is_copyright_exception(fname):
171
match = copyright_canonical_re.search(text)
173
match = copyright_re.search(text)
175
incorrect.append((fname, 'found: %s' % (match.group(),)))
177
incorrect.append((fname, 'no copyright line found\n'))
179
if 'by Canonical' in match.group():
180
incorrect.append((fname,
181
'should not have: "by Canonical": %s'
185
help_text = ["Some files have missing or incorrect copyright"
188
"Please either add them to the list of"
189
" COPYRIGHT_EXCEPTIONS in"
190
" bzrlib/tests/test_source.py",
191
# this is broken to prevent a false match
192
"or add '# Copyright (C)"
193
" 2006 Canonical Ltd' to these files:",
196
for fname, comment in incorrect:
197
help_text.append(fname)
198
help_text.append((' '*4) + comment)
200
self.fail('\n'.join(help_text))
203
"""Test that all .py files have a GPL disclaimer"""
207
# This program is free software; you can redistribute it and/or modify
208
# it under the terms of the GNU General Public License as published by
209
# the Free Software Foundation; either version 2 of the License, or
210
# (at your option) any later version.
212
# This program is distributed in the hope that it will be useful,
213
# but WITHOUT ANY WARRANTY; without even the implied warranty of
214
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
215
# GNU General Public License for more details.
217
# You should have received a copy of the GNU General Public License
218
# along with this program; if not, write to the Free Software
219
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
221
gpl_re = re.compile(re.escape(gpl_txt), re.MULTILINE)
223
for fname, text in self.get_source_file_contents():
224
if self.is_license_exception(fname):
226
if not gpl_re.search(text):
227
incorrect.append(fname)
230
help_text = ['Some files have missing or incomplete GPL statement',
232
"Please either add them to the list of"
233
" LICENSE_EXCEPTIONS in"
234
" bzrlib/tests/test_source.py",
235
"Or add the following text to the beginning:",
238
for fname in incorrect:
239
help_text.append((' '*4) + fname)
241
self.fail('\n'.join(help_text))