1# Copyright 2017 The Abseil Authors. 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"""Internal helper for running tests on Windows Bazel.""" 16 17import os 18 19from absl import flags 20 21FLAGS = flags.FLAGS 22 23 24def get_executable_path(py_binary_name): 25 """Returns the executable path of a py_binary. 26 27 This returns the executable path of a py_binary that is in another Bazel 28 target's data dependencies. 29 30 On Linux/macOS, the path and __file__ has the same root directory. 31 On Windows, bazel builds an .exe file and we need to use the MANIFEST file 32 the location the actual binary. 33 34 Args: 35 py_binary_name: string, the name of a py_binary that is in another Bazel 36 target's data dependencies. 37 38 Raises: 39 RuntimeError: Raised when it cannot locate the executable path. 40 """ 41 42 if os.name == 'nt': 43 py_binary_name += '.exe' 44 manifest_file = os.path.join(FLAGS.test_srcdir, 'MANIFEST') 45 workspace_name = os.environ['TEST_WORKSPACE'] 46 manifest_entry = '{}/{}'.format(workspace_name, py_binary_name) 47 with open(manifest_file, 'r') as manifest_fd: 48 for line in manifest_fd: 49 tokens = line.strip().split(' ') 50 if len(tokens) != 2: 51 continue 52 if manifest_entry == tokens[0]: 53 return tokens[1] 54 raise RuntimeError( 55 'Cannot locate executable path for {}, MANIFEST file: {}.'.format( 56 py_binary_name, manifest_file)) 57 else: 58 # NOTE: __file__ may be .py or .pyc, depending on how the module was 59 # loaded and executed. 60 path = __file__ 61 62 # Use the package name to find the root directory: every dot is 63 # a directory, plus one for ourselves. 64 for _ in range(__name__.count('.') + 1): 65 path = os.path.dirname(path) 66 67 root_directory = path 68 return os.path.join(root_directory, py_binary_name) 69