Updating presubmit to check license is a valid spdx identifier.

Further details are available in https://docs.google.com/document/d/1x4GLly7KJ2xmlJRvsswJlmVSLLjBjk5NOxWZ-Dryg_A

Bug: 358504615
Change-Id: I76997454140ee63aea6b6f492669800efce271be
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6021876
Reviewed-by: Joey Scarr <jsca@google.com>
Commit-Queue: Jordan Brown <rop@google.com>
Reviewed-by: Andrew Grieve <agrieve@chromium.org>
Reviewed-by: Rick Byers <rbyers@chromium.org>
Reviewed-by: Rachael Newitt <renewitt@google.com>
changes/76/6021876/9
Jordan 8 months ago committed by LUCI CQ
parent bc85464ac5
commit b5eb54d5c1

@ -0,0 +1,7 @@
# ATLs are responsible for approving new licenses.
# TODO(b/379562012) Replace with file:/ATL_OWNERS.
rbyers@chromium.org
thakis@chromium.org
# TODO(b/379223095) Remove security team once transition to spdx allow list is complete.
file:SECURITY_TEAM_OWNERS

@ -1,6 +1,5 @@
# Software Supply Chain Integrity/SBOM # Software Supply Chain Integrity/SBOM.
aredulla@google.com
dlf@google.com file:SECURITY_TEAM_OWNERS
jsca@google.com
renewitt@google.com per-file fields/custom/license_allowlist.py=file:LICENSE_OWNERS
sumakasa@google.com

@ -0,0 +1,11 @@
# Chops security team.
aredulla@google.com
ayatane@chromium.org
dlf@google.com
heidichan@google.com
jsca@google.com
mitchella@google.com
qjw@chromium.org
renewitt@google.com
rop@google.com

@ -18,34 +18,7 @@ sys.path.insert(0, _ROOT_DIR)
import metadata.fields.field_types as field_types import metadata.fields.field_types as field_types
import metadata.fields.util as util import metadata.fields.util as util
import metadata.validation_result as vr import metadata.validation_result as vr
from metadata.fields.custom.license_allowlist import ALLOWED_SPDX_LICENSES
# Copied from ANDROID_ALLOWED_LICENSES in
# https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/PRESUBMIT.py
_ANDROID_ALLOWED_LICENSES = [
"A(pple )?PSL 2(\.0)?",
"Android Software Development Kit License",
"Apache( License)?,?( Version)? 2(\.0)?",
"(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?",
"GNU Lesser Public License",
"L?GPL ?v?2(\.[01])?( or later)?( with the classpath exception)?",
"(The )?MIT(/X11)?(-like)?( License)?",
"MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1",
"MPL 2(\.0)?",
"Microsoft Limited Public License",
"Microsoft Permissive License",
"Public Domain",
"Python",
"SIL Open Font License, Version 1.1",
"SGI Free Software License B",
"Unicode, Inc. License",
"University of Illinois\/NCSA Open Source",
"X11",
"Zlib",
]
_PATTERN_LICENSE_ALLOWED = re.compile(
"^({})$".format("|".join(_ANDROID_ALLOWED_LICENSES)),
re.IGNORECASE,
)
_PATTERN_VERBOSE_DELIMITER = re.compile(r" and | or | / ") _PATTERN_VERBOSE_DELIMITER = re.compile(r" and | or | / ")
@ -97,7 +70,7 @@ def is_license_allowlisted(value: str) -> bool:
"""Returns whether the value is in the allowlist for license """Returns whether the value is in the allowlist for license
types. types.
""" """
return util.matches(_PATTERN_LICENSE_ALLOWED, value) return value in ALLOWED_SPDX_LICENSES
class LicenseField(field_types.SingleLineTextField): class LicenseField(field_types.SingleLineTextField):

@ -0,0 +1,38 @@
#!/usr/bin/env python3
# Copyright 2024 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# These licenses are used to verify that code imported to Android complies with
# their licensing requirements. Do not add entries to this list without approval.
# Any licenses added should be a valid SPDX Identifier. For the full list of
# identifiers; see https://spdx.org/licenses/
ALLOWED_SPDX_LICENSES = frozenset([
"APSL-2.0",
"Apache-2.0",
"BSD-2-Clause",
"BSD-2-Clause-FreeBSD",
"BSD-3-Clause",
"BSD-4-Clause",
"BSD-4-Clause-UC",
"BSD-Source-Code",
"GPL-2.0-with-classpath-exception",
"MIT",
"MIT-0",
"MIT-Modern-Variant",
"MPL-1.1",
"MPL-2.0",
"NCSA",
"OFL-1.1",
"SGI-B-2.0",
"Unicode-3.0",
"Unicode-DFS-2015",
"Unicode-DFS-2016",
"X11",
"Zlib",
# Public Domain variants.
"ISC",
"ICU",
"SunPro",
"BSL-1.0",
])

