1# Copyright 2022 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 15"""Skylib module containing common functions for working with native.subpackages() 16""" 17_SUBPACKAGES_SUPPORTED = hasattr(native, "subpackages") 18 19def _supported(): 20 return _SUBPACKAGES_SUPPORTED 21 22def _check_supported(): 23 if not _SUBPACKAGES_SUPPORTED: 24 fail("native.subpackages not supported in this version of Bazel.") 25 26def _all(exclude = [], allow_empty = False, fully_qualified = True): 27 """List all direct subpackages of the current package regardless of directory depth. 28 29 The returned list contains all subpackages, but not subpackages of subpackages. 30 31 Example: 32 Assuming the following BUILD files exist: 33 34 BUILD 35 foo/BUILD 36 foo/sub/BUILD 37 bar/BUILD 38 baz/deep/dir/BUILD 39 40 If the current package is '//' all() will return ['//foo', '//bar', 41 '//baz/deep/dir']. //foo/sub is not included because it is a direct 42 subpackage of '//foo' not '//' 43 44 NOTE: fail()s if native.subpackages() is not supported. 45 46 Args: 47 exclude: see native.subpackages(exclude) 48 allow_empty: see native.subpackages(allow_empty) 49 fully_qualified: It true return fully qualified Labels for subpackages, 50 otherwise returns subpackage path relative to current package. 51 52 Returns: 53 A mutable sorted list containing all sub-packages of the current Bazel 54 package. 55 """ 56 _check_supported() 57 58 subs = native.subpackages(include = ["**"], exclude = exclude, allow_empty = allow_empty) 59 if fully_qualified: 60 return [_fully_qualified(s) for s in subs] 61 62 return subs 63 64def _fully_qualified(relative_path): 65 return "//%s/%s" % (native.package_name(), relative_path) 66 67def _exists(relative_path): 68 """Checks to see if relative_path is a direct subpackage of the current package. 69 70 Example: 71 72 BUILD 73 foo/BUILD 74 foo/sub/BUILD 75 76 If the current package is '//' (the top-level BUILD file): 77 subpackages.exists("foo") == True 78 subpackages.exists("foo/sub") == False 79 subpackages.exists("bar") == False 80 81 NOTE: fail()s if native.subpackages() is not supported in the current Bazel version. 82 83 Args: 84 relative_path: a path to a subpackage to test, must not be an absolute Label. 85 86 Returns: 87 True if 'relative_path' is a subpackage of the current package. 88 """ 89 _check_supported() 90 return relative_path in native.subpackages(include = [relative_path], allow_empty = True) 91 92subpackages = struct( 93 all = _all, 94 exists = _exists, 95 supported = _supported, 96) 97