1*bcb5dc79SHONG Yifan# Copyright 2022 The Bazel Authors. All rights reserved. 2*bcb5dc79SHONG Yifan# 3*bcb5dc79SHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License"); 4*bcb5dc79SHONG Yifan# you may not use this file except in compliance with the License. 5*bcb5dc79SHONG Yifan# You may obtain a copy of the License at 6*bcb5dc79SHONG Yifan# 7*bcb5dc79SHONG Yifan# http://www.apache.org/licenses/LICENSE-2.0 8*bcb5dc79SHONG Yifan# 9*bcb5dc79SHONG Yifan# Unless required by applicable law or agreed to in writing, software 10*bcb5dc79SHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS, 11*bcb5dc79SHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*bcb5dc79SHONG Yifan# See the License for the specific language governing permissions and 13*bcb5dc79SHONG Yifan# limitations under the License. 14*bcb5dc79SHONG Yifan 15*bcb5dc79SHONG Yifan"""Skylib module containing common functions for working with native.subpackages() 16*bcb5dc79SHONG Yifan""" 17*bcb5dc79SHONG Yifan_SUBPACKAGES_SUPPORTED = hasattr(native, "subpackages") 18*bcb5dc79SHONG Yifan 19*bcb5dc79SHONG Yifandef _supported(): 20*bcb5dc79SHONG Yifan return _SUBPACKAGES_SUPPORTED 21*bcb5dc79SHONG Yifan 22*bcb5dc79SHONG Yifandef _check_supported(): 23*bcb5dc79SHONG Yifan if not _SUBPACKAGES_SUPPORTED: 24*bcb5dc79SHONG Yifan fail("native.subpackages not supported in this version of Bazel.") 25*bcb5dc79SHONG Yifan 26*bcb5dc79SHONG Yifandef _all(exclude = [], allow_empty = False, fully_qualified = True): 27*bcb5dc79SHONG Yifan """List all direct subpackages of the current package regardless of directory depth. 28*bcb5dc79SHONG Yifan 29*bcb5dc79SHONG Yifan The returned list contains all subpackages, but not subpackages of subpackages. 30*bcb5dc79SHONG Yifan 31*bcb5dc79SHONG Yifan Example: 32*bcb5dc79SHONG Yifan Assuming the following BUILD files exist: 33*bcb5dc79SHONG Yifan 34*bcb5dc79SHONG Yifan BUILD 35*bcb5dc79SHONG Yifan foo/BUILD 36*bcb5dc79SHONG Yifan foo/sub/BUILD 37*bcb5dc79SHONG Yifan bar/BUILD 38*bcb5dc79SHONG Yifan baz/deep/dir/BUILD 39*bcb5dc79SHONG Yifan 40*bcb5dc79SHONG Yifan If the current package is '//' all() will return ['//foo', '//bar', 41*bcb5dc79SHONG Yifan '//baz/deep/dir']. //foo/sub is not included because it is a direct 42*bcb5dc79SHONG Yifan subpackage of '//foo' not '//' 43*bcb5dc79SHONG Yifan 44*bcb5dc79SHONG Yifan NOTE: fail()s if native.subpackages() is not supported. 45*bcb5dc79SHONG Yifan 46*bcb5dc79SHONG Yifan Args: 47*bcb5dc79SHONG Yifan exclude: see native.subpackages(exclude) 48*bcb5dc79SHONG Yifan allow_empty: see native.subpackages(allow_empty) 49*bcb5dc79SHONG Yifan fully_qualified: It true return fully qualified Labels for subpackages, 50*bcb5dc79SHONG Yifan otherwise returns subpackage path relative to current package. 51*bcb5dc79SHONG Yifan 52*bcb5dc79SHONG Yifan Returns: 53*bcb5dc79SHONG Yifan A mutable sorted list containing all sub-packages of the current Bazel 54*bcb5dc79SHONG Yifan package. 55*bcb5dc79SHONG Yifan """ 56*bcb5dc79SHONG Yifan _check_supported() 57*bcb5dc79SHONG Yifan 58*bcb5dc79SHONG Yifan subs = native.subpackages(include = ["**"], exclude = exclude, allow_empty = allow_empty) 59*bcb5dc79SHONG Yifan if fully_qualified: 60*bcb5dc79SHONG Yifan return [_fully_qualified(s) for s in subs] 61*bcb5dc79SHONG Yifan 62*bcb5dc79SHONG Yifan return subs 63*bcb5dc79SHONG Yifan 64*bcb5dc79SHONG Yifandef _fully_qualified(relative_path): 65*bcb5dc79SHONG Yifan return "//%s/%s" % (native.package_name(), relative_path) 66*bcb5dc79SHONG Yifan 67*bcb5dc79SHONG Yifandef _exists(relative_path): 68*bcb5dc79SHONG Yifan """Checks to see if relative_path is a direct subpackage of the current package. 69*bcb5dc79SHONG Yifan 70*bcb5dc79SHONG Yifan Example: 71*bcb5dc79SHONG Yifan 72*bcb5dc79SHONG Yifan BUILD 73*bcb5dc79SHONG Yifan foo/BUILD 74*bcb5dc79SHONG Yifan foo/sub/BUILD 75*bcb5dc79SHONG Yifan 76*bcb5dc79SHONG Yifan If the current package is '//' (the top-level BUILD file): 77*bcb5dc79SHONG Yifan subpackages.exists("foo") == True 78*bcb5dc79SHONG Yifan subpackages.exists("foo/sub") == False 79*bcb5dc79SHONG Yifan subpackages.exists("bar") == False 80*bcb5dc79SHONG Yifan 81*bcb5dc79SHONG Yifan NOTE: fail()s if native.subpackages() is not supported in the current Bazel version. 82*bcb5dc79SHONG Yifan 83*bcb5dc79SHONG Yifan Args: 84*bcb5dc79SHONG Yifan relative_path: a path to a subpackage to test, must not be an absolute Label. 85*bcb5dc79SHONG Yifan 86*bcb5dc79SHONG Yifan Returns: 87*bcb5dc79SHONG Yifan True if 'relative_path' is a subpackage of the current package. 88*bcb5dc79SHONG Yifan """ 89*bcb5dc79SHONG Yifan _check_supported() 90*bcb5dc79SHONG Yifan return relative_path in native.subpackages(include = [relative_path], allow_empty = True) 91*bcb5dc79SHONG Yifan 92*bcb5dc79SHONG Yifansubpackages = struct( 93*bcb5dc79SHONG Yifan all = _all, 94*bcb5dc79SHONG Yifan exists = _exists, 95*bcb5dc79SHONG Yifan supported = _supported, 96*bcb5dc79SHONG Yifan) 97