@ -4,7 +4,7 @@ URL: https://www.example.com/metadata,
https://www.example.com/parser https://www.example.com/parser
Version: 1.0.12 Version: 1.0.12
Date: 2020-12-03 Date: 2020-12-03
License: Apache, 2.0 and MIT License: Apache-2.0 and MIT
License File: LICENSE License File: LICENSE
Security Critical: yes Security Critical: yes
Shipped: yes Shipped: yes

@ -4,7 +4,7 @@ URL: https://www.example.com/metadata,
https://www.example.com/parser https://www.example.com/parser
Version: 1.0.12 Version: 1.0.12
Date: 2020-12-03 Date: 2020-12-03
License: Apache, 2.0 and MIT License: Apache-2.0 and MIT
License File: LICENSE License File: LICENSE
Security Critical: yes Security Critical: yes
Shipped: yes Shipped: yes
@ -26,7 +26,7 @@ Short Name: metadata-test-valid-again
URL: https://www.example.com/metadata URL: https://www.example.com/metadata
Version: 1.0.12 Version: 1.0.12
Date: 2020-12-03 Date: 2020-12-03
License: Apache, 2.0 and MIT License: MIT
License File: LICENSE License File: LICENSE
Security Critical: yes Security Critical: yes
Shipped: yes Shipped: yes
@ -38,7 +38,7 @@ Short Name: metadata-test-valid-again
URL: https://www.example.com/metadata URL: https://www.example.com/metadata
Version: 1.0.12 Version: 1.0.12
Date: 2020-12-03 Date: 2020-12-03
License: Apache, 2.0 and MIT License: Apache-2.0
License File: LICENSE License File: LICENSE
Security Critical: yes Security Critical: yes
Shipped in Chromium: yes Shipped in Chromium: yes

