Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Improve tidy's license validation logic
fixes #10716

I took the lazy way out and hardcoded the size of block we examine for
licenses.

fixes #10719

Includes tests for new functionality.
  • Loading branch information
edunham authored and UK992 committed Aug 12, 2016
1 parent 1f4dd87 commit 48ace17
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 105 deletions.
11 changes: 11 additions & 0 deletions 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
Expand Down
114 changes: 23 additions & 91 deletions python/tidy/servo_tidy/licenseck.py
Expand Up @@ -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 = [
Expand Down
42 changes: 30 additions & 12 deletions python/tidy/servo_tidy/tidy.py
Expand Up @@ -17,12 +17,9 @@
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",
Expand Down Expand Up @@ -55,7 +52,6 @@
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"),
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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.")

Expand Down
5 changes: 5 additions & 0 deletions 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.
4 changes: 4 additions & 0 deletions python/tidy/servo_tidy_tests/test_tidy.py
Expand Up @@ -58,6 +58,10 @@ def test_shell(self):
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])
Expand Down
4 changes: 2 additions & 2 deletions python/tidy/setup.py
Expand Up @@ -11,7 +11,7 @@
from setuptools import setup, find_packages


VERSION = '0.0.3'
VERSION = '0.1.0'

install_requires = [
"flake8==2.4.1",
Expand Down Expand Up @@ -51,7 +51,7 @@
zip_safe=False,
entry_points={
'console_scripts': [
'servo-tidy=servo_tidy.tidy:scan'
'servo-tidy=servo_tidy.tidy:scan',
],
},
)
1 change: 1 addition & 0 deletions support/rust-task_info/Cargo.toml
Expand Up @@ -3,6 +3,7 @@
name = "task_info"
version = "0.0.1"
authors = ["The Servo Project Developers"]
license = "MPL-2.0"

build = "build.rs"

Expand Down

0 comments on commit 48ace17

Please sign in to comment.