diff options
Diffstat (limited to 'tools/deps.bzl')
-rw-r--r-- | tools/deps.bzl | 119 |
1 files changed, 0 insertions, 119 deletions
diff --git a/tools/deps.bzl b/tools/deps.bzl deleted file mode 100644 index 91442617c..000000000 --- a/tools/deps.bzl +++ /dev/null @@ -1,119 +0,0 @@ -"""Rules for dependency checking.""" - -# DepsInfo provides a list of dependencies found when building a target. -DepsInfo = provider( - "lists dependencies encountered while building", - fields = { - "nodes": "a dict from targets to a list of their dependencies", - }, -) - -def _deps_check_impl(target, ctx): - # Check the target's dependencies and add any of our own deps. - deps = [] - for dep in ctx.rule.attr.deps: - deps.append(dep) - nodes = {} - if len(deps) != 0: - nodes[target] = deps - - # Keep and propagate each dep's providers. - for dep in ctx.rule.attr.deps: - nodes.update(dep[DepsInfo].nodes) - - return [DepsInfo(nodes = nodes)] - -_deps_check = aspect( - implementation = _deps_check_impl, - attr_aspects = ["deps"], -) - -def _is_allowed(target, allowlist, prefixes): - # Check for allowed prefixes. - for prefix in prefixes: - workspace, pfx = prefix.split("//", 1) - if len(workspace) > 0 and workspace[0] == "@": - workspace = workspace[1:] - if target.workspace_name == workspace and target.package.startswith(pfx): - return True - - # Check the allowlist. - for allowed in allowlist: - if target == allowed.label: - return True - - return False - -def _deps_test_impl(ctx): - nodes = {} - for target in ctx.attr.targets: - for (node_target, node_deps) in target[DepsInfo].nodes.items(): - # Ignore any disallowed targets. This generates more useful error - # messages. Consider the case where A dependes on B and B depends - # on C, and both B and C are disallowed. Avoid emitting an error - # that B depends on C, when the real issue is that A depends on B. - if not _is_allowed(node_target.label, ctx.attr.allowed, ctx.attr.allowed_prefixes) and node_target.label != target.label: - continue - bad_deps = [] - for dep in node_deps: - if not _is_allowed(dep.label, ctx.attr.allowed, ctx.attr.allowed_prefixes): - bad_deps.append(dep) - if len(bad_deps) > 0: - nodes[node_target] = bad_deps - - # If there aren't any violations, write a passing test. - if len(nodes) == 0: - ctx.actions.write( - output = ctx.outputs.executable, - content = "#!/bin/bash\n\nexit 0\n", - ) - return [] - - # If we're here, we've found at least one violation. - script_lines = [ - "#!/bin/bash", - "echo Invalid dependencies found. If you\\'re sure you want to add dependencies,", - "echo modify this target.", - "echo", - ] - - # List the violations. - for target, deps in nodes.items(): - script_lines.append( - 'echo "{target} depends on:"'.format(target = target.label), - ) - for dep in deps: - script_lines.append('echo "\t{dep}"'.format(dep = dep.label)) - - # The test must fail. - script_lines.append("exit 1\n") - - ctx.actions.write( - output = ctx.outputs.executable, - content = "\n".join(script_lines), - ) - return [] - -# Checks that targets only depend on an allowlist of other targets. Targets can -# be specified directly, or prefixes can be used to allow entire packages or -# directory trees. -# -# This recursively checks the "deps" attribute of each target, dependencies -# expressed other ways are not checked. For example, protobuf targets pull in -# protobuf code, but aren't analyzed by deps_test. -deps_test = rule( - implementation = _deps_test_impl, - attrs = { - "targets": attr.label_list( - doc = "The targets to check the transitive dependencies of.", - aspects = [_deps_check], - ), - "allowed": attr.label_list( - doc = "The allowed dependency targets.", - ), - "allowed_prefixes": attr.string_list( - doc = "Any packages beginning with these prefixes are allowed.", - ), - }, - test = True, -) |