@ -30,7 +30,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.URL.get_name(), dependency.add_entry(known_fields.URL.get_name(),
"https://www.example.com") "https://www.example.com")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
@ -53,7 +53,7 @@ class DependencyValidationTest(unittest.TestCase):
"Test alias field used") "Test alias field used")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
# Use Shipped in Chromium instead of Shipped. # Use Shipped in Chromium instead of Shipped.
dependency.add_entry(known_fields.SHIPPED_IN_CHROMIUM.get_name(), "no") dependency.add_entry(known_fields.SHIPPED_IN_CHROMIUM.get_name(), "no")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
@ -75,7 +75,7 @@ class DependencyValidationTest(unittest.TestCase):
"Test alias field overwrite") "Test alias field overwrite")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.SHIPPED_IN_CHROMIUM.get_name(), "no") dependency.add_entry(known_fields.SHIPPED_IN_CHROMIUM.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "test") dependency.add_entry(known_fields.SHIPPED.get_name(), "test")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
@ -98,7 +98,7 @@ class DependencyValidationTest(unittest.TestCase):
"Test alias field error attributed") "Test alias field error attributed")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.SHIPPED_IN_CHROMIUM.get_name(), dependency.add_entry(known_fields.SHIPPED_IN_CHROMIUM.get_name(),
"test") "test")
dependency.add_entry(known_fields.SHIPPED.get_name(), "yes") dependency.add_entry(known_fields.SHIPPED.get_name(), "yes")
@ -121,7 +121,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.URL.get_name(), dependency.add_entry(known_fields.URL.get_name(),
"https://www.example.com") "https://www.example.com")
dependency.add_entry(known_fields.VERSION.get_name(), "N/A") dependency.add_entry(known_fields.VERSION.get_name(), "N/A")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
@ -145,7 +145,7 @@ class DependencyValidationTest(unittest.TestCase):
"https://www.example.com") "https://www.example.com")
dependency.add_entry(known_fields.VERSION.get_name(), "N/A") dependency.add_entry(known_fields.VERSION.get_name(), "N/A")
dependency.add_entry(known_fields.REVISION.get_name(), "N/A") dependency.add_entry(known_fields.REVISION.get_name(), "N/A")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
@ -173,7 +173,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.REVISION.get_name(), dependency.add_entry(known_fields.REVISION.get_name(),
"invalid_revision") "invalid_revision")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
@ -197,7 +197,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.URL.get_name(), dependency.add_entry(known_fields.URL.get_name(),
"https://www.example.com") "https://www.example.com")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
@ -227,7 +227,7 @@ class DependencyValidationTest(unittest.TestCase):
"https://www.example.com") "https://www.example.com")
dependency.add_entry(known_fields.VERSION.get_name(), "N/A") dependency.add_entry(known_fields.VERSION.get_name(), "N/A")
dependency.add_entry(known_fields.REVISION.get_name(), "DEPS") dependency.add_entry(known_fields.REVISION.get_name(), "DEPS")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
@ -245,7 +245,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.NAME.get_name(), "Test missing field") dependency.add_entry(known_fields.NAME.get_name(), "Test missing field")
# Leave URL field unspecified. # Leave URL field unspecified.
@ -267,7 +267,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.NAME.get_name(), "Test invalid field") dependency.add_entry(known_fields.NAME.get_name(), "Test invalid field")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "test") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "test")
@ -288,7 +288,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.URL.get_name(), dependency.add_entry(known_fields.URL.get_name(),
"https://www.example.com") "https://www.example.com")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), dependency.add_entry(known_fields.LICENSE_FILE.get_name(),
"MISSING-LICENSE") "MISSING-LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
@ -309,7 +309,7 @@ class DependencyValidationTest(unittest.TestCase):
"Test multiple errors") "Test multiple errors")
# Leave URL field unspecified. # Leave URL field unspecified.
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), dependency.add_entry(known_fields.LICENSE_FILE.get_name(),
"MISSING-LICENSE") "MISSING-LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "test") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "test")
@ -335,7 +335,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.URL.get_name(), dependency.add_entry(known_fields.URL.get_name(),
"https://www.example.com") "https://www.example.com")
dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0") dependency.add_entry(known_fields.VERSION.get_name(), "1.0.0")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "no")
dependency.add_entry(known_fields.SHIPPED.get_name(), "no") dependency.add_entry(known_fields.SHIPPED.get_name(), "no")
@ -357,7 +357,7 @@ class DependencyValidationTest(unittest.TestCase):
dependency.add_entry(known_fields.URL.get_name(), dependency.add_entry(known_fields.URL.get_name(),
"This is the canonical repository") "This is the canonical repository")
dependency.add_entry(known_fields.VERSION.get_name(), "N/A") dependency.add_entry(known_fields.VERSION.get_name(), "N/A")
dependency.add_entry(known_fields.LICENSE.get_name(), "Public Domain") dependency.add_entry(known_fields.LICENSE.get_name(), "MIT")
dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE") dependency.add_entry(known_fields.LICENSE_FILE.get_name(), "LICENSE")
dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "yes") dependency.add_entry(known_fields.SECURITY_CRITICAL.get_name(), "yes")
dependency.add_entry(known_fields.SHIPPED.get_name(), "yes") dependency.add_entry(known_fields.SHIPPED.get_name(), "yes")

@ -115,13 +115,12 @@ class FieldValidationTest(unittest.TestCase):
self._run_field_validation( self._run_field_validation(
field=known_fields.LICENSE, field=known_fields.LICENSE,
valid_values=[ valid_values=[
"Apache, 2.0 / MIT / MPL 2", "Apache-2.0 / MIT",
"LGPL 2.1", "Apache-2.0",
"GPL v2 or later", "BSD-2-Clause",
"LGPL2 with the classpath exception", "BSD-2-Clause-FreeBSD",
"Apache, Version 2 and Public domain", "MIT",
"Public domain or MPL 2", "APSL-2.0 and MIT",
"APSL 2 and the MIT license",
], ],
error_values=["", "\n", ",", "Apache 2.0 / MIT / "], error_values=["", "\n", ",", "Apache 2.0 / MIT / "],
warning_values=[ warning_values=[

@ -77,7 +77,7 @@ class ParseTest(unittest.TestCase):
" https://www.example.com/parser"), " https://www.example.com/parser"),
("Version", "1.0.12"), ("Version", "1.0.12"),
("Date", "2020-12-03"), ("Date", "2020-12-03"),
("License", "Apache, 2.0 and MIT"), ("License", "Apache-2.0 and MIT"),
("License File", "LICENSE"), ("License File", "LICENSE"),
("Security Critical", "yes"), ("Security Critical", "yes"),
("Shipped", "yes"), ("Shipped", "yes"),

Loading…
Cancel
Save