Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2fb9a2a

Browse filesBrowse files
authored
feat(py_wheel): Add support for specifying Project-URL in METADATA (bazel-contrib#1276)
`Project-URL` is a field available in core metadata since version 1.2, which allows specifying additional URLs and display as Project Links in PyPI package web page. https://packaging.python.org/en/latest/specifications/core-metadata/#project-url-multiple-use This change adds the support to specify that.
1 parent 643a14b commit 2fb9a2a
Copy full SHA for 2fb9a2a

File tree

6 files changed

+78
-3
lines changed
Filter options

6 files changed

+78
-3
lines changed

‎docs/packaging.md

Copy file name to clipboardExpand all lines: docs/packaging.md
+3-2Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/wheel/BUILD.bazel

Copy file name to clipboardExpand all lines: examples/wheel/BUILD.bazel
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ py_wheel(
157157
},
158158
homepage = "www.example.com",
159159
license = "Apache 2.0",
160+
project_urls = {
161+
"Bug Tracker": "www.example.com/issues",
162+
"Documentation": "www.example.com/docs",
163+
},
160164
python_tag = "py3",
161165
# Requirements embedded into the wheel metadata.
162166
requires = ["pytest"],

‎examples/wheel/wheel_test.py

Copy file name to clipboardExpand all lines: examples/wheel/wheel_test.py
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_customized_wheel(self):
9999
record_contents,
100100
# The entries are guaranteed to be sorted.
101101
b"""\
102-
example_customized-0.0.1.dist-info/METADATA,sha256=vRiyyV45PC5fzK_40nSTtIn3yYzDdsbBAbUvkZiRyc8,461
102+
example_customized-0.0.1.dist-info/METADATA,sha256=QYQcDJFQSIqan8eiXqL67bqsUfgEAwf2hoK_Lgi1S-0,559
103103
example_customized-0.0.1.dist-info/NOTICE,sha256=Xpdw-FXET1IRgZ_wTkx1YQfo1-alET0FVf6V1LXO4js,76
104104
example_customized-0.0.1.dist-info/README,sha256=WmOFwZ3Jga1bHG3JiGRsUheb4UbLffUxyTdHczS27-o,40
105105
example_customized-0.0.1.dist-info/RECORD,,
@@ -131,6 +131,8 @@ def test_customized_wheel(self):
131131
License: Apache 2.0
132132
Description-Content-Type: text/markdown
133133
Summary: A one-line summary of this test package
134+
Project-URL: Bug Tracker, www.example.com/issues
135+
Project-URL: Documentation, www.example.com/docs
134136
Classifier: License :: OSI Approved :: Apache Software License
135137
Classifier: Intended Audience :: Developers
136138
Requires-Dist: pytest

‎python/private/py_wheel.bzl

Copy file name to clipboardExpand all lines: python/private/py_wheel.bzl
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ _other_attrs = {
176176
doc = "A string specifying the license of the package.",
177177
default = "",
178178
),
179+
"project_urls": attr.string_dict(
180+
doc = ("A string dict specifying additional browsable URLs for the project and corresponding labels, " +
181+
"where label is the key and url is the value. " +
182+
'e.g `{{"Bug Tracker": "http://bitbucket.org/tarek/distribute/issues/"}}`'),
183+
),
179184
"python_requires": attr.string(
180185
doc = (
181186
"Python versions required by this distribution, e.g. '>=3.5,<3.7'"
@@ -191,6 +196,7 @@ _other_attrs = {
191196
),
192197
}
193198

199+
_PROJECT_URL_LABEL_LENGTH_LIMIT = 32
194200
_DESCRIPTION_FILE_EXTENSION_TO_TYPE = {
195201
"md": "text/markdown",
196202
"rst": "text/x-rst",
@@ -301,6 +307,11 @@ def _py_wheel_impl(ctx):
301307
if ctx.attr.summary:
302308
metadata_contents.append("Summary: %s" % ctx.attr.summary)
303309

310+
for label, url in sorted(ctx.attr.project_urls.items()):
311+
if len(label) > _PROJECT_URL_LABEL_LENGTH_LIMIT:
312+
fail("`label` {} in `project_urls` is too long. It is limited to {} characters.".format(len(label), _PROJECT_URL_LABEL_LENGTH_LIMIT))
313+
metadata_contents.append("Project-URL: %s, %s" % (label, url))
314+
304315
for c in ctx.attr.classifiers:
305316
metadata_contents.append("Classifier: %s" % c)
306317

+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2023 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""Tests for py_wheel."""
15+
16+
load(":py_wheel_tests.bzl", "py_wheel_test_suite")
17+
18+
py_wheel_test_suite(name = "py_wheel_tests")
+39Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Test for py_wheel."""
2+
3+
load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
4+
load("@rules_testing//lib:truth.bzl", "matching")
5+
load("@rules_testing//lib:util.bzl", rt_util = "util")
6+
load("//python:packaging.bzl", "py_wheel")
7+
load("//tools/build_defs/python/tests:util.bzl", pt_util = "util")
8+
9+
_tests = []
10+
11+
def _test_too_long_project_url_label(name, config):
12+
rt_util.helper_target(
13+
config.rule,
14+
name = name + "_wheel",
15+
distribution = name + "_wheel",
16+
python_tag = "py3",
17+
version = "0.0.1",
18+
project_urls = {"This is a label whose length is above the limit!": "www.example.com"},
19+
)
20+
analysis_test(
21+
name = name,
22+
target = name + "_wheel",
23+
impl = _test_too_long_project_url_label_impl,
24+
expect_failure = True,
25+
)
26+
27+
def _test_too_long_project_url_label_impl(env, target):
28+
env.expect.that_target(target).failures().contains_predicate(
29+
matching.str_matches("in `project_urls` is too long"),
30+
)
31+
32+
_tests.append(_test_too_long_project_url_label)
33+
34+
def py_wheel_test_suite(name):
35+
config = struct(rule = py_wheel, base_test_rule = py_wheel)
36+
native.test_suite(
37+
name = name,
38+
tests = pt_util.create_tests(_tests, config = config),
39+
)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.