Skip to content

Commit

Permalink
Rename COPYING file to LICENSES, and add a file that contains all of our
Browse files Browse the repository at this point in the history
dependencies' licenses. Add these to our release binaries.

PiperOrigin-RevId: 576266234
  • Loading branch information
gunan authored and Copybara-Service committed Oct 24, 2023
1 parent 07b3c70 commit 6dcbaad
Show file tree
Hide file tree
Showing 9 changed files with 2,218 additions and 16 deletions.
6 changes: 6 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ load("@rules_jvm_external//:defs.bzl", "java_export")

package(licenses = ["notice"])

exports_files([
"LICENSE",
])

filegroup(
name = "sonatype_bundles",
srcs = [
Expand Down Expand Up @@ -152,7 +156,9 @@ oss_java_library(
"-target 11",
],
resources = [
":LICENSE",
":externs_zip",
"//license_check:THIRD_PARTY_NOTICES",
] + glob([
"src/**/*.properties",
]),
Expand Down
File renamed without changes.
18 changes: 2 additions & 16 deletions WORKSPACE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,10 @@ load("@com_github_johnynek_bazel_jar_jar//:jar_jar.bzl", "jar_jar_repositories")
jar_jar_repositories()

load("@rules_jvm_external//:defs.bzl", "maven_install")
load("//license_check:maven_artifacts.bzl", "MAVEN_ARTIFACTS")

maven_install(
artifacts = [
"args4j:args4j:2.33",
"com.google.code.gson:gson:2.9.1",
"com.google.errorprone:error_prone_annotations:2.15.0",
"com.google.guava:failureaccess:1.0.1",
"com.google.guava:guava:32.1.2-jre",
"com.google.guava:guava-testlib:32.1.2-jre",
"com.google.jimfs:jimfs:1.2",
"com.google.protobuf:protobuf-java:3.21.12",
"com.google.re2j:re2j:1.3",
"com.google.truth.extensions:truth-liteproto-extension:1.1",
"com.google.truth.extensions:truth-proto-extension:1.1",
"io.github.java-diff-utils:java-diff-utils:4.12",
"org.apache.ant:ant:1.10.11",
"org.jspecify:jspecify:0.2.0",
],
artifacts = MAVEN_ARTIFACTS,
repositories = [
"https://maven.google.com",
"https://repo1.maven.org/maven2",
Expand Down
30 changes: 30 additions & 0 deletions license_check/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2020 Google LLC
#
# Licensed 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
#
# https://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.

package(licenses = ["notice"])

exports_files([
"maven_artifacts.bzl",
"THIRD_PARTY_NOTICES",
])

sh_test(
name = "third_party_license_test",
srcs = ["third_party_license_test.sh"],
data = [
":THIRD_PARTY_NOTICES",
":maven_artifacts.bzl",
":third_party_license_test.py",
],
)
1,855 changes: 1,855 additions & 0 deletions license_check/THIRD_PARTY_NOTICES

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions license_check/maven_artifacts.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""List of external dependencies from Maven."""

MAVEN_ARTIFACTS = [
"args4j:args4j:2.33",
"com.google.code.gson:gson:2.9.1",
"com.google.errorprone:error_prone_annotations:2.15.0",
"com.google.guava:failureaccess:1.0.1",
"com.google.guava:guava:32.1.2-jre",
"com.google.guava:guava-testlib:32.1.2-jre",
"com.google.jimfs:jimfs:1.2",
"com.google.protobuf:protobuf-java:3.21.12",
"com.google.re2j:re2j:1.3",
"com.google.truth.extensions:truth-liteproto-extension:1.1",
"com.google.truth.extensions:truth-proto-extension:1.1",
"io.github.java-diff-utils:java-diff-utils:4.12",
"org.apache.ant:ant:1.10.11",
"org.jspecify:jspecify:0.2.0",
]

ORDERED_POM_OR_GRADLE_FILE_LIST = [
"https://github.com/kohsuke/args4j/blob/master/args4j/pom.xml",
"https://github.com/google/gson/blob/main/gson/pom.xml",
"https://github.com/google/error-prone/blob/master/annotations/pom.xml",
"https://github.com/google/guava/blob/master/futures/failureaccess/pom.xml",
"https://github.com/google/guava/blob/master/guava/pom.xml",
"https://github.com/google/guava/blob/master/guava-testlib/pom.xml",
"https://github.com/google/jimfs/blob/master/jimfs/pom.xml",
"https://github.com/protocolbuffers/protobuf/blob/main/java/core/pom.xml",
"https://github.com/google/re2j/blob/master/build.gradle",
"https://github.com/google/truth/blob/master/extensions/liteproto/pom.xml",
"https://github.com/google/truth/blob/master/extensions/proto/pom.xml",
"https://github.com/java-diff-utils/java-diff-utils/blob/master/java-diff-utils/pom.xml",
"https://github.com/apache/ant/blob/master/src/etc/poms/ant/pom.xml",
"https://github.com/jspecify/jspecify/blob/main/gradle/publish.gradle",
]
243 changes: 243 additions & 0 deletions license_check/third_party_license_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
"""Check and generate the licenses for third party dependencies.
This script generates the THIRD_PARTY_NOTICES file, which is the licenses
for all our external dependencies. It reads the maven_artifacts.bzl
file, compares the pom.xml and gradle files with the jar file list,
and then generates the license file.
"""

import argparse
import sys
import xml.etree.ElementTree as ET
import requests

# Constants
GITHUB_PREFIX = 'https://github.com/'
RAW_FILE_PREFIX = 'https://raw.githubusercontent.com/'

POM_FILE_SUFFIX = '.xml'
GRADLE_FILE_SUFFIX = '.gradle'

SPACER = """
===============================================================================
===============================================================================
===============================================================================
"""


def get_file_from_github(github_url):
raw_file_url_with_blob = github_url.replace(GITHUB_PREFIX, RAW_FILE_PREFIX)

raw_file_url = ''
branch_roots = ['master/', 'main/']

for br in branch_roots:
if br in raw_file_url_with_blob:
split_url = raw_file_url_with_blob.split(br)
raw_file_url = split_url[0][:-5] + br + split_url[1]
break

if not raw_file_url:
return None

response = requests.get(raw_file_url)

if response.status_code != 200:
return None

return response.text


def get_pom_artifact_name(pom_xml_github_url):
pom_xml_content = get_file_from_github(pom_xml_github_url)
if pom_xml_content is None:
print('Github Returned Error status when reading :', pom_xml_github_url)
sys.exit(1)

root = ET.fromstring(pom_xml_content)
ns = {'mvn': 'http://maven.apache.org/POM/4.0.0'}

parent = root.find('mvn:parent', ns)
group_id = parent.find('mvn:groupId', ns).text
artifact_id = root.find('mvn:artifactId', ns).text

return '%s:%s' % (group_id, artifact_id)


def get_grad_rval(line):
return (line.split()[-1]).strip("'")


def get_gradle_artifact_name(url):
content = get_file_from_github(url)

group_id = ''
artifact_id = ''

for line in content.splitlines():
if 'groupId' in line:
group_id = get_grad_rval(line)
if 'artifactId' in line:
artifact_id = get_grad_rval(line)

return '%s:%s' % (group_id, artifact_id)


def get_github_root_url(url):
branch_roots = ['master/', 'main/']
github_root = ''

for br in branch_roots:
if br in url:
split_url = url.split(br)
github_root = split_url[0] + br

if not github_root:
print(
'Cannot find the main branch root directory for the pom/gradle ',
'file: ',
url,
)
sys.exit(1)

return github_root


def get_license_from_pom(url):
github_branch_root = get_github_root_url(url)
license_filenames = ['LICENSE', 'COPYING']

license_content = None
license_url = ''

for filename in license_filenames:
license_url = github_branch_root + filename
license_content = get_file_from_github(license_url)
if license_content is not None:
break

if license_content is None:
print('Cannot get license information for pom/gradle file: ', url)
sys.exit(1)

return (license_url, license_content)


def main():
parser = argparse.ArgumentParser(
prog='ThirdPartyLicenseTest',
description='Checks if the third party licenses are up to date',
epilog='',
)

parser.add_argument(
'maven_artifacts_file',
help='path to the bzl file with the list of maven artifacts.',
)
parser.add_argument(
'third_party_notices_file', help='path to the THIRD_PARTY_NOTICES file.'
)
parser.add_argument(
'-u',
'--update',
action='store_true',
help='Update THIRD_PARTY_NOTICES with the new content.',
)
args = parser.parse_args()

# Read maven_artifacts.bzl
bzl_file_contents = open(args.maven_artifacts_file).read()

# Work around a python3 bug with exec and local variables
ldict = {}
exec(bzl_file_contents, globals(), ldict) # pylint: disable=exec-used
maven_artifacts = ldict['MAVEN_ARTIFACTS']
pom_gradle_filelist = ldict['ORDERED_POM_OR_GRADLE_FILE_LIST']

# Compare list lengths
if len(maven_artifacts) != len(pom_gradle_filelist):
print(
'artifact list length and pom/gradle file list length is not equal. ',
'Please check the file :',
args.maven_artifacts_file,
)
sys.exit(1)

package_name_to_pom = {}

# Compare pom/gradle artifact names with maven jar files
artifact_list_from_github = []
for url in pom_gradle_filelist:
if url.endswith(POM_FILE_SUFFIX):
tmp = get_pom_artifact_name(url)
artifact_list_from_github.append(tmp)
package_name_to_pom[tmp] = url
elif url.endswith(GRADLE_FILE_SUFFIX):
tmp = get_gradle_artifact_name(url)
artifact_list_from_github.append(tmp)
package_name_to_pom[tmp] = url
else:
print('Neither a Pom, nor a Gradle a file found in the list. exiting.')
sys.exit(1)

artifact_list_from_maven = []
for artifact_name in maven_artifacts:
split_artifact_name = artifact_name.split(':')
artifact_list_from_maven.append(
'%s:%s' % (split_artifact_name[0], split_artifact_name[1])
)

if artifact_list_from_github != artifact_list_from_maven:
print('Artifact names from github and maven are different.')
print('Github artifact list: ', artifact_list_from_github)
print('Maven artifact list: ', artifact_list_from_maven)
sys.exit(1)

license_url_to_package = {}
license_url_to_content = {}
# Create a dictionary of license names to maven jar files
for package in artifact_list_from_github:
(license_url, license_content) = get_license_from_pom(
package_name_to_pom[package]
)
if license_url in license_url_to_package:
license_url_to_package[license_url].append(package)
else:
license_url_to_package[license_url] = [package]
license_url_to_content[license_url] = license_content

# Create THIRD_PARTY_NOTICES
third_party_notices_content = ''
for license_url in license_url_to_package:
third_party_notices_content += 'License for package(s): ' + str(
license_url_to_package[license_url]
)
third_party_notices_content += '\n\n'
third_party_notices_content += license_url_to_content[license_url]
third_party_notices_content += SPACER

# Compare or Write out THIRD_PARTY_NOTICES file
if args.update:
fh = open(args.third_party_notices_file, 'w')
fh.write(third_party_notices_content)
fh.close()
sys.exit()

else:
old_third_party_notices_content = open(args.third_party_notices_file).read()
if old_third_party_notices_content == third_party_notices_content:
sys.exit()
else:
print('Changes detected in THIRD_PARTY_NOTICES file!')
print('Please run the following command to update the license file: \n')
print(' python3 \\')
print(' third_party/third_party_license_test.py \\')
print(' third_party/maven_artifacts.bzl \\')
print(' third_party/THIRD_PARTY_NOTICES --update')
sys.exit(1)


if __name__ == '__main__':
main()
7 changes: 7 additions & 0 deletions license_check/third_party_license_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

set -e

ROOT_DIR=${TEST_SRCDIR}/com_google_javascript_jscomp/third_party/

python3 ${ROOT_DIR}/third_party_license_test.py ${ROOT_DIR}/maven_artifacts.bzl ${ROOT_DIR}/THIRD_PARTY_NOTICES "${@:2}"

0 comments on commit 6dcbaad

Please sign in to comment.