diff --git a/LICENSE-binary b/LICENSE-binary index d809cc19ef4..d5b7fbbe150 100644 --- a/LICENSE-binary +++ b/LICENSE-binary @@ -205,64 +205,64 @@ This project bundles some components that are also licensed under the Apache License Version 2.0: -audience-annotations-0.12.0 -caffeine-3.1.1 -commons-beanutils-1.9.4 -commons-collections-3.2.2 -commons-digester-2.1 -commons-lang3-3.12.0 -commons-logging-1.3.2 -commons-validator-1.9.0 -error_prone_annotations-2.14.0 -jackson-annotations-2.16.2 -jackson-core-2.16.2 -jackson-databind-2.16.2 -jackson-dataformat-csv-2.16.2 -jackson-dataformat-yaml-2.16.2 -jackson-datatype-jdk8-2.16.2 -jackson-jakarta-rs-base-2.16.2 -jackson-jakarta-rs-json-provider-2.16.2 -jackson-jaxrs-base-2.16.2 -jackson-jaxrs-json-provider-2.16.2 -jackson-module-blackbird-2.16.2 -jackson-module-jakarta-xmlbind-annotations-2.16.2 -jackson-module-jaxb-annotations-2.16.2 -jackson-module-scala_2.13-2.16.2 -jakarta.inject-api-2.0.1 -jakarta.validation-api-3.0.2 -javassist-3.29.2-GA -jetty-alpn-client-12.0.15 -jetty-client-12.0.15 -jetty-continuation-9.4.56.v20240826 -jetty-ee10-servlet-12.0.15 -jetty-ee10-servlets-12.0.15 -jetty-http-12.0.15 -jetty-io-12.0.15 -jetty-security-12.0.15 -jetty-server-12.0.15 -jetty-servlet-9.4.56.v20240826 -jetty-servlets-9.4.56.v20240826 -jetty-session-12.0.15 -jetty-util-12.0.15 -jetty-util-ajax-9.4.56.v20240826 -jose4j-0.9.4 -log4j-api-2.24.1 -log4j-core-2.24.1 -log4j-core-test-2.24.1 -log4j-slf4j-impl-2.24.1 -log4j-1.2-api-2.24.1 -lz4-java-1.8.0 -maven-artifact-3.9.6 -metrics-core-2.2.0 -opentelemetry-proto-1.0.0-alpha -plexus-utils-3.5.1 -rocksdbjni-9.7.3 -scala-library-2.13.15 -scala-logging_2.13-3.9.5 -scala-reflect-2.13.15 -snappy-java-1.1.10.5 -snakeyaml-2.2 -swagger-annotations-2.2.25 +- audience-annotations-0.12.0 +- caffeine-3.1.1 +- commons-beanutils-1.9.4 +- commons-collections-3.2.2 +- commons-digester-2.1 +- commons-lang3-3.12.0 +- commons-logging-1.3.2 +- commons-validator-1.9.0 +- error_prone_annotations-2.14.0 +- jackson-annotations-2.16.2 +- jackson-core-2.16.2 +- jackson-databind-2.16.2 +- jackson-dataformat-csv-2.16.2 +- jackson-dataformat-yaml-2.16.2 +- jackson-datatype-jdk8-2.16.2 +- jackson-jakarta-rs-base-2.16.2 +- jackson-jakarta-rs-json-provider-2.16.2 +- jackson-jaxrs-base-2.16.2 +- jackson-jaxrs-json-provider-2.16.2 +- jackson-module-blackbird-2.16.2 +- jackson-module-jakarta-xmlbind-annotations-2.16.2 +- jackson-module-jaxb-annotations-2.16.2 +- jackson-module-scala_2.13-2.16.2 +- jakarta.inject-api-2.0.1 +- jakarta.validation-api-3.0.2 +- javassist-3.29.2-GA +- jetty-alpn-client-12.0.15 +- jetty-client-12.0.15 +- jetty-continuation-9.4.56.v20240826 +- jetty-ee10-servlet-12.0.15 +- jetty-ee10-servlets-12.0.15 +- jetty-http-12.0.15 +- jetty-io-12.0.15 +- jetty-security-12.0.15 +- jetty-server-12.0.15 +- jetty-servlet-9.4.56.v20240826 +- jetty-servlets-9.4.56.v20240826 +- jetty-session-12.0.15 +- jetty-util-12.0.15 +- jetty-util-ajax-9.4.56.v20240826 +- jose4j-0.9.4 +- log4j-api-2.24.1 +- log4j-core-2.24.1 +- log4j-core-test-2.24.1 +- log4j-slf4j-impl-2.24.1 +- log4j-1.2-api-2.24.1 +- lz4-java-1.8.0 +- maven-artifact-3.9.6 +- metrics-core-2.2.0 +- opentelemetry-proto-1.0.0-alpha +- plexus-utils-3.5.1 +- rocksdbjni-9.7.3 +- scala-library-2.13.15 +- scala-logging_2.13-3.9.5 +- scala-reflect-2.13.15 +- snappy-java-1.1.10.5 +- snakeyaml-2.2 +- swagger-annotations-2.2.25 =============================================================================== This product bundles various third-party components under other open source @@ -273,64 +273,64 @@ See licenses/ for text of these licenses. Eclipse Distribution License - v 1.0 see: licenses/eclipse-distribution-license-1.0 -jakarta.activation-api-2.1.0 -jakarta.xml.bind-api-3.0.1 +- jakarta.activation-api-2.1.0 +- jakarta.xml.bind-api-3.0.1 --------------------------------------- Eclipse Public License - v 2.0 see: licenses/eclipse-public-license-2.0 -jakarta.annotation-api-2.1.1 -jakarta.ws.rs-api-3.1.0 -hk2-api-3.0.6 -hk2-locator-3.0.6 -hk2-utils-3.0.6 -osgi-resource-locator-1.0.3 -aopalliance-repackaged-3.0.6 -jakarta.inject-2.6.1 -jersey-client-3.1.9 -jersey-common-3.1.9 -jersey-container-servlet-3.1.9 -jersey-container-servlet-core-3.1.9 -jersey-hk2-3.1.9 -jersey-server-3.1.9 +- jakarta.annotation-api-2.1.1 +- jakarta.ws.rs-api-3.1.0 +- hk2-api-3.0.6 +- hk2-locator-3.0.6 +- hk2-utils-3.0.6 +- osgi-resource-locator-1.0.3 +- aopalliance-repackaged-3.0.6 +- jakarta.inject-2.6.1 +- jersey-client-3.1.9 +- jersey-common-3.1.9 +- jersey-container-servlet-3.1.9 +- jersey-container-servlet-core-3.1.9 +- jersey-hk2-3.1.9 +- jersey-server-3.1.9 --------------------------------------- CDDL 1.1 + GPLv2 with classpath exception see: licenses/CDDL+GPL-1.1 -jakarta.servlet-api-6.0.0 -javax.activation-api-1.2.0 -javax.annotation-api-1.3.2 -javax.servlet-api-3.1.0 -jaxb-api-2.3.1 -activation-1.1.1 +- jakarta.servlet-api-6.0.0 +- javax.activation-api-1.2.0 +- javax.annotation-api-1.3.2 +- javax.servlet-api-3.1.0 +- jaxb-api-2.3.1 +- activation-1.1.1 --------------------------------------- MIT License -argparse4j-0.7.0, see: licenses/argparse-MIT -classgraph-4.8.173, see: licenses/classgraph-MIT -jopt-simple-5.0.4, see: licenses/jopt-simple-MIT -slf4j-api-1.7.36, see: licenses/slf4j-MIT -pcollections-4.0.1, see: licenses/pcollections-MIT +- argparse4j-0.7.0, see: licenses/argparse-MIT +- classgraph-4.8.173, see: licenses/classgraph-MIT +- jopt-simple-5.0.4, see: licenses/jopt-simple-MIT +- slf4j-api-1.7.36, see: licenses/slf4j-MIT +- pcollections-4.0.1, see: licenses/pcollections-MIT --------------------------------------- BSD 2-Clause -zstd-jni-1.5.6-6 see: licenses/zstd-jni-BSD-2-clause -HdrHistogram-2.2.2 see: licenses/hdrHistogram-BSD-2-clause +- zstd-jni-1.5.6-6, see: licenses/zstd-jni-BSD-2-clause +- HdrHistogram-2.2.2, see: licenses/hdrHistogram-BSD-2-clause --------------------------------------- BSD 3-Clause -jline-3.25.1, see: licenses/jline-BSD-3-clause -jsr305-3.0.2, see: licenses/jsr305-BSD-3-clause -paranamer-2.8, see: licenses/paranamer-BSD-3-clause -protobuf-java-3.25.5, see: licenses/protobuf-java-BSD-3-clause -jakarta.activation-2.0.1, see: licenses/jakarta-BSD-3-clause +- jline-3.25.1, see: licenses/jline-BSD-3-clause +- jsr305-3.0.2, see: licenses/jsr305-BSD-3-clause +- paranamer-2.8, see: licenses/paranamer-BSD-3-clause +- protobuf-java-3.25.5, see: licenses/protobuf-java-BSD-3-clause +- jakarta.activation-2.0.1, see: licenses/jakarta-BSD-3-clause --------------------------------------- Go License -re2j-1.7 see: licenses/re2j-GO +- re2j-1.7, see: licenses/re2j-GO diff --git a/committer-tools/verify_license.py b/committer-tools/verify_license.py new file mode 100644 index 00000000000..7dc29f5517e --- /dev/null +++ b/committer-tools/verify_license.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import re +import sys +import tarfile +import tempfile +import subprocess + +# Constant: Regex to extract dependency tokens from the LICENSE file. +# Matches lines that start with a dash and then a dependency token of the form: +# DependencyName-x.y, DependencyName-x.y.z, or DependencyName-x.y.z.w +# Optionally, a trailing suffix (e.g., "-alpha") is captured. +LICENSE_DEP_PATTERN = re.compile( + r'^\s*-\s*([A-Za-z0-9_.+-]+-[0-9]+\.[0-9]+(?:\.[0-9]+){0,2}(?:[-.][A-Za-z0-9]+)?)', + re.MULTILINE +) + +def run_gradlew(project_dir): + print("Running './gradlew clean releaseTarGz'") + subprocess.run(["./gradlew", "clean", "releaseTarGz"], check=True, cwd=project_dir) + +def get_tarball_path(project_dir): + distributions_dir = os.path.join(project_dir, "core", "build", "distributions") + if not os.path.isdir(distributions_dir): + print("Error: Distributions directory not found:", distributions_dir) + sys.exit(1) + + pattern = re.compile(r'^kafka_2\.13-.+\.tgz$', re.IGNORECASE) + candidates = [ + os.path.join(distributions_dir, f) + for f in os.listdir(distributions_dir) + if pattern.match(f) + ] + if not candidates: + print("Error: No tarball matching 'kafka_2.13-*.tgz' found in:", distributions_dir) + sys.exit(1) + + tarball_path = max(candidates, key=os.path.getmtime) + return tarball_path + +def extract_tarball(tarball, extract_dir): + with tarfile.open(tarball, "r:gz") as tar: + # Use a filter to avoid future deprecation warnings. + tar.extractall(path=extract_dir, filter=lambda tarinfo, dest: tarinfo) + print("Tarball extracted to:", extract_dir) + +def get_libs_set(libs_dir): + return { + fname[:-4] + for fname in os.listdir(libs_dir) + if fname.endswith(".jar") and not re.search(r"(kafka|connect|trogdor)", fname, re.IGNORECASE) + } + +def get_license_deps(license_text): + return set(LICENSE_DEP_PATTERN.findall(license_text)) + +def main(): + # Assume the current working directory is the project root. + project_dir = os.getcwd() + print("Using project directory:", project_dir) + + # Build the tarball. + run_gradlew(project_dir) + tarball = get_tarball_path(project_dir) + print("Tarball created at:", tarball) + + # Extract the tarball into a temporary directory. + with tempfile.TemporaryDirectory() as tmp_dir: + extract_tarball(tarball, tmp_dir) + extracted_dirs = os.listdir(tmp_dir) + if not extracted_dirs: + print("Error: No directory found after extraction.") + sys.exit(1) + extracted = os.path.join(tmp_dir, extracted_dirs[0]) + print("Tarball extracted to:", extracted) + + # Locate the LICENSE file and libs directory. + license_path = os.path.join(extracted, "LICENSE") + libs_dir = os.path.join(extracted, "libs") + if not os.path.exists(license_path) or not os.path.exists(libs_dir): + print("Error: LICENSE file or libs directory not found in the extracted project.") + sys.exit(1) + + with open(license_path, "r", encoding="utf-8") as f: + license_text = f.read() + + # Get dependency sets. + libs = get_libs_set(libs_dir) + license_deps = get_license_deps(license_text) + + print("\nDependencies from libs (extracted from jar names):") + for dep in sorted(libs): + print(" -", dep) + + print("\nDependencies extracted from LICENSE file:") + for dep in sorted(license_deps): + print(" -", dep) + + # Compare the sets. + missing_in_license = libs - license_deps + extra_in_license = license_deps - libs + + if missing_in_license: + print("\nThe following libs (from ./libs) are missing in the LICENSE file. These should be added to the LICENSE-binary file:") + for dep in sorted(missing_in_license): + print(" -", dep) + else: + print("\nAll libs from ./libs are present in the LICENSE file.") + + if extra_in_license: + print("\nThe following entries are in the LICENSE file but not present in ./libs. These should be removed from the LICENSE-binary file:") + for dep in sorted(extra_in_license): + print(" -", dep) + else: + print("\nNo extra dependencies in the LICENSE file.") + + if missing_in_license or extra_in_license: + sys.exit(1) + +if __name__ == "__main__": + main() +