diff options
author | William Deegan <bill@baddogconsulting.com> | 2024-11-25 04:47:03 (GMT) |
---|---|---|
committer | William Deegan <bill@baddogconsulting.com> | 2024-11-25 04:48:20 (GMT) |
commit | 8999666f07311ba025ee91e801c04dd2fd5adb96 (patch) | |
tree | 24df78c610ecef25ecd8f08862cc2aea44ce5658 | |
parent | c580a721ccabcf1fc9789e0a3f906cb2c08db0da (diff) | |
download | SCons-8999666f07311ba025ee91e801c04dd2fd5adb96.zip SCons-8999666f07311ba025ee91e801c04dd2fd5adb96.tar.gz SCons-8999666f07311ba025ee91e801c04dd2fd5adb96.tar.bz2 |
Fixed ninja binary location logic to use ninja.BIN_DIR. Previous logic no longer works starting with python ninja package version 1.11.1.2
26 files changed, 134 insertions, 180 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index e449bba..9642966 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -85,6 +85,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER via top-level `from __future__ import annotations`. - Implemented type hints for Nodes. + From William Deegan: + - Update ninja tool to use ninja.BIN_DIR to find pypi packaged ninja binary. + python ninja package version 1.11.1.2 changed the location and previous + logic no longer worked. + - Added ninja_binary() method to TestSCons to centralize logic to find ninja binary + From Alex James: - On Darwin, PermissionErrors are now handled while trying to access /etc/paths.d. This may occur if SCons is invoked in a sandboxed diff --git a/RELEASE.txt b/RELEASE.txt index 8e88a0b..4aa9697 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -140,6 +140,11 @@ FIXES - Make sure unknown variables from a Variables file are recognized as such (issue #4645) +- Update ninja tool to use ninja.BIN_DIR to find pypi packaged ninja binary. + python ninja package version 1.11.1.2 changed the location and previous + logic no longer worked. + + IMPROVEMENTS ------------ @@ -196,6 +201,8 @@ DEVELOPMENT - Implemented type hints for Nodes. +- Added ninja_binary() method to TestSCons to centralize logic to find ninja binary + Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== .. code-block:: text diff --git a/SCons/Tool/ninja/NinjaState.py b/SCons/Tool/ninja/NinjaState.py index 549af78..da7aa28 100644 --- a/SCons/Tool/ninja/NinjaState.py +++ b/SCons/Tool/ninja/NinjaState.py @@ -60,12 +60,11 @@ class NinjaState: if not self.ninja_bin_path: # default to using ninja installed with python module ninja_bin = 'ninja.exe' if env["PLATFORM"] == "win32" else 'ninja' + self.ninja_bin_path = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - ninja_bin)) + ninja.BIN_DIR, ninja_bin + )) + if not os.path.exists(self.ninja_bin_path): # couldn't find it, just give the bin name and hope # its in the path later @@ -398,7 +397,7 @@ class NinjaState: self.rules.update({key: non_rsp_rule}) else: self.rules.update({key: rule}) - + self.pools.update(self.env.get(NINJA_POOLS, {})) content = io.StringIO() @@ -435,7 +434,7 @@ class NinjaState: generated_source_files = sorted( [] if not generated_sources_build else generated_sources_build['implicit'] ) - + def check_generated_source_deps(build): return ( build != generated_sources_build @@ -464,7 +463,7 @@ class NinjaState: rule="phony", implicit=generated_source_files ) - + def check_generated_source_deps(build): return ( not build["rule"] == "INSTALL" @@ -661,7 +660,7 @@ class NinjaState: all_targets = [str(node) for node in NINJA_DEFAULT_TARGETS] else: all_targets = list(all_targets) - + if len(all_targets) == 0: all_targets = ["phony_default"] ninja_sorted_build( @@ -669,7 +668,7 @@ class NinjaState: outputs=all_targets, rule="phony", ) - + ninja.default([self.ninja_syntax.escape_path(path) for path in sorted(all_targets)]) with NamedTemporaryFile(delete=False, mode='w') as temp_ninja_file: diff --git a/test/ninja/build_libraries.py b/test/ninja/build_libraries.py index 0a1941a..0561f6f 100644 --- a/test/ninja/build_libraries.py +++ b/test/ninja/build_libraries.py @@ -23,8 +23,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import os - import TestSCons from TestCmd import IS_WINDOWS, IS_MACOS from TestSCons import _exe, _lib, lib_, _dll, dll_ @@ -36,12 +34,7 @@ try: except ImportError: test.skip_test("Could not find ninja module. Skipping test.\n") -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/command_line_targets.py b/test/ninja/command_line_targets.py index 9fa77ea..b043f62 100644 --- a/test/ninja/command_line_targets.py +++ b/test/ninja/command_line_targets.py @@ -36,12 +36,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/copy_function_command.py b/test/ninja/copy_function_command.py index 7e999b3..13036ee 100644 --- a/test/ninja/copy_function_command.py +++ b/test/ninja/copy_function_command.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/default_targets.py b/test/ninja/default_targets.py index 1b2f2b9..7752d5a 100644 --- a/test/ninja/default_targets.py +++ b/test/ninja/default_targets.py @@ -36,9 +36,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath( - os.path.join(ninja.__file__, os.pardir, 'data', 'bin', 'ninja' + _exe) -) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/force_scons_callback.py b/test/ninja/force_scons_callback.py index e0da0dd..b668f92 100644 --- a/test/ninja/force_scons_callback.py +++ b/test/ninja/force_scons_callback.py @@ -37,9 +37,8 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath( - os.path.join(ninja.__file__, os.pardir, "data", "bin", "ninja" + _exe) -) +ninja_bin = test.ninja_binary() + test.dir_fixture("ninja-fixture") diff --git a/test/ninja/generate_and_build.py b/test/ninja/generate_and_build.py index e1c26d4..c14af70 100644 --- a/test/ninja/generate_and_build.py +++ b/test/ninja/generate_and_build.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/generate_and_build_cxx.py b/test/ninja/generate_and_build_cxx.py index 074a5cb..51f68dc 100644 --- a/test/ninja/generate_and_build_cxx.py +++ b/test/ninja/generate_and_build_cxx.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/generate_source.py b/test/ninja/generate_source.py index 8300176..f4bd0c0 100644 --- a/test/ninja/generate_source.py +++ b/test/ninja/generate_source.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/generated_sources_alias.py b/test/ninja/generated_sources_alias.py index 2c4ed36..3e7f9d1 100644 --- a/test/ninja/generated_sources_alias.py +++ b/test/ninja/generated_sources_alias.py @@ -37,9 +37,8 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.BIN_DIR, - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() + test.dir_fixture('ninja-fixture') diff --git a/test/ninja/iterative_speedup.py b/test/ninja/iterative_speedup.py index e5673b0..8190175 100644 --- a/test/ninja/iterative_speedup.py +++ b/test/ninja/iterative_speedup.py @@ -39,12 +39,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/mingw_command_generator_action.py b/test/ninja/mingw_command_generator_action.py index 58c5106..8fc08a8 100644 --- a/test/ninja/mingw_command_generator_action.py +++ b/test/ninja/mingw_command_generator_action.py @@ -52,9 +52,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.BIN_DIR, - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/mingw_depfile_format.py b/test/ninja/mingw_depfile_format.py index 5de7b5f..e9c89a0 100644 --- a/test/ninja/mingw_depfile_format.py +++ b/test/ninja/mingw_depfile_format.py @@ -36,9 +36,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.BIN_DIR, - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/mkdir_function_command.py b/test/ninja/mkdir_function_command.py index 8a17623..c01cb98 100644 --- a/test/ninja/mkdir_function_command.py +++ b/test/ninja/mkdir_function_command.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.write('SConstruct', """ SetOption('experimental','ninja') diff --git a/test/ninja/multi_env.py b/test/ninja/multi_env.py index e5da6cf..6aaeccd 100644 --- a/test/ninja/multi_env.py +++ b/test/ninja/multi_env.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test = TestSCons.TestSCons() diff --git a/test/ninja/ninja_command_line.py b/test/ninja/ninja_command_line.py index d8e3c08..d6744aa 100644 --- a/test/ninja/ninja_command_line.py +++ b/test/ninja/ninja_command_line.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture', 'src') diff --git a/test/ninja/ninja_conftest.py b/test/ninja/ninja_conftest.py index 91d2e03..a92ecd9 100644 --- a/test/ninja/ninja_conftest.py +++ b/test/ninja/ninja_conftest.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/ninja_file_deterministic.py b/test/ninja/ninja_file_deterministic.py index 9832f22..232e7ab 100644 --- a/test/ninja/ninja_file_deterministic.py +++ b/test/ninja/ninja_file_deterministic.py @@ -39,9 +39,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.BIN_DIR, - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/ninja_handle_control_c_rebuild.py b/test/ninja/ninja_handle_control_c_rebuild.py index 9f6b413..5635367 100644 --- a/test/ninja/ninja_handle_control_c_rebuild.py +++ b/test/ninja/ninja_handle_control_c_rebuild.py @@ -23,7 +23,7 @@ # """ This test ensures if ninja gets a control-c (or other interrupting signal) while -regenerating the build.ninja, it doesn't remove the build.ninja leaving it +regenerating the build.ninja, it doesn't remove the build.ninja leaving it in an unworkable state. """ import os @@ -41,9 +41,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath( - os.path.join(ninja.__file__, os.pardir, "data", "bin", "ninja" + _exe) -) +ninja_bin = test.ninja_binary() test.dir_fixture("ninja-fixture") diff --git a/test/ninja/no_for_sig_subst.py b/test/ninja/no_for_sig_subst.py index a0292ae..da33f8d 100644 --- a/test/ninja/no_for_sig_subst.py +++ b/test/ninja/no_for_sig_subst.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/response_file.py b/test/ninja/response_file.py index 3d23c2b..e9f778a 100644 --- a/test/ninja/response_file.py +++ b/test/ninja/response_file.py @@ -42,12 +42,7 @@ _python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/shell_command.py b/test/ninja/shell_command.py index a6c48c4..0ed8f2a 100644 --- a/test/ninja/shell_command.py +++ b/test/ninja/shell_command.py @@ -37,12 +37,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath(os.path.join( - ninja.__file__, - os.pardir, - 'data', - 'bin', - 'ninja' + _exe)) +ninja_bin = test.ninja_binary() test.dir_fixture('ninja-fixture') diff --git a/test/ninja/shutdown_scons_daemon.py b/test/ninja/shutdown_scons_daemon.py index 64ec2c7..25823d7 100644 --- a/test/ninja/shutdown_scons_daemon.py +++ b/test/ninja/shutdown_scons_daemon.py @@ -44,9 +44,7 @@ except ImportError: _python_ = TestSCons._python_ _exe = TestSCons._exe -ninja_bin = os.path.abspath( - os.path.join(ninja.__file__, os.pardir, "data", "bin", "ninja" + _exe) -) +ninja_bin = test.ninja_binary() test.dir_fixture("ninja-fixture") diff --git a/testing/framework/TestSCons.py b/testing/framework/TestSCons.py index 51aa7cf..d6c5125 100644 --- a/testing/framework/TestSCons.py +++ b/testing/framework/TestSCons.py @@ -40,17 +40,14 @@ import os import re import shutil import sys -import time import subprocess as sp +import time import zipfile from collections import namedtuple +from SCons.Util import get_hash_format, get_current_hash_algorithm_used from TestCommon import * from TestCommon import __all__, _python_ -from SCons.Util import get_hash_format, get_current_hash_algorithm_used - -from TestCmd import Popen -from TestCmd import PIPE # Some tests which verify that SCons has been packaged properly need to # look for specific version file names. Replicating the version number @@ -224,6 +221,8 @@ def restore_sconsflags(sconsflags) -> None: # Helpers for Configure()'s config.log processing ConfigCheckInfo = namedtuple('ConfigCheckInfo', ['check_string', 'result', 'cached', 'temp_filename']) + + # check_string: the string output to for this checker # results : The expected results for each check # cached : If the corresponding check is expected to be cached @@ -234,6 +233,7 @@ class NoMatch(Exception): """ Exception for matchPart to indicate there was no match found in the passed logfile """ + def __init__(self, p) -> None: self.pos = p @@ -418,7 +418,8 @@ class TestSCons(TestCommon): return None - def wrap_stdout(self, build_str: str="", read_str: str="", error: int=0, cleaning: int=0) -> str: + def wrap_stdout(self, build_str: str = "", read_str: str = "", error: int = 0, + cleaning: int = 0) -> str: """Wraps "expect" strings in SCons boilerplate. Given strings of expected output specific to a test, @@ -444,11 +445,11 @@ class TestSCons(TestCommon): term = f"scons: done {lc}ing targets.\n" return "scons: Reading SConscript files ...\n" + \ - read_str + \ - "scons: done reading SConscript files.\n" + \ - f"scons: {cap}ing targets ...\n" + \ - build_str + \ - term + read_str + \ + "scons: done reading SConscript files.\n" + \ + f"scons: {cap}ing targets ...\n" + \ + build_str + \ + term def run(self, *args, **kw) -> None: """ @@ -484,7 +485,7 @@ class TestSCons(TestCommon): # kw['options'] = ' '.join(options) # TestCommon.run(self, *args, **kw) - def up_to_date(self, arguments: str='.', read_str: str="", **kw) -> None: + def up_to_date(self, arguments: str = '.', read_str: str = "", **kw) -> None: """Asserts that all of the targets listed in arguments is up to date, but does not make any assumptions on other targets. This function is most useful in conjunction with the -n option. @@ -500,7 +501,7 @@ class TestSCons(TestCommon): kw['match'] = self.match_re_dotall self.run(**kw) - def not_up_to_date(self, arguments: str='.', read_str: str="", **kw) -> None: + def not_up_to_date(self, arguments: str = '.', read_str: str = "", **kw) -> None: """Asserts that none of the targets listed in arguments is up to date, but does not make any assumptions on other targets. This function is most useful in conjunction with the -n option. @@ -510,7 +511,8 @@ class TestSCons(TestCommon): s = f"{s}(?!scons: `{re.escape(arg)}' is up to date.)" s = f"({s}[^\n]*\n)*" kw['arguments'] = arguments - stdout = re.escape(self.wrap_stdout(read_str=read_str, build_str='ARGUMENTSGOHERE')) + stdout = re.escape( + self.wrap_stdout(read_str=read_str, build_str='ARGUMENTSGOHERE')) kw['stdout'] = stdout.replace('ARGUMENTSGOHERE', s) kw['match'] = self.match_re_dotall self.run(**kw) @@ -619,15 +621,15 @@ class TestSCons(TestCommon): return warning - def diff_substr(self, expect, actual, prelen: int=20, postlen: int=40) -> str: + def diff_substr(self, expect, actual, prelen: int = 20, postlen: int = 40) -> str: i = 0 for x, y in zip(expect, actual): if x != y: return "Actual did not match expect at char %d:\n" \ " Expect: %s\n" \ " Actual: %s\n" \ - % (i, repr(expect[i - prelen:i + postlen]), - repr(actual[i - prelen:i + postlen])) + % (i, repr(expect[i - prelen:i + postlen]), + repr(actual[i - prelen:i + postlen])) i = i + 1 return "Actual matched the expected output???" @@ -671,7 +673,7 @@ class TestSCons(TestCommon): return s @staticmethod - def to_bytes_re_sub(pattern, repl, string, count: int=0, flags: int=0): + def to_bytes_re_sub(pattern, repl, string, count: int = 0, flags: int = 0): """ Wrapper around re.sub to change pattern and repl to bytes to work with both python 2 & 3 @@ -713,8 +715,9 @@ class TestSCons(TestCommon): d = zlib.decompress(s[b:e]) d = self.to_bytes_re_sub(r'%%CreationDate: [^\n]*\n', r'%%CreationDate: 1970 Jan 01 00:00:00\n', d) - d = self.to_bytes_re_sub(r'%DVIPSSource: TeX output \d\d\d\d\.\d\d\.\d\d:\d\d\d\d', - r'%DVIPSSource: TeX output 1970.01.01:0000', d) + d = self.to_bytes_re_sub( + r'%DVIPSSource: TeX output \d\d\d\d\.\d\d\.\d\d:\d\d\d\d', + r'%DVIPSSource: TeX output 1970.01.01:0000', d) d = self.to_bytes_re_sub(r'/(BaseFont|FontName) /[A-Z]{6}', r'/\1 /XXXXXX', d) r.append(d) @@ -754,10 +757,9 @@ class TestSCons(TestCommon): if hash_format is None and current_hash_algorithm == 'md5': return ".sconsign" else: - database_prefix=f".sconsign_{current_hash_algorithm}" + database_prefix = f".sconsign_{current_hash_algorithm}" return database_prefix - def unlink_sconsignfile(self, name: str = '.sconsign.dblite') -> None: """Delete the sconsign file. @@ -850,7 +852,8 @@ class TestSCons(TestCommon): '/usr/lib/jvm/default-java/include/jni.h', '/usr/lib/jvm/java-*-oracle/include/jni.h'] else: - jni_dirs = [f'/System/Library/Frameworks/JavaVM.framework/Versions/{version}*/Headers/jni.h'] + jni_dirs = [ + f'/System/Library/Frameworks/JavaVM.framework/Versions/{version}*/Headers/jni.h'] jni_dirs.extend([f'/usr/lib/jvm/java-*-sun-{version}*/include/jni.h', f'/usr/lib/jvm/java-{version}*-openjdk*/include/jni.h', f'/usr/java/jdk{version}*/include/jni.h']) @@ -975,7 +978,8 @@ class TestSCons(TestCommon): where_java = self.where_is('java', ENV['PATH']) if not where_java: - self.skip_test("Could not find Java java, skipping test(s).\n", from_fw=True) + self.skip_test("Could not find Java java, skipping test(s).\n", + from_fw=True) elif sys.platform == "darwin": self.java_mac_check(where_java, 'java') @@ -996,7 +1000,8 @@ class TestSCons(TestCommon): else: where_javac = self.where_is('javac', ENV['PATH']) if not where_javac: - self.skip_test("Could not find Java javac, skipping test(s).\n", from_fw=True) + self.skip_test("Could not find Java javac, skipping test(s).\n", + from_fw=True) elif sys.platform == "darwin": self.java_mac_check(where_javac, 'javac') @@ -1050,7 +1055,8 @@ class TestSCons(TestCommon): else: where_javah = self.where_is('javah', ENV['PATH']) if not where_javah: - self.skip_test("Could not find Java javah, skipping test(s).\n", from_fw=True) + self.skip_test("Could not find Java javah, skipping test(s).\n", + from_fw=True) return where_javah def java_where_rmic(self, version=None) -> str: @@ -1068,7 +1074,9 @@ class TestSCons(TestCommon): else: where_rmic = self.where_is('rmic', ENV['PATH']) if not where_rmic: - self.skip_test("Could not find Java rmic, skipping non-simulated test(s).\n", from_fw=True) + self.skip_test( + "Could not find Java rmic, skipping non-simulated test(s).\n", + from_fw=True) return where_rmic def java_get_class_files(self, dir): @@ -1079,7 +1087,16 @@ class TestSCons(TestCommon): result.append(os.path.join(dirpath, fname)) return sorted(result) - def Qt_dummy_installation(self, dir: str='qt') -> None: + def ninja_binary(self): + try: + import ninja + except ImportError: + return False + + return os.path.abspath(os.path.join(ninja.BIN_DIR, 'ninja' + _exe)) + + + def Qt_dummy_installation(self, dir: str = 'qt') -> None: # create a dummy qt installation self.subdir(dir, [dir, 'bin'], [dir, 'include'], [dir, 'lib']) @@ -1185,11 +1202,11 @@ else: self.QT_UIC = f"{_python_} {self.workpath(dir, 'bin', 'myuic.py')}" self.QT_LIB_DIR = self.workpath(dir, 'lib') - def Qt_create_SConstruct(self, place, qt_tool: str='qt3') -> None: + def Qt_create_SConstruct(self, place, qt_tool: str = 'qt3') -> None: if isinstance(place, list): place = self.workpath(*place) - var_prefix=qt_tool.upper() + var_prefix = qt_tool.upper() self.write(place, f"""\ if ARGUMENTS.get('noqtdir', 0): {var_prefix}DIR = None @@ -1239,7 +1256,7 @@ SConscript(sconscript) """ return 'COVERAGE_PROCESS_START' in os.environ or 'COVERAGE_FILE' in os.environ - def skip_if_not_msvc(self, check_platform: bool=True) -> None: + def skip_if_not_msvc(self, check_platform: bool = True) -> None: """ Skip test if MSVC is not available. Check whether we are on a Windows platform and skip the test if @@ -1264,10 +1281,10 @@ SConscript(sconscript) pass def checkConfigureLogAndStdout(self, checks, - logfile: str='config.log', - sconf_dir: str='.sconf_temp', - sconstruct: str="SConstruct", - doCheckLog: bool=True, doCheckStdout: bool=True): + logfile: str = 'config.log', + sconf_dir: str = '.sconf_temp', + sconstruct: str = "SConstruct", + doCheckLog: bool = True, doCheckStdout: bool = True): """ Verify expected output from Configure. Used to verify the expected output from using Configure() @@ -1298,7 +1315,8 @@ SConscript(sconscript) # sys.stderr.write("LOGFILE[%s]:%s"%(type(logfile),logfile)) if (doCheckLog and - logfile.find("scons: warning: The stored build information has an unexpected class.") >= 0): + logfile.find( + "scons: warning: The stored build information has an unexpected class.") >= 0): self.fail_test() log = r'file \S*%s\,line \d+:' % re.escape(sconstruct) + ls @@ -1321,7 +1339,7 @@ SConscript(sconscript) result_cached = 1 for bld_desc in check_info.cached: # each TryXXX for ext, flag in bld_desc: # each file in TryBuild - conf_filename = re.escape(check_info.temp_filename%ext) + conf_filename = re.escape(check_info.temp_filename % ext) if flag == self.NCR: # NCR = Non Cached Rebuild @@ -1339,8 +1357,9 @@ SConscript(sconscript) re.escape("scons: Configure: \"") + \ conf_filename + \ re.escape("\" is up to date.") + ls - log = log + re.escape("scons: Configure: The original builder " - "output was:") + ls + log = log + re.escape( + "scons: Configure: The original builder " + "output was:") + ls log = f"{log}( \\|.*{ls})+" if flag == self.NCF: # non-cached rebuild failure @@ -1351,8 +1370,10 @@ SConscript(sconscript) log = log + \ re.escape("scons: Configure: Building \"") + \ conf_filename + \ - re.escape("\" failed in a previous run and all its sources are up to date.") + ls - log = log + re.escape("scons: Configure: The original builder output was:") + ls + re.escape( + "\" failed in a previous run and all its sources are up to date.") + ls + log = log + re.escape( + "scons: Configure: The original builder output was:") + ls log = f"{log}( \\|.*{ls})+" if result_cached: result = f"(cached) {check_info.result}" @@ -1396,11 +1417,9 @@ SConscript(sconscript) print("-----------------------------------------------------") self.fail_test() - - def checkLogAndStdout(self, checks, results, cached, logfile, sconf_dir, sconstruct, - doCheckLog: bool=True, doCheckStdout: bool=True): + doCheckLog: bool = True, doCheckStdout: bool = True): """ Verify expected output from Configure. Used to verify the expected output from using Configure() @@ -1434,7 +1453,8 @@ SConscript(sconscript) # sys.stderr.write("LOGFILE[%s]:%s"%(type(logfile),logfile)) if (doCheckLog and - logfile.find("scons: warning: The stored build information has an unexpected class.") >= 0): + logfile.find( + "scons: warning: The stored build information has an unexpected class.") >= 0): self.fail_test() sconf_dir = sconf_dir @@ -1462,10 +1482,12 @@ SConscript(sconscript) for bld_desc in cache_desc: # each TryXXX for ext, flag in bld_desc: # each file in TryBuild if ext in ['.c', '.cpp']: - conf_filename = re.escape(os.path.join(sconf_dir, "conftest")) +\ + conf_filename = re.escape( + os.path.join(sconf_dir, "conftest")) + \ r'_[a-z0-9]{32,64}_\d+%s' % re.escape(ext) elif ext == '': - conf_filename = re.escape(os.path.join(sconf_dir, "conftest")) +\ + conf_filename = re.escape( + os.path.join(sconf_dir, "conftest")) + \ r'_[a-z0-9]{32,64}(_\d+_[a-z0-9]{32,64})?' else: @@ -1477,8 +1499,10 @@ SConscript(sconscript) # this shortcut should be sufficient. # TODO: perhaps revisit and/or fix file naming for intermediate files in # Configure context logic - conf_filename = re.escape(os.path.join(sconf_dir, "conftest")) +\ - r'_[a-z0-9]{32,64}_\d+(_[a-z0-9]{32,64})?%s' % re.escape(ext) + conf_filename = re.escape( + os.path.join(sconf_dir, "conftest")) + \ + r'_[a-z0-9]{32,64}_\d+(_[a-z0-9]{32,64})?%s' % re.escape( + ext) if flag == self.NCR: # NCR = Non Cached Rebuild @@ -1496,8 +1520,9 @@ SConscript(sconscript) re.escape("scons: Configure: \"") + \ conf_filename + \ re.escape("\" is up to date.") + ls - log = log + re.escape("scons: Configure: The original builder " - "output was:") + ls + log = log + re.escape( + "scons: Configure: The original builder " + "output was:") + ls log = f"{log}( \\|.*{ls})+" if flag == self.NCF: # non-cached rebuild failure @@ -1508,8 +1533,10 @@ SConscript(sconscript) log = log + \ re.escape("scons: Configure: Building \"") + \ conf_filename + \ - re.escape("\" failed in a previous run and all its sources are up to date.") + ls - log = log + re.escape("scons: Configure: The original builder output was:") + ls + re.escape( + "\" failed in a previous run and all its sources are up to date.") + ls + log = log + re.escape( + "scons: Configure: The original builder output was:") + ls log = f"{log}( \\|.*{ls})+" # cnt = cnt + 1 if result_cached: @@ -1562,7 +1589,7 @@ SConscript(sconscript) # see also sys.prefix documentation return python_minor_version_string() - def get_platform_python_info(self, python_h_required: bool=False): + def get_platform_python_info(self, python_h_required: bool = False): """Return information about Python. Returns a path to a Python executable suitable for testing on @@ -1577,7 +1604,8 @@ SConscript(sconscript) """ python = os.environ.get('python_executable', self.where_is('python')) if not python: - self.skip_test('Can not find installed "python", skipping test.\n', from_fw=True) + self.skip_test('Can not find installed "python", skipping test.\n', + from_fw=True) # construct a program to run in the intended environment # in order to fetch the characteristics of that Python. @@ -1635,7 +1663,8 @@ else: stdout = self.stdout() or "" incpath, libpath, libname, python_h = stdout.strip().split('\n') if python_h == "False" and python_h_required: - self.skip_test('Can not find required "Python.h", skipping test.\n', from_fw=True) + self.skip_test('Can not find required "Python.h", skipping test.\n', + from_fw=True) return (python, incpath, libpath, libname + _lib) @@ -1656,7 +1685,7 @@ else: restore_sconsflags(sconsflags) return p - def wait_for(self, fname, timeout: float=20.0, popen=None) -> None: + def wait_for(self, fname, timeout: float = 20.0, popen=None) -> None: """ Waits for the specified file name to exist. """ @@ -2004,7 +2033,7 @@ class TimeSCons(TestSCons): destination = source.replace(source_dir, dest_dir) shutil.copy2(source, destination) - def up_to_date(self, arguments: str='.', read_str: str="", **kw) -> None: + def up_to_date(self, arguments: str = '.', read_str: str = "", **kw) -> None: """Asserts that all of the targets listed in arguments is up to date, but does not make any assumptions on other targets. This function is most useful in conjunction with the -n option. @@ -2025,7 +2054,6 @@ class TimeSCons(TestSCons): self.run(**kw) - # In some environments, $AR will generate a warning message to stderr # if the library doesn't previously exist and is being created. One # way to fix this is to tell AR to be quiet (sometimes the 'c' flag), |