|
1 |
|
2 # This Source Code Form is subject to the terms of the Mozilla Public |
|
3 # License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
5 |
|
6 import unittest |
|
7 import os.path |
|
8 |
|
9 parent = os.path.dirname |
|
10 test_dir = parent(os.path.abspath(__file__)) |
|
11 sdk_root = parent(parent(parent(test_dir))) |
|
12 |
|
13 def from_sdk_top(fn): |
|
14 return os.path.abspath(os.path.join(sdk_root, fn)) |
|
15 |
|
16 MPL2_URL = "http://mozilla.org/MPL/2.0/" |
|
17 |
|
18 # These files all come with their own license headers |
|
19 skip = [ |
|
20 "python-lib/cuddlefish/_version.py", # generated, public domain |
|
21 "doc/static-files/js/jquery.js", # MIT/GPL dual |
|
22 "examples/annotator/data/jquery-1.4.2.min.js", # MIT/GPL dual |
|
23 "examples/reddit-panel/data/jquery-1.4.4.min.js", # MIT/GPL dual |
|
24 "examples/library-detector/data/library-detector.js", # MIT |
|
25 "python-lib/mozrunner/killableprocess.py", # MIT? BSDish? |
|
26 "python-lib/mozrunner/winprocess.py", # MIT |
|
27 "packages/api-utils/tests/test-querystring.js", # MIT |
|
28 "packages/api-utils/lib/promise.js", # MIT |
|
29 "packages/api-utils/tests/test-promise.js", # MIT |
|
30 ] |
|
31 absskip = [from_sdk_top(os.path.join(*fn.split("/"))) for fn in skip] |
|
32 |
|
33 class Licenses(unittest.TestCase): |
|
34 def test(self): |
|
35 # Examine most SDK files to check if they've got an MPL2 license |
|
36 # header. We exclude some files that are known to include different |
|
37 # licenses. |
|
38 self.missing = [] |
|
39 self.scan_file(from_sdk_top(os.path.join("python-lib", "jetpack_sdk_env.py"))) |
|
40 self.scan(os.path.join("python-lib", "cuddlefish"), [".js", ".py"], |
|
41 skipdirs=["sdk-docs"], # test_generate.py makes this |
|
42 ) |
|
43 self.scan(os.path.join("python-lib", "mozrunner"), [".py"]) |
|
44 |
|
45 for sdk_package in ["addon-kit", "api-utils", "test-harness"]: |
|
46 self.scan(os.path.join("packages", sdk_package), |
|
47 [".js", ".py", ".md"]) |
|
48 self.scan("examples", [".js", ".css", ".html", ".md"]) |
|
49 self.scan("bin", [".bat", ".ps1"]) |
|
50 for fn in [os.path.join("bin", "activate"), |
|
51 os.path.join("bin", "cfx"), |
|
52 os.path.join("bin", "integration-scripts", "buildbot-run-cfx-helper"), |
|
53 os.path.join("bin", "integration-scripts", "integration-check"), |
|
54 ]: |
|
55 self.scan_file(from_sdk_top(fn)) |
|
56 self.scan("doc", [".js", ".css", ".md"], skipdirs=["syntaxhighlighter"]) |
|
57 |
|
58 if self.missing: |
|
59 print |
|
60 print "The following files are missing an MPL2 header:" |
|
61 for fn in sorted(self.missing): |
|
62 print " "+fn |
|
63 self.fail("%d files are missing an MPL2 header" % len(self.missing)) |
|
64 |
|
65 def scan(self, start, extensions=[], skipdirs=[]): |
|
66 # scan a whole subdirectory |
|
67 start = from_sdk_top(start) |
|
68 for root, dirs, files in os.walk(start): |
|
69 for d in skipdirs: |
|
70 if d in dirs: |
|
71 dirs.remove(d) |
|
72 for fn in files: |
|
73 ext = os.path.splitext(fn)[1] |
|
74 if extensions and ext not in extensions: |
|
75 continue |
|
76 absfn = os.path.join(root, fn) |
|
77 if absfn in absskip: |
|
78 continue |
|
79 self.scan_file(absfn) |
|
80 |
|
81 def scan_file(self, fn): |
|
82 # scan a single file |
|
83 if not MPL2_URL in open(fn, "r").read(): |
|
84 relfile = fn[len(sdk_root)+1:] |
|
85 self.missing.append(relfile) |
|
86 |
|
87 if __name__ == '__main__': |
|
88 unittest.main() |