aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
authoredunham <edunham@mozilla.com>2016-04-19 13:57:09 -0700
committerUK992 <urbankrajnc92@gmail.com>2016-08-12 13:32:09 +0200
commit48ace17b5419a9795a13bded286e113e79d56905 (patch)
treebc78a198ae1129c8c16979b868fba2b2634d0eb1 /python
parent1f4dd8765fe06784f052765f63f3e4869faf8164 (diff)
downloadservo-48ace17b5419a9795a13bded286e113e79d56905.tar.gz
servo-48ace17b5419a9795a13bded286e113e79d56905.zip
Improve tidy's license validation logic
fixes https://github.com/servo/servo/issues/10716 I took the lazy way out and hardcoded the size of block we examine for licenses. fixes https://github.com/servo/servo/issues/10719 Includes tests for new functionality.
Diffstat (limited to 'python')
-rw-r--r--python/tidy/HISTORY.rst11
-rw-r--r--python/tidy/servo_tidy/licenseck.py114
-rw-r--r--python/tidy/servo_tidy/tidy.py42
-rw-r--r--python/tidy/servo_tidy_tests/apache2_license.rs5
-rw-r--r--python/tidy/servo_tidy_tests/test_tidy.py4
-rw-r--r--python/tidy/setup.py4
6 files changed, 75 insertions, 105 deletions
diff --git a/python/tidy/HISTORY.rst b/python/tidy/HISTORY.rst
index 1e02962afa0..bc36c7e908f 100644
--- a/python/tidy/HISTORY.rst
+++ b/python/tidy/HISTORY.rst
@@ -1,6 +1,17 @@
Release History
---------------
+0.1.0 (2016-08-09)
+++++++++++++++++++
+
+- Improve license checking to disregard comments and line breaks
+- License checking verifies that COPYRIGHT is specified when apache2 is used
+
+0.0.3 (2016-04-19)
+++++++++++++++++++
+
+- Add alternate wording of apache2 license
+
0.0.2 (2016-04-17)
++++++++++++++++++
- Cleanup Tidy to work on external deps
diff --git a/python/tidy/servo_tidy/licenseck.py b/python/tidy/servo_tidy/licenseck.py
index 3a17f1fdf04..a9fe9077f21 100644
--- a/python/tidy/servo_tidy/licenseck.py
+++ b/python/tidy/servo_tidy/licenseck.py
@@ -7,97 +7,29 @@
# option. This file may not be copied, modified, or distributed
# except according to those terms.
-
-# These licenses are valid for use in Servo
-licenses = [
-
-"""\
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-""",
-
-"""\
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-""",
-
-"""\
-#!/usr/bin/env bash
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-""",
-
-"""\
-#!/usr/bin/env python
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-""",
-
-"""\
-#!/usr/bin/env python3
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-""",
-
-"""\
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-""",
-
-"""\
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-""",
-
-"""\
-# Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-""",
-
-"""\
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-""",
-
-"""\
-// Copyright 2012-2014 The Rust Project Developers.
-// See http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-""",
-] # noqa: Indicate to flake8 that we do not want to check indentation here
+# when wrapped to 80 chars, the longest license is 10 lines.
+# TODO actually grab whatever commented block is before the second blank line
+# of the file instead of hard-coding this.
+MAX_LICENSE_LINESPAN = 12
+
+MPL = """\
+This Source Code Form is subject to the terms of the Mozilla Public \
+License, v. 2.0. If a copy of the MPL was not distributed with this \
+file, You can obtain one at http://mozilla.org/MPL/2.0/.\
+"""
+
+APACHE = """\
+Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or \
+http://www.apache.org/licenses/LICENSE-2.0> or the MIT license \
+<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your \
+option. This file may not be copied, modified, or distributed \
+except according to those terms.\
+"""
+
+COPYRIGHT = [
+ "See the COPYRIGHT file at the top-level directory of this distribution",
+ "See http://rust-lang.org/COPYRIGHT",
+]
# The valid licenses, in the form we'd expect to see them in a Cargo.toml file.
licenses_toml = [
diff --git a/python/tidy/servo_tidy/tidy.py b/python/tidy/servo_tidy/tidy.py
index 3433e8265ed..fac5f8e7063 100644
--- a/python/tidy/servo_tidy/tidy.py
+++ b/python/tidy/servo_tidy/tidy.py
@@ -17,12 +17,9 @@ import site
import StringIO
import subprocess
import sys
-from licenseck import licenses, licenses_toml, licenses_dep_toml
+from licenseck import MPL, APACHE, COPYRIGHT, licenses_toml, licenses_dep_toml
-# License and header checks
-EMACS_HEADER = "/* -*- Mode:"
-VIM_HEADER = "/* vim:"
-MAX_LICENSE_LINESPAN = max(len(license.splitlines()) for license in licenses)
+COMMENTS = ["// ", "# ", " *", "/* "]
# File patterns to include in the non-WPT tidy check.
FILE_PATTERNS_TO_CHECK = ["*.rs", "*.rc", "*.cpp", "*.c",
@@ -55,7 +52,6 @@ IGNORED_FILES = [
IGNORED_DIRS = [
# Upstream
os.path.join(".", "support", "android", "apk"),
- os.path.join(".", "support", "rust-task_info"),
os.path.join(".", "tests", "wpt", "css-tests"),
os.path.join(".", "tests", "wpt", "harness"),
os.path.join(".", "tests", "wpt", "update"),
@@ -147,13 +143,35 @@ def filter_files(start_dir, only_changed_files, progress):
yield file_name
+def uncomment(line):
+ for c in COMMENTS:
+ if line.startswith(c):
+ if line.endswith("*/"):
+ return line[len(c):(len(line) - 3)].strip()
+ return line[len(c):].strip()
+
+
+def licensed_mpl(header):
+ return MPL in header
+
+
+def licensed_apache(header):
+ if APACHE in header:
+ return any(c in header for c in COPYRIGHT)
+
+
def check_license(file_name, lines):
if any(file_name.endswith(ext) for ext in (".toml", ".lock", ".json")):
raise StopIteration
- while lines and (lines[0].startswith(EMACS_HEADER) or lines[0].startswith(VIM_HEADER)):
- lines = lines[1:]
- contents = "".join(lines[:MAX_LICENSE_LINESPAN])
- valid_license = any(contents.startswith(license) for license in licenses)
+ block = min(len(lines), licenseck.MAX_LICENSE_LINESPAN)
+ license_block = []
+ for l in lines[:block]:
+ l = l.rstrip('\n')
+ line = uncomment(l)
+ if line is not None:
+ license_block += [line]
+ contents = " ".join(license_block)
+ valid_license = licensed_mpl(contents) or licensed_apache(contents)
acknowledged_bad_license = "xfail-license" in contents
if not (valid_license or acknowledged_bad_license):
yield (1, "incorrect license")
@@ -305,8 +323,8 @@ def check_toml(file_name, lines):
for idx, line in enumerate(lines):
if line.find("*") != -1:
yield (idx + 1, "found asterisk instead of minimum version number")
- for license in licenses_toml:
- ok_licensed |= (license in line)
+ for license_line in licenses_toml:
+ ok_licensed |= (license_line in line)
if not ok_licensed:
yield (0, ".toml file should contain a valid license.")
diff --git a/python/tidy/servo_tidy_tests/apache2_license.rs b/python/tidy/servo_tidy_tests/apache2_license.rs
new file mode 100644
index 00000000000..c9fed89cf73
--- /dev/null
+++ b/python/tidy/servo_tidy_tests/apache2_license.rs
@@ -0,0 +1,5 @@
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
diff --git a/python/tidy/servo_tidy_tests/test_tidy.py b/python/tidy/servo_tidy_tests/test_tidy.py
index 92b304a5c1a..888c0faf693 100644
--- a/python/tidy/servo_tidy_tests/test_tidy.py
+++ b/python/tidy/servo_tidy_tests/test_tidy.py
@@ -58,6 +58,10 @@ class CheckTidiness(unittest.TestCase):
self.assertEqual('script should use `[[` instead of `[` for conditional testing', errors.next()[2])
self.assertNoMoreErrors(errors)
+ def test_apache2_incomplete(self):
+ errors = tidy.collect_errors_for_files(iterFile('apache2_license.rs'), [], [tidy.check_license])
+ self.assertEqual('incorrect license', errors.next()[2])
+
def test_rust(self):
errors = tidy.collect_errors_for_files(iterFile('rust_tidy.rs'), [], [tidy.check_rust], print_text=False)
self.assertEqual('use statement spans multiple lines', errors.next()[2])
diff --git a/python/tidy/setup.py b/python/tidy/setup.py
index a1af7d88465..dbff59e7964 100644
--- a/python/tidy/setup.py
+++ b/python/tidy/setup.py
@@ -11,7 +11,7 @@ import os
from setuptools import setup, find_packages
-VERSION = '0.0.3'
+VERSION = '0.1.0'
install_requires = [
"flake8==2.4.1",
@@ -51,7 +51,7 @@ if __name__ == '__main__':
zip_safe=False,
entry_points={
'console_scripts': [
- 'servo-tidy=servo_tidy.tidy:scan'
+ 'servo-tidy=servo_tidy.tidy:scan',
],
},
)