• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2022 Google LLC
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# https://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"""Rules for declaring metadata about a package."""
15
16load(
17    "@rules_license//rules:providers.bzl",
18    "ExperimentalMetadataInfo",
19    "PackageInfo",
20)
21
22#
23# package_info()
24#
25
26def _package_info_impl(ctx):
27    provider = PackageInfo(
28        # Metadata providers must include a type discriminator. We don't need it
29        # to collect the providers, but we do need it to write the JSON. We
30        # key on the type field to look up the correct block of code to pull
31        # data out and format it. We can't to the lookup on the provider class.
32        type = "package_info",
33        label = ctx.label,
34        package_name = ctx.attr.package_name or ctx.build_file_path.rstrip("/BUILD"),
35        package_url = ctx.attr.package_url,
36        package_version = ctx.attr.package_version,
37        purl = ctx.attr.purl,
38    )
39
40    # Experimental alternate design, using a generic 'data' back to hold things
41    generic_provider = ExperimentalMetadataInfo(
42        type = "package_info_alt",
43        label = ctx.label,
44        data = {
45            "package_name": ctx.attr.package_name or ctx.build_file_path.rstrip("/BUILD"),
46            "package_url": ctx.attr.package_url,
47            "package_version": ctx.attr.package_version,
48            "purl": ctx.attr.purl,
49        },
50    )
51    return [provider, generic_provider]
52
53_package_info = rule(
54    implementation = _package_info_impl,
55    attrs = {
56        "package_name": attr.string(
57            doc = "A human readable name identifying this package." +
58                  " This may be used to produce an index of OSS packages used by" +
59                  " an application.",
60        ),
61        "package_url": attr.string(
62            doc = "The URL this instance of the package was download from." +
63                  " This may be used to produce an index of OSS packages used by" +
64                  " an application.",
65        ),
66        "package_version": attr.string(
67            doc = "A human readable version string identifying this package." +
68                  " This may be used to produce an index of OSS packages used" +
69                  " by an application.  It should be a value that" +
70                  " increases over time, rather than a commit hash.",
71        ),
72        "purl": attr.string(
73            doc = "A pURL conforming to the spec outlined in" +
74                  " https://github.com/package-url/purl-spec. This may be used when" +
75                  " generating an SBOM.",
76        ),
77    },
78)
79
80# buildifier: disable=function-docstring-args
81def package_info(
82        name,
83        package_name = None,
84        package_url = None,
85        package_version = None,
86        purl = None,
87        **kwargs):
88    """Wrapper for package_info rule.
89
90    @wraps(_package_info)
91
92    The purl attribute should be a valid pURL, as defined in the
93    [pURL spec](https://github.com/package-url/purl-spec).
94
95    Args:
96      name: str target name.
97      package_name: str A human readable name identifying this package. This
98                    may be used to produce an index of OSS packages used by
99                    an application.
100      package_url: str The canoncial URL this package distribution was retrieved from.
101                       Note that, because of local mirroring, that might not be the
102                       physical URL it was retrieved from.
103      package_version: str A human readable name identifying version of this package.
104      purl: str The canonical pURL by which this package is known.
105      kwargs: other args. Most are ignored.
106    """
107    visibility = kwargs.get("visibility") or ["//visibility:public"]
108    _package_info(
109        name = name,
110        package_name = package_name,
111        package_url = package_url,
112        package_version = package_version,
113        purl = purl,
114        applicable_licenses = [],
115        visibility = visibility,
116        tags = [],
117        testonly = 0,
118    )
119