diff --git a/build_defs/python.build_defs b/build_defs/python.build_defs index 2435ac29..97af2a5b 100644 --- a/build_defs/python.build_defs +++ b/build_defs/python.build_defs @@ -440,7 +440,7 @@ def pip_library(name:str, version:str, labels:list=[], hashes:list=None, package repo = repo or CONFIG.PYTHON.DEFAULT_PIP_REPO if repo: if looks_like_build_label(repo): # Looks like a build label, not a URL. - repo_flag = f'-f %(location {repo})' + repo_flag = f'-f $(location {repo})' deps += [repo] else: repo_flag = '-f ' + repo @@ -507,6 +507,7 @@ def pip_library(name:str, version:str, labels:list=[], hashes:list=None, package test_only = test_only, output_dirs = [pip_target_dir], srcs = patches if patch else [], + deps = [repo] if looks_like_build_label(repo) else [], building_description = 'Fetching...', tools = tools, sandbox = False, @@ -516,7 +517,7 @@ def pip_library(name:str, version:str, labels:list=[], hashes:list=None, package # Don't include the dependency whl's into our whl. They are later picked up by py_binary anyway. cmd = f'$TOOLS_ARCAT z --suffix="" --exclude_suffix=whl --include_other -i . -r $PKG/{name}:$PKG' if not licences: - cmd += ' && find . -name METADATA -or -name PKG-INFO | grep -v "^./build/" | xargs grep -E "License ?:" | grep -v UNKNOWN | cat || true' + cmd += ' && find . -name METADATA -or -name PKG-INFO | grep -v "^./build/" | xargs grep -E "License(-Expression)? ?:" | grep -v UNKNOWN | cat || true' return build_rule( name = name, @@ -661,7 +662,7 @@ def python_wheel(name:str, version:str, labels:list=[], hashes:list=None, packag cmd += ['find . %s | xargs rm -rf' % ' -or '.join(['-name "%s"' % s for s in strip])] if not licences: cmd += ['find . -name METADATA -or -name PKG-INFO | grep -v "^./build/" | ' - 'xargs grep -hE "License ?:" | grep -v UNKNOWN | cat || true'] + 'xargs grep -hE "License(-Expression)? ?:" | grep -v UNKNOWN | cat || true'] if patch: patches, c = _patch_cmd(patch) cmd += c @@ -848,6 +849,9 @@ def _add_licences(name, output): # section still seems to know what they are licenced as. add_licence(name, line.split(' :: ')[-1]) found = True + elif line.startswith('License-Expression: '): + add_licence(name, line.removeprefix('License-Expression: ')) + found = True if not found: name = name.lstrip('_').split('#')[0] msg = f'No licence found for {name}, should add licences = [...] to the rule' diff --git a/test/BUILD b/test/BUILD index d12cad3f..91fd408c 100644 --- a/test/BUILD +++ b/test/BUILD @@ -152,6 +152,14 @@ plugin_e2e_test( }, ) +# Test that pip_library correctly auto-detects licences from a PEP 639 `License-Expression:` +# metadata field (as well as the legacy `License:` field). +plugin_e2e_test( + name = "pip_library_license_expression_test", + repo = "license_expression_repo", + test_cmd = "plz build //third_party/python:fakepkg", +) + # Test that python_wheel targets can have name_scheme as a list or a string python_test( diff --git a/test/license_expression_repo/.plzconfig b/test/license_expression_repo/.plzconfig new file mode 100644 index 00000000..e5f64a6a --- /dev/null +++ b/test/license_expression_repo/.plzconfig @@ -0,0 +1,3 @@ +[Plugin "python"] +Target = //plugins:python +RequireLicences = true diff --git a/test/license_expression_repo/plugins/BUILD_FILE b/test/license_expression_repo/plugins/BUILD_FILE new file mode 100644 index 00000000..bd8b3fd9 --- /dev/null +++ b/test/license_expression_repo/plugins/BUILD_FILE @@ -0,0 +1,4 @@ +plugin_repo( + name = "python", + revision = "e2e", +) diff --git a/test/license_expression_repo/third_party/python/BUILD_FILE b/test/license_expression_repo/third_party/python/BUILD_FILE new file mode 100644 index 00000000..35d639ab --- /dev/null +++ b/test/license_expression_repo/third_party/python/BUILD_FILE @@ -0,0 +1,33 @@ +subinclude("///python//build_defs:python") + +package( + # The pip_library target below installs from a local wheelhouse fixture, not the network - + # make sure we don't accidentally try to look it up on PyPI. + python = { + "use_pypi": False, + }, +) + +# Builds a fixture wheel from plain-text sources whose METADATA only declares a PEP 639 +# `License-Expression:` field (no legacy `License:` or `Classifier: License`), to exercise +# pip_library's auto-detection of that field. +genrule( + name = "fakepkg_whl", + srcs = ["fakepkg_src"], + outs = ["fakepkg-1.0.0-py3-none-any.whl"], + cmd = "cd $SRC && $TOOLS_ARCAT z -d -i . -o $OUT", + tools = {"arcat": [CONFIG.ARCAT_TOOL]}, +) + +genrule( + name = "wheelhouse", + srcs = [":fakepkg_whl"], + cmd = "mkdir -p wheelhouse && cp $SRCS wheelhouse/", + output_dirs = ["wheelhouse"], +) + +pip_library( + name = "fakepkg", + repo = ":wheelhouse", + version = "1.0.0", +) diff --git a/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/METADATA b/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/METADATA new file mode 100644 index 00000000..c2444db9 --- /dev/null +++ b/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/METADATA @@ -0,0 +1,4 @@ +Metadata-Version: 2.4 +Name: fakepkg +Version: 1.0.0 +License-Expression: MIT diff --git a/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/RECORD b/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/RECORD new file mode 100644 index 00000000..c6a9efec --- /dev/null +++ b/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/RECORD @@ -0,0 +1,4 @@ +fakepkg/__init__.py,, +fakepkg-1.0.0.dist-info/METADATA,, +fakepkg-1.0.0.dist-info/WHEEL,, +fakepkg-1.0.0.dist-info/RECORD,, diff --git a/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/WHEEL b/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/WHEEL new file mode 100644 index 00000000..d3aa0df6 --- /dev/null +++ b/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg-1.0.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: fixture +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg/__init__.py b/test/license_expression_repo/third_party/python/fakepkg_src/fakepkg/__init__.py new file mode 100644 index 00000000..e69de29b