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