1# Copyright 2020 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 15"""License compliance checking at analysis time.""" 16 17load( 18 "@rules_license//examples/policy_checker:license_policy_provider.bzl", 19 "LicensePolicyInfo", 20) 21load( 22 "@rules_license//rules:gather_licenses_info.bzl", 23 "gather_licenses_info", 24) 25load("@rules_license//rules:providers.bzl", "LicenseInfo") 26load("@rules_license//rules/private:gathering_providers.bzl", "TransitiveLicensesInfo") 27 28# This is a crude example of the kind of thing which can be done. 29def _license_policy_check_impl(ctx): 30 policy = ctx.attr.policy[LicensePolicyInfo] 31 allowed_conditions = policy.conditions 32 if TransitiveLicensesInfo in ctx.attr.target: 33 for license in ctx.attr.target[TransitiveLicensesInfo].licenses.to_list(): 34 for kind in license.license_kinds: 35 # print(kind.conditions) 36 for condition in kind.conditions: 37 if condition not in allowed_conditions: 38 fail("Condition %s violates policy %s" % ( 39 condition, 40 policy.label, 41 )) 42 43 if LicenseInfo in ctx.attr.target: 44 for license in ctx.attr.target[LicenseInfo].licenses.to_list(): 45 for kind in license.license_kinds: 46 # print(kind.conditions) 47 for condition in kind.conditions: 48 if condition not in allowed_conditions: 49 fail("Condition %s violates policy %s" % ( 50 condition, 51 policy.label, 52 )) 53 return [DefaultInfo()] 54 55_license_policy_check = rule( 56 implementation = _license_policy_check_impl, 57 doc = """Internal implementation method for license_policy_check().""", 58 attrs = { 59 "policy": attr.label( 60 doc = """Policy definition.""", 61 mandatory = True, 62 providers = [LicensePolicyInfo], 63 ), 64 "target": attr.label( 65 doc = """Target to collect LicenseInfo for.""", 66 aspects = [gather_licenses_info], 67 mandatory = True, 68 allow_single_file = True, 69 ), 70 }, 71) 72 73def license_policy_check(name, target, policy, **kwargs): 74 """Checks a target against a policy. 75 76 Args: 77 name: The target. 78 target: A target to test for compliance with a policy 79 policy: A rule providing LicensePolicyInfo. 80 **kwargs: other args. 81 82 Usage: 83 84 license_policy_check( 85 name = "license_info", 86 target = ":my_app", 87 policy = "//my_org/compliance/policies:mobile_application", 88 ) 89 """ 90 _license_policy_check(name = name, target = target, policy = policy, **kwargs) 91