diff options
Diffstat (limited to '')
-rw-r--r-- | tools/lint/license.yml | 94 | ||||
-rw-r--r-- | tools/lint/license/__init__.py | 195 | ||||
-rw-r--r-- | tools/lint/license/valid-licenses.txt | 30 |
3 files changed, 319 insertions, 0 deletions
diff --git a/tools/lint/license.yml b/tools/lint/license.yml new file mode 100644 index 0000000000..f6bd6576ac --- /dev/null +++ b/tools/lint/license.yml @@ -0,0 +1,94 @@ +--- +license: + description: License Check + include: + - . + exclude: + # These paths need to be triaged. + - build/pgo/js-input + # License not super clear + - browser/branding/ + # Trademarks + - browser/components/pocket/content/panels/ + - browser/components/newtab/data/content/tippytop/images/ + - toolkit/components/pdfjs/content/web/images/ + # We probably want a specific license + - browser/extensions/webcompat/injections/ + # Different license + - build/pgo/blueprint/print.css + # Different license + - build/pgo/blueprint/screen.css + # Empty files + - config/external/nspr/_pl_bld.h + - config/external/nspr/_pr_bld.h + # Unknown origin + - gfx/2d/MMIHelpers.h + # might not work with license + - gradle.properties + # might not work with license + - gradle/wrapper/gradle-wrapper.properties + # Imported code that is dual Apache2 / MIT licensed + - intl/l10n/rust/l10nregistry-rs + # tests + - js/src/devtools/rootAnalysis/t/ + - mobile/android/geckoview/src/main/AndroidManifest.xml + - mobile/android/geckoview/src/main/AndroidManifest_overlay.jinja + - mobile/android/geckoview/src/main/res/drawable/ic_generic_file.xml + - mobile/android/geckoview_example/src/main + - testing/webcompat/interventions/ + - testing/webcompat/shims/ + # might not work with license + - mobile/android/gradle/dotgradle-offline/gradle.properties + # might not work with license + - mobile/android/gradle/dotgradle-online/gradle.properties + # Almost empty file + - modules/libpref/greprefs.js + - parser/html/java/named-character-references.html + - python/mozlint/test/files/ + # By design + - python/mozrelease/mozrelease + - security/mac/hardenedruntime/browser.developer.entitlements.xml + - security/mac/hardenedruntime/browser.production.entitlements.xml + - security/mac/hardenedruntime/developer.entitlements.xml + - security/mac/hardenedruntime/plugin-container.developer.entitlements.xml + - security/mac/hardenedruntime/plugin-container.production.entitlements.xml + - security/mac/hardenedruntime/production.entitlements.xml + - testing/marionette/harness/marionette_harness/www/ + # Browsertime can't handle this script when there's a comment at the top + - testing/raptor/browsertime/browsertime_benchmark.js + - toolkit/components/reputationservice/chromium/chrome/common/safe_browsing/csd.pb.cc + - toolkit/components/reputationservice/chromium/chrome/common/safe_browsing/csd.pb.h + - toolkit/mozapps/update/updater/crctable.h + - tools/lint/eslint/eslint-plugin-mozilla/lib/configs + # template fragments used to generate .js sources. + - toolkit/components/uniffi-bindgen-gecko-js/src/templates/js + # By design + - tools/lint/test/ + extensions: + - .c + - .cc + - .cpp + - .css + - .dtd + - .ftl + - .h + - .html + - .java + - .js + - .jsm + - .jsx + - .m + - .mm + - .mjs + - .properties + - .py + - .rs + - .svg + - .xhtml + - .xml + - .xul + support-files: + - 'tools/lint/license/**' + type: external + payload: license:lint + find-dotfiles: true diff --git a/tools/lint/license/__init__.py b/tools/lint/license/__init__.py new file mode 100644 index 0000000000..25139b49c5 --- /dev/null +++ b/tools/lint/license/__init__.py @@ -0,0 +1,195 @@ +# 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/. + +import os + +from mozlint import result +from mozlint.pathutils import expand_exclusions + +here = os.path.abspath(os.path.dirname(__file__)) + +results = [] + +# Official source: https://www.mozilla.org/en-US/MPL/headers/ +TEMPLATES = { + "mpl2_license": """ + 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/. + """.strip().splitlines(), + "public_domain_license": """ + Any copyright is dedicated to the public domain. + http://creativecommons.org/publicdomain/zero/1.0/ + """.strip().splitlines(), +} +license_list = os.path.join(here, "valid-licenses.txt") + + +def load_valid_license(): + """ + Load the list of license patterns + """ + with open(license_list) as f: + l = f.readlines() + # Remove the empty lines + return list(filter(bool, [x.replace("\n", "") for x in l])) + + +def is_valid_license(licenses, filename): + """ + From a given file, check if we can find the license patterns + in the X first lines of the file + """ + with open(filename, "r", errors="replace") as myfile: + contents = myfile.read() + # Empty files don't need a license. + if not contents: + return True + + for l in licenses: + if l.lower().strip() in contents.lower(): + return True + return False + + +def add_header(log, filename, header): + """ + Add the header to the top of the file + """ + header.append("\n") + with open(filename, "r+") as f: + # lines in list format + try: + lines = f.readlines() + except UnicodeDecodeError as e: + log.debug("Could not read file '{}'".format(f)) + log.debug("Error: {}".format(e)) + return + + i = 0 + if lines: + # if the file isn't empty (__init__.py can be empty files) + if lines[0].startswith("#!") or lines[0].startswith("<?xml "): + i = 1 + + if lines[0].startswith("/* -*- Mode"): + i = 2 + # Insert in the top of the data structure + lines[i:i] = header + f.seek(0, 0) + f.write("".join(lines)) + + +def is_test(f): + """ + is the file a test or not? + """ + if "lint/test/" in f: + # For the unit tests + return False + return ( + "/tests/" in f + or "/test/" in f + or "/test_" in f + or "/gtest" in f + or "/crashtest" in f + or "/mochitest" in f + or "/reftest" in f + or "/imptest" in f + or "/androidTest" in f + or "/jit-test/" in f + or "jsapi-tests/" in f + ) + + +def fix_me(log, filename): + """ + Add the copyright notice to the top of the file + """ + _, ext = os.path.splitext(filename) + license = [] + + license_template = TEMPLATES["mpl2_license"] + test = False + + if is_test(filename): + license_template = TEMPLATES["public_domain_license"] + test = True + + if ext in [ + ".cpp", + ".c", + ".cc", + ".h", + ".m", + ".mm", + ".rs", + ".java", + ".js", + ".jsm", + ".jsx", + ".css", + ]: + for i, l in enumerate(license_template): + start = " " + end = "" + if i == 0: + # first line, we have the /* + start = "/" + if i == len(license_template) - 1: + # Last line, we end by */ + end = " */" + license.append(start + "* " + l.strip() + end + "\n") + + add_header(log, filename, license) + return + + if ext in [".py", ".ftl", ".properties"] or filename.endswith(".inc.xul"): + for l in license_template: + license.append("# " + l.strip() + "\n") + add_header(log, filename, license) + return + + if ext in [".xml", ".xul", ".html", ".xhtml", ".dtd", ".svg"]: + for i, l in enumerate(license_template): + start = " - " + end = "" + if i == 0: + # first line, we have the <!-- + start = "<!-- " + if i == 2 or (i == 1 and test): + # Last line, we end by --> + end = " -->" + license.append(start + l.strip() + end) + if ext != ".svg" or end == "": + # When dealing with an svg, we should not have a space between + # the license and the content + license.append("\n") + add_header(log, filename, license) + return + + +def lint(paths, config, fix=None, **lintargs): + log = lintargs["log"] + files = list(expand_exclusions(paths, config, lintargs["root"])) + fixed = 0 + + licenses = load_valid_license() + for f in files: + if is_test(f): + # For now, do not do anything with test (too many) + continue + + if not is_valid_license(licenses, f): + res = { + "path": f, + "message": "No matching license strings found in tools/lint/license/valid-licenses.txt", # noqa + "level": "error", + } + results.append(result.from_config(config, **res)) + if fix: + fix_me(log, f) + fixed += 1 + + return {"results": results, "fixed": fixed} diff --git a/tools/lint/license/valid-licenses.txt b/tools/lint/license/valid-licenses.txt new file mode 100644 index 0000000000..8a1d39a69e --- /dev/null +++ b/tools/lint/license/valid-licenses.txt @@ -0,0 +1,30 @@ +mozilla.org/MPL/ +Licensed under the Apache License, Version 2.0 +copyright is dedicated to the Public Domain. +under the MIT +Redistributions of source code must retain the above copyright +Use of this source code is governed by a BSD-style license +The author disclaims copyright to this source code. +The author hereby disclaims copyright to this source code +Use, Modification and Redistribution (including distribution of any +author grants irrevocable permission to anyone to use, modify, +THIS FILE IS AUTO-GENERATED +Permission is hereby granted, free of charge, to any person obtaining +Permission to use, copy, modify, +License: Public domain. You are free to use this code however you +You are granted a license to use, reproduce and create derivative works +GENERATED FILE, DO NOT EDIT +This code is governed by the BSD license +This Source Code Form is subject to the terms of the Apache License +DO NOT EDIT +This program is made available under an ISC-style license. +under MIT license +License MIT per upstream +DO NOT MODIFY +GNU General Public License +FILE IS GENERATED +Generated by +do not edit +may be protected as a trademark in some jurisdictions +The ASF licenses this file to You under the Apache License, Version 2.0 +Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions |