From d3f7a3c3f738ba3cadc3a3ed63f4348fd53ec07c Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sat, 21 Jun 2025 00:17:02 +0000 Subject: [PATCH 1/2] feat: update gyp-next to v0.20.1 --- gyp/.github/workflows/node-gyp.yml | 7 +++++-- gyp/.github/workflows/nodejs.yml | 6 ++++-- gyp/.release-please-manifest.json | 2 +- gyp/CHANGELOG.md | 8 ++++++++ gyp/pylib/gyp/MSVSSettings.py | 3 +-- gyp/pylib/gyp/MSVSVersion.py | 3 +-- gyp/pylib/gyp/common.py | 33 ++++++++++++++++++++++-------- gyp/pylib/gyp/common_test.py | 32 +++++++++++++++++++++-------- gyp/pylib/gyp/generator/android.py | 3 +-- gyp/pylib/gyp/generator/cmake.py | 6 ++---- gyp/pylib/gyp/generator/eclipse.py | 3 +-- gyp/pylib/gyp/generator/make.py | 8 +++----- gyp/pylib/gyp/generator/msvs.py | 12 ++++------- gyp/pylib/gyp/generator/ninja.py | 15 +++++--------- gyp/pylib/gyp/mac_tool.py | 3 +-- gyp/pylib/gyp/msvs_emulation.py | 16 +++++---------- gyp/pylib/gyp/win_tool.py | 3 +-- gyp/pylib/gyp/xcode_emulation.py | 9 +++----- gyp/pylib/gyp/xcode_ninja.py | 3 +-- gyp/pylib/gyp/xcodeproj_file.py | 12 ++++------- gyp/pylib/packaging/_elffile.py | 3 +-- gyp/pylib/packaging/markers.py | 3 +-- gyp/pylib/packaging/metadata.py | 3 +-- gyp/pyproject.toml | 2 +- 24 files changed, 104 insertions(+), 94 deletions(-) diff --git a/gyp/.github/workflows/node-gyp.yml b/gyp/.github/workflows/node-gyp.yml index 56cdb4086c..c13b28effb 100644 --- a/gyp/.github/workflows/node-gyp.yml +++ b/gyp/.github/workflows/node-gyp.yml @@ -14,10 +14,13 @@ jobs: python-version: ["3.9", "3.11", "3.13"] include: - node-version: "22" - os: macos-13 + os: macos-13 # macOS on Intel python-version: "3.13" - node-version: "22" - os: windows-2025 + os: ubuntu-24.04-arm # Ubuntu on ARM + python-version: "3.13" + - node-version: "22" + os: windows-11-arm # Windows on ARM python-version: "3.13" runs-on: ${{ matrix.os }} steps: diff --git a/gyp/.github/workflows/nodejs.yml b/gyp/.github/workflows/nodejs.yml index 213fcbd0c1..416dfe45d1 100644 --- a/gyp/.github/workflows/nodejs.yml +++ b/gyp/.github/workflows/nodejs.yml @@ -12,9 +12,11 @@ jobs: os: [macos-latest, ubuntu-latest, windows-latest] python: ["3.9", "3.11", "3.13"] include: - - os: macos-13 + - os: macos-13 # macOS on Intel python-version: "3.13" - - os: windows-2025 + - os: ubuntu-24.04-arm # Ubuntu on ARM + python-version: "3.13" + - os: windows-11-arm # Windows on ARM python-version: "3.13" runs-on: ${{ matrix.os }} diff --git a/gyp/.release-please-manifest.json b/gyp/.release-please-manifest.json index 589cd4553e..9dd08b2d68 100644 --- a/gyp/.release-please-manifest.json +++ b/gyp/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.20.0" + ".": "0.20.1" } diff --git a/gyp/CHANGELOG.md b/gyp/CHANGELOG.md index 3f676055a6..488de4dc72 100644 --- a/gyp/CHANGELOG.md +++ b/gyp/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.20.1](https://github.com/nodejs/gyp-next/compare/v0.20.0...v0.20.1) (2025-06-06) + + +### Bug Fixes + +* Ensure Consistent Order of build_files in WriteAutoRegenerationRule ([#293](https://github.com/nodejs/gyp-next/issues/293)) ([59b5903](https://github.com/nodejs/gyp-next/commit/59b59035f4ae63419343ffdafe0f0ff511ada17d)) +* ignore failure of `GetCompilerPredefines` ([#295](https://github.com/nodejs/gyp-next/issues/295)) ([0eaea29](https://github.com/nodejs/gyp-next/commit/0eaea297f0fbb0869597aa162f66f78eb2468fad)) + ## [0.20.0](https://github.com/nodejs/gyp-next/compare/v0.19.1...v0.20.0) (2025-03-27) diff --git a/gyp/pylib/gyp/MSVSSettings.py b/gyp/pylib/gyp/MSVSSettings.py index fea6e67286..8f8f53bb71 100644 --- a/gyp/pylib/gyp/MSVSSettings.py +++ b/gyp/pylib/gyp/MSVSSettings.py @@ -396,8 +396,7 @@ def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr): # This may be unrecognized because it's an exclusion list. If the # setting name has the _excluded suffix, then check the root name. unrecognized = True - m = re.match(_EXCLUDED_SUFFIX_RE, setting) - if m: + if m := re.match(_EXCLUDED_SUFFIX_RE, setting): root_setting = m.group(1) unrecognized = root_setting not in settings diff --git a/gyp/pylib/gyp/MSVSVersion.py b/gyp/pylib/gyp/MSVSVersion.py index 93f48bc05c..e1c153b592 100644 --- a/gyp/pylib/gyp/MSVSVersion.py +++ b/gyp/pylib/gyp/MSVSVersion.py @@ -552,8 +552,7 @@ def SelectVisualStudioVersion(version="auto", allow_fallback=True): "2019": ("16.0",), "2022": ("17.0",), } - override_path = os.environ.get("GYP_MSVS_OVERRIDE_PATH") - if override_path: + if override_path := os.environ.get("GYP_MSVS_OVERRIDE_PATH"): msvs_version = os.environ.get("GYP_MSVS_VERSION") if not msvs_version: raise ValueError( diff --git a/gyp/pylib/gyp/common.py b/gyp/pylib/gyp/common.py index fbf1024fc3..35a64b1e6a 100644 --- a/gyp/pylib/gyp/common.py +++ b/gyp/pylib/gyp/common.py @@ -421,8 +421,9 @@ def EnsureDirExists(path): except OSError: pass -def GetCrossCompilerPredefines(): # -> dict +def GetCompilerPredefines(): # -> dict cmd = [] + defines = {} # shlex.split() will eat '\' in posix mode, but # setting posix=False will preserve extra '"' cause CreateProcess fail on Windows @@ -439,7 +440,7 @@ def replace_sep(s): if CXXFLAGS := os.environ.get("CXXFLAGS"): cmd += shlex.split(replace_sep(CXXFLAGS)) else: - return {} + return defines if sys.platform == "win32": fd, input = tempfile.mkstemp(suffix=".c") @@ -450,17 +451,33 @@ def replace_sep(s): real_cmd, shell=True, capture_output=True, check=True ).stdout + except subprocess.CalledProcessError as e: + print( + "Warning: failed to get compiler predefines\n" + "cmd: %s\n" + "status: %d" % (e.cmd, e.returncode), + file=sys.stderr + ) + return defines finally: os.unlink(input) else: input = "/dev/null" real_cmd = [*cmd, "-dM", "-E", "-x", "c", input] - stdout = subprocess.run( - real_cmd, shell=False, - capture_output=True, check=True - ).stdout + try: + stdout = subprocess.run( + real_cmd, shell=False, + capture_output=True, check=True + ).stdout + except subprocess.CalledProcessError as e: + print( + "Warning: failed to get compiler predefines\n" + "cmd: %s\n" + "status: %d" % (e.cmd, e.returncode), + file=sys.stderr + ) + return defines - defines = {} lines = stdout.decode("utf-8").replace("\r\n", "\n").split("\n") for line in lines: if (line or "").startswith("#define "): @@ -499,7 +516,7 @@ def GetFlavor(params): if "flavor" in params: return params["flavor"] - defines = GetCrossCompilerPredefines() + defines = GetCompilerPredefines() if "__EMSCRIPTEN__" in defines: return "emscripten" if "__wasm__" in defines: diff --git a/gyp/pylib/gyp/common_test.py b/gyp/pylib/gyp/common_test.py index bd7172afaf..d25e621ab5 100755 --- a/gyp/pylib/gyp/common_test.py +++ b/gyp/pylib/gyp/common_test.py @@ -7,6 +7,7 @@ """Unit tests for the common.py file.""" import os +import subprocess import sys import unittest from unittest.mock import MagicMock, patch @@ -85,22 +86,34 @@ def decode(self, encoding): @patch("os.close") @patch("os.unlink") @patch("tempfile.mkstemp") - def test_GetCrossCompilerPredefines(self, mock_mkstemp, mock_unlink, mock_close): + def test_GetCompilerPredefines(self, mock_mkstemp, mock_unlink, mock_close): mock_close.return_value = None mock_unlink.return_value = None mock_mkstemp.return_value = (0, "temp.c") - def mock_run(env, defines_stdout, expected_cmd): + def mock_run(env, defines_stdout, expected_cmd, throws=False): with patch("subprocess.run") as mock_run: - mock_process = MagicMock() - mock_process.returncode = 0 - mock_process.stdout = TestGetFlavor.MockCommunicate(defines_stdout) - mock_run.return_value = mock_process expected_input = "temp.c" if sys.platform == "win32" else "/dev/null" + if throws: + mock_run.side_effect = subprocess.CalledProcessError( + returncode=1, + cmd=[ + *expected_cmd, + "-dM", "-E", "-x", "c", expected_input + ] + ) + else: + mock_process = MagicMock() + mock_process.returncode = 0 + mock_process.stdout = TestGetFlavor.MockCommunicate(defines_stdout) + mock_run.return_value = mock_process with patch.dict(os.environ, env): - defines = gyp.common.GetCrossCompilerPredefines() + try: + defines = gyp.common.GetCompilerPredefines() + except Exception as e: + self.fail(f"GetCompilerPredefines raised an exception: {e}") flavor = gyp.common.GetFlavor({}) - if env.get("CC_target"): + if env.get("CC_target") or env.get("CC"): mock_run.assert_called_with( [ *expected_cmd, @@ -110,6 +123,9 @@ def mock_run(env, defines_stdout, expected_cmd): capture_output=True, check=True) return [defines, flavor] + [defines0, _] = mock_run({ "CC": "cl.exe" }, "", ["cl.exe"], True) + assert defines0 == {} + [defines1, _] = mock_run({}, "", []) assert defines1 == {} diff --git a/gyp/pylib/gyp/generator/android.py b/gyp/pylib/gyp/generator/android.py index 5ebe58bb55..cc02298e4e 100644 --- a/gyp/pylib/gyp/generator/android.py +++ b/gyp/pylib/gyp/generator/android.py @@ -900,8 +900,7 @@ def WriteTarget( if self.type != "none": self.WriteTargetFlags(spec, configs, link_deps) - settings = spec.get("aosp_build_settings", {}) - if settings: + if settings := spec.get("aosp_build_settings", {}): self.WriteLn("### Set directly by aosp_build_settings.") for k, v in settings.items(): if isinstance(v, list): diff --git a/gyp/pylib/gyp/generator/cmake.py b/gyp/pylib/gyp/generator/cmake.py index e69103e1b9..db8cc6e026 100644 --- a/gyp/pylib/gyp/generator/cmake.py +++ b/gyp/pylib/gyp/generator/cmake.py @@ -810,8 +810,7 @@ def WriteTarget( # link directories to targets defined after it is called. # As a result, link_directories must come before the target definition. # CMake unfortunately has no means of removing entries from LINK_DIRECTORIES. - library_dirs = config.get("library_dirs") - if library_dirs is not None: + if (library_dirs := config.get("library_dirs")) is not None: output.write("link_directories(") for library_dir in library_dirs: output.write(" ") @@ -1295,8 +1294,7 @@ def CallGenerateOutputForConfig(arglist): def GenerateOutput(target_list, target_dicts, data, params): - user_config = params.get("generator_flags", {}).get("config", None) - if user_config: + if user_config := params.get("generator_flags", {}).get("config", None): GenerateOutputForConfig(target_list, target_dicts, data, params, user_config) else: config_names = target_dicts[target_list[0]]["configurations"] diff --git a/gyp/pylib/gyp/generator/eclipse.py b/gyp/pylib/gyp/generator/eclipse.py index ed6daa91ba..be7ecd8b3b 100644 --- a/gyp/pylib/gyp/generator/eclipse.py +++ b/gyp/pylib/gyp/generator/eclipse.py @@ -451,8 +451,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if params["options"].generator_output: raise NotImplementedError("--generator_output not implemented for eclipse") - user_config = params.get("generator_flags", {}).get("config", None) - if user_config: + if user_config := params.get("generator_flags", {}).get("config", None): GenerateOutputForConfig(target_list, target_dicts, data, params, user_config) else: config_names = target_dicts[target_list[0]]["configurations"] diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index e860479069..4d4f049768 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -1465,8 +1465,7 @@ def WriteSources( order_only=True, ) - pchdeps = precompiled_header.GetObjDependencies(compilable, objs) - if pchdeps: + if pchdeps := precompiled_header.GetObjDependencies(compilable, objs): self.WriteLn("# Dependencies from obj files to their precompiled headers") for source, obj, gch in pchdeps: self.WriteLn(f"{obj}: {gch}") @@ -1600,8 +1599,7 @@ def ComputeOutputBasename(self, spec): target_prefix = spec.get("product_prefix", target_prefix) target = spec.get("product_name", target) - product_ext = spec.get("product_extension") - if product_ext: + if product_ext := spec.get("product_extension"): target_ext = "." + product_ext return target_prefix + target + target_ext @@ -2383,7 +2381,7 @@ def WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files) % { "makefile_name": makefile_name, "deps": replace_sep( - " ".join(SourceifyAndQuoteSpaces(bf) for bf in build_files) + " ".join(sorted(SourceifyAndQuoteSpaces(bf) for bf in build_files)) ), "cmd": replace_sep(gyp.common.EncodePOSIXShellList( [gyp_binary, "-fmake"] + gyp.RegenerateFlags(options) + build_files_args diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py index b4aea2e69a..baf5042150 100644 --- a/gyp/pylib/gyp/generator/msvs.py +++ b/gyp/pylib/gyp/generator/msvs.py @@ -1364,8 +1364,7 @@ def _GetOutputTargetExt(spec): Returns: A string with the extension, or None """ - target_extension = spec.get("product_extension") - if target_extension: + if target_extension := spec.get("product_extension"): return "." + target_extension return None @@ -3166,8 +3165,7 @@ def _GetMSBuildAttributes(spec, config, build_file): "windows_driver": "Link", "static_library": "Lib", } - msbuild_tool = msbuild_tool_map.get(spec["type"]) - if msbuild_tool: + if msbuild_tool := msbuild_tool_map.get(spec["type"]): msbuild_settings = config["finalized_msbuild_settings"] out_file = msbuild_settings[msbuild_tool].get("OutputFile") if out_file: @@ -3184,8 +3182,7 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): # there are actions. # TODO(jeanluc) Handle the equivalent of setting 'CYGWIN=nontsec'. new_paths = [] - cygwin_dirs = spec.get("msvs_cygwin_dirs", ["."])[0] - if cygwin_dirs: + if cygwin_dirs := spec.get("msvs_cygwin_dirs", ["."])[0]: cyg_path = "$(MSBuildProjectDirectory)\\%s\\bin\\" % _FixPath(cygwin_dirs) new_paths.append(cyg_path) # TODO(jeanluc) Change the convention to have both a cygwin_dir and a @@ -3370,7 +3367,6 @@ def _FinalizeMSBuildSettings(spec, configuration): prebuild = configuration.get("msvs_prebuild") postbuild = configuration.get("msvs_postbuild") def_file = _GetModuleDefinition(spec) - precompiled_header = configuration.get("msvs_precompiled_header") # Add the information to the appropriate tool # TODO(jeanluc) We could optimize and generate these settings only if @@ -3408,7 +3404,7 @@ def _FinalizeMSBuildSettings(spec, configuration): msbuild_settings, "ClCompile", "DisableSpecificWarnings", disabled_warnings ) # Turn on precompiled headers if appropriate. - if precompiled_header: + if precompiled_header := configuration.get("msvs_precompiled_header"): # While MSVC works with just file name eg. "v8_pch.h", ClangCL requires # the full path eg. "tools/msvs/pch/v8_pch.h" to find the file. # P.S. Only ClangCL defines msbuild_toolset, for MSVC it is None. diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index b7ac823d14..a387954cda 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -263,8 +263,7 @@ def ExpandSpecial(self, path, product_dir=None): dir. """ - PRODUCT_DIR = "$!PRODUCT_DIR" - if PRODUCT_DIR in path: + if (PRODUCT_DIR := "$!PRODUCT_DIR") in path: if product_dir: path = path.replace(PRODUCT_DIR, product_dir) else: @@ -272,8 +271,7 @@ def ExpandSpecial(self, path, product_dir=None): path = path.replace(PRODUCT_DIR + "\\", "") path = path.replace(PRODUCT_DIR, ".") - INTERMEDIATE_DIR = "$!INTERMEDIATE_DIR" - if INTERMEDIATE_DIR in path: + if (INTERMEDIATE_DIR := "$!INTERMEDIATE_DIR") in path: int_dir = self.GypPathToUniqueOutput("gen") # GypPathToUniqueOutput generates a path relative to the product dir, # so insert product_dir in front if it is provided. @@ -2075,16 +2073,14 @@ def OpenOutput(path, mode="w"): def CommandWithWrapper(cmd, wrappers, prog): - wrapper = wrappers.get(cmd, "") - if wrapper: + if wrapper := wrappers.get(cmd, ""): return wrapper + " " + prog return prog def GetDefaultConcurrentLinks(): """Returns a best-guess for a number of concurrent links.""" - pool_size = int(os.environ.get("GYP_LINK_CONCURRENCY") or 0) - if pool_size: + if pool_size := int(os.environ.get("GYP_LINK_CONCURRENCY") or 0): return pool_size if sys.platform in ("win32", "cygwin"): @@ -2305,8 +2301,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name key_prefix = re.sub(r"\.HOST$", ".host", key_prefix) wrappers[key_prefix] = os.path.join(build_to_root, value) - mac_toolchain_dir = generator_flags.get("mac_toolchain_dir", None) - if mac_toolchain_dir: + if mac_toolchain_dir := generator_flags.get("mac_toolchain_dir", None): wrappers["LINK"] = "export DEVELOPER_DIR='%s' &&" % mac_toolchain_dir if flavor == "win": diff --git a/gyp/pylib/gyp/mac_tool.py b/gyp/pylib/gyp/mac_tool.py index 70aab4f178..d51362f51e 100755 --- a/gyp/pylib/gyp/mac_tool.py +++ b/gyp/pylib/gyp/mac_tool.py @@ -25,8 +25,7 @@ def main(args): executor = MacTool() - exit_code = executor.Dispatch(args) - if exit_code is not None: + if (exit_code := executor.Dispatch(args)) is not None: sys.exit(exit_code) diff --git a/gyp/pylib/gyp/msvs_emulation.py b/gyp/pylib/gyp/msvs_emulation.py index ace0cae5eb..f8b3b87d94 100644 --- a/gyp/pylib/gyp/msvs_emulation.py +++ b/gyp/pylib/gyp/msvs_emulation.py @@ -247,9 +247,7 @@ def GetExtension(self): the target type. """ ext = self.spec.get("product_extension", None) - if ext: - return ext - return gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec["type"], "") + return ext or gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec["type"], "") def GetVSMacroEnv(self, base_to_build=None, config=None): """Get a dict of variables mapping internal VS macro names to their gyp @@ -625,8 +623,7 @@ def GetDefFile(self, gyp_to_build_path): def _GetDefFileAsLdflags(self, ldflags, gyp_to_build_path): """.def files get implicitly converted to a ModuleDefinitionFile for the linker in the VS generator. Emulate that behaviour here.""" - def_file = self.GetDefFile(gyp_to_build_path) - if def_file: + if def_file := self.GetDefFile(gyp_to_build_path): ldflags.append('/DEF:"%s"' % def_file) def GetPGDName(self, config, expand_special): @@ -674,14 +671,11 @@ def GetLdflags( ) ld("DelayLoadDLLs", prefix="/DELAYLOAD:") ld("TreatLinkerWarningAsErrors", prefix="/WX", map={"true": "", "false": ":NO"}) - out = self.GetOutputName(config, expand_special) - if out: + if out := self.GetOutputName(config, expand_special): ldflags.append("/OUT:" + out) - pdb = self.GetPDBName(config, expand_special, output_name + ".pdb") - if pdb: + if pdb := self.GetPDBName(config, expand_special, output_name + ".pdb"): ldflags.append("/PDB:" + pdb) - pgd = self.GetPGDName(config, expand_special) - if pgd: + if pgd := self.GetPGDName(config, expand_special): ldflags.append("/PGD:" + pgd) map_file = self.GetMapFileName(config, expand_special) ld("GenerateMapFile", map={"true": "/MAP:" + map_file if map_file else "/MAP"}) diff --git a/gyp/pylib/gyp/win_tool.py b/gyp/pylib/gyp/win_tool.py index 7e647f40a8..3004f533ca 100755 --- a/gyp/pylib/gyp/win_tool.py +++ b/gyp/pylib/gyp/win_tool.py @@ -27,8 +27,7 @@ def main(args): executor = WinTool() - exit_code = executor.Dispatch(args) - if exit_code is not None: + if (exit_code := executor.Dispatch(args)) is not None: sys.exit(exit_code) diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index 85a63dfd7a..0746865dc8 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -1350,8 +1350,7 @@ def _DefaultSdkRoot(self): if xcode_version < "0500": return "" default_sdk_path = self._XcodeSdkPath("") - default_sdk_root = XcodeSettings._sdk_root_cache.get(default_sdk_path) - if default_sdk_root: + if default_sdk_root := XcodeSettings._sdk_root_cache.get(default_sdk_path): return default_sdk_root try: all_sdks = GetStdout(["xcodebuild", "-showsdks"]) @@ -1787,11 +1786,9 @@ def _GetXcodeEnv( env["INFOPLIST_PATH"] = xcode_settings.GetBundlePlistPath() env["WRAPPER_NAME"] = xcode_settings.GetWrapperName() - install_name = xcode_settings.GetInstallName() - if install_name: + if install_name := xcode_settings.GetInstallName(): env["LD_DYLIB_INSTALL_NAME"] = install_name - install_name_base = xcode_settings.GetInstallNameBase() - if install_name_base: + if install_name_base := xcode_settings.GetInstallNameBase(): env["DYLIB_INSTALL_NAME_BASE"] = install_name_base xcode_version, _ = XcodeVersion() if xcode_version >= "0500" and not env.get("SDKROOT"): diff --git a/gyp/pylib/gyp/xcode_ninja.py b/gyp/pylib/gyp/xcode_ninja.py index cac1af56f7..ae3079d85a 100644 --- a/gyp/pylib/gyp/xcode_ninja.py +++ b/gyp/pylib/gyp/xcode_ninja.py @@ -70,12 +70,11 @@ def _TargetFromSpec(old_spec, params): target_name = old_spec.get("target_name") product_name = old_spec.get("product_name", target_name) - product_extension = old_spec.get("product_extension") ninja_target = {} ninja_target["target_name"] = target_name ninja_target["product_name"] = product_name - if product_extension: + if product_extension := old_spec.get("product_extension"): ninja_target["product_extension"] = product_extension ninja_target["toolset"] = old_spec.get("toolset") ninja_target["default_configuration"] = old_spec.get("default_configuration") diff --git a/gyp/pylib/gyp/xcodeproj_file.py b/gyp/pylib/gyp/xcodeproj_file.py index be17ef946d..0376693d95 100644 --- a/gyp/pylib/gyp/xcodeproj_file.py +++ b/gyp/pylib/gyp/xcodeproj_file.py @@ -183,8 +183,7 @@ def SourceTreeAndPathFromPath(input_path): 'path' (None, 'path') """ - source_group_match = _path_leading_variable.match(input_path) - if source_group_match: + if source_group_match := _path_leading_variable.match(input_path): source_tree = source_group_match.group(1) output_path = source_group_match.group(3) # This may be None. else: @@ -390,8 +389,7 @@ def Comment(self): def Hashables(self): hashables = [self.__class__.__name__] - name = self.Name() - if name is not None: + if (name := self.Name()) is not None: hashables.append(name) hashables.extend(self._hashables) @@ -1051,8 +1049,7 @@ def Hashables(self): # including paths with a sourceTree, they'll still inherit their parents' # hashables, even though the paths aren't relative to their parents. This # is not expected to be much of a problem in practice. - path = self.PathFromSourceTreeAndPath() - if path is not None: + if (path := self.PathFromSourceTreeAndPath()) is not None: components = path.split(posixpath.sep) for component in components: hashables.append(self.__class__.__name__ + ".path") @@ -2109,8 +2106,7 @@ def SetDestination(self, path): specifically, "$(DIR)/path". """ - path_tree_match = self.path_tree_re.search(path) - if path_tree_match: + if path_tree_match := self.path_tree_re.search(path): path_tree = path_tree_match.group(1) if path_tree in self.path_tree_first_to_subfolder: subfolder = self.path_tree_first_to_subfolder[path_tree] diff --git a/gyp/pylib/packaging/_elffile.py b/gyp/pylib/packaging/_elffile.py index 6fb19b30bb..cb33e10556 100644 --- a/gyp/pylib/packaging/_elffile.py +++ b/gyp/pylib/packaging/_elffile.py @@ -48,8 +48,7 @@ def __init__(self, f: IO[bytes]) -> None: ident = self._read("16B") except struct.error: raise ELFInvalid("unable to parse identification") - magic = bytes(ident[:4]) - if magic != b"\x7fELF": + if (magic := bytes(ident[:4])) != b"\x7fELF": raise ELFInvalid(f"invalid magic: {magic!r}") self.capacity = ident[4] # Format for program header (bitness). diff --git a/gyp/pylib/packaging/markers.py b/gyp/pylib/packaging/markers.py index 8b98fca723..7e4d150208 100644 --- a/gyp/pylib/packaging/markers.py +++ b/gyp/pylib/packaging/markers.py @@ -166,8 +166,7 @@ def _evaluate_markers(markers: MarkerList, environment: Dict[str, str]) -> bool: def format_full_version(info: "sys._version_info") -> str: version = "{0.major}.{0.minor}.{0.micro}".format(info) - kind = info.releaselevel - if kind != "final": + if (kind := info.releaselevel) != "final": version += kind[0] + str(info.serial) return version diff --git a/gyp/pylib/packaging/metadata.py b/gyp/pylib/packaging/metadata.py index 23bb564f3d..43f5c5b30d 100644 --- a/gyp/pylib/packaging/metadata.py +++ b/gyp/pylib/packaging/metadata.py @@ -591,8 +591,7 @@ def _process_description_content_type(self, value: str) -> str: f"{{field}} must be one of {list(content_types)}, not {value!r}" ) - charset = parameters.get("charset", "UTF-8") - if charset != "UTF-8": + if (charset := parameters.get("charset", "UTF-8")) != "UTF-8": raise self._invalid_metadata( f"{{field}} can only specify the UTF-8 charset, not {list(charset)}" ) diff --git a/gyp/pyproject.toml b/gyp/pyproject.toml index 537308731f..d6ed4c7d2b 100644 --- a/gyp/pyproject.toml +++ b/gyp/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "gyp-next" -version = "0.20.0" +version = "0.20.1" authors = [ { name="Node.js contributors", email="ryzokuken@disroot.org" }, ] From 263923e5ffb9968fcddd95ac715fd22184c485b4 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sun, 22 Jun 2025 10:57:11 +0000 Subject: [PATCH 2/2] feat: update gyp-next to v0.20.2 --- gyp/.release-please-manifest.json | 2 +- gyp/CHANGELOG.md | 7 +++++++ gyp/pylib/gyp/MSVSVersion.py | 2 +- gyp/pylib/gyp/__init__.py | 2 +- gyp/pylib/gyp/common.py | 3 ++- gyp/pylib/gyp/generator/make.py | 2 +- gyp/pylib/gyp/generator/ninja.py | 7 +++---- gyp/pylib/gyp/mac_tool.py | 2 +- gyp/pyproject.toml | 3 +-- gyp/test_gyp.py | 4 ++-- 10 files changed, 20 insertions(+), 14 deletions(-) diff --git a/gyp/.release-please-manifest.json b/gyp/.release-please-manifest.json index 9dd08b2d68..69ae3d039e 100644 --- a/gyp/.release-please-manifest.json +++ b/gyp/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.20.1" + ".": "0.20.2" } diff --git a/gyp/CHANGELOG.md b/gyp/CHANGELOG.md index 488de4dc72..c1c1c5909d 100644 --- a/gyp/CHANGELOG.md +++ b/gyp/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.20.2](https://github.com/nodejs/gyp-next/compare/v0.20.1...v0.20.2) (2025-06-22) + + +### Bug Fixes + +* Python lint import-outside-top-level ruff rule PLC0415 ([#298](https://github.com/nodejs/gyp-next/issues/298)) ([34f4df6](https://github.com/nodejs/gyp-next/commit/34f4df614936ee6a056e47406ebbe7e3c1cb6540)) + ## [0.20.1](https://github.com/nodejs/gyp-next/compare/v0.20.0...v0.20.1) (2025-06-06) diff --git a/gyp/pylib/gyp/MSVSVersion.py b/gyp/pylib/gyp/MSVSVersion.py index e1c153b592..a34631b452 100644 --- a/gyp/pylib/gyp/MSVSVersion.py +++ b/gyp/pylib/gyp/MSVSVersion.py @@ -219,7 +219,7 @@ def _RegistryGetValueUsingWinReg(key, value): contents of the registry key's value, or None on failure. Throws ImportError if winreg is unavailable. """ - from winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx + from winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx # noqa: PLC0415 try: root, subkey = key.split("\\", 1) assert root == "HKLM" # Only need HKLM for now. diff --git a/gyp/pylib/gyp/__init__.py b/gyp/pylib/gyp/__init__.py index 77800661a4..efc15fc62f 100755 --- a/gyp/pylib/gyp/__init__.py +++ b/gyp/pylib/gyp/__init__.py @@ -489,7 +489,7 @@ def gyp_main(args): options, build_files_arg = parser.parse_args(args) if options.version: - import pkg_resources + import pkg_resources # noqa: PLC0415 print(f"v{pkg_resources.get_distribution('gyp-next').version}") return 0 build_files = build_files_arg diff --git a/gyp/pylib/gyp/common.py b/gyp/pylib/gyp/common.py index 35a64b1e6a..9431c432c8 100644 --- a/gyp/pylib/gyp/common.py +++ b/gyp/pylib/gyp/common.py @@ -583,7 +583,8 @@ def uniquer(seq, idfun=lambda x: x): # Based on http://code.activestate.com/recipes/576694/. -class OrderedSet(MutableSet): +class OrderedSet(MutableSet): # noqa: PLW1641 + # TODO (cclauss): Fix eq-without-hash ruff rule PLW1641 def __init__(self, iterable=None): self.end = end = [] end += [None, end, end] # sentinel node for doubly linked list diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 4d4f049768..7118492e77 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -78,7 +78,7 @@ def CalculateVariables(default_variables, params): # Copy additional generator configuration data from Xcode, which is shared # by the Mac Make generator. - import gyp.generator.xcode as xcode_generator + import gyp.generator.xcode as xcode_generator # noqa: PLC0415 global generator_additional_non_configuration_keys generator_additional_non_configuration_keys = getattr( diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index a387954cda..d5dfa1a118 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -5,6 +5,7 @@ import collections import copy +import ctypes import hashlib import json import multiprocessing @@ -1993,7 +1994,7 @@ def CalculateVariables(default_variables, params): # Copy additional generator configuration data from Xcode, which is shared # by the Mac Ninja generator. - import gyp.generator.xcode as xcode_generator + import gyp.generator.xcode as xcode_generator # noqa: PLC0415 generator_additional_non_configuration_keys = getattr( xcode_generator, "generator_additional_non_configuration_keys", [] @@ -2016,7 +2017,7 @@ def CalculateVariables(default_variables, params): # Copy additional generator configuration data from VS, which is shared # by the Windows Ninja generator. - import gyp.generator.msvs as msvs_generator + import gyp.generator.msvs as msvs_generator # noqa: PLC0415 generator_additional_non_configuration_keys = getattr( msvs_generator, "generator_additional_non_configuration_keys", [] @@ -2084,8 +2085,6 @@ def GetDefaultConcurrentLinks(): return pool_size if sys.platform in ("win32", "cygwin"): - import ctypes - class MEMORYSTATUSEX(ctypes.Structure): _fields_ = [ ("dwLength", ctypes.c_ulong), diff --git a/gyp/pylib/gyp/mac_tool.py b/gyp/pylib/gyp/mac_tool.py index d51362f51e..58fb9c7398 100755 --- a/gyp/pylib/gyp/mac_tool.py +++ b/gyp/pylib/gyp/mac_tool.py @@ -141,7 +141,7 @@ def _CopyStringsFile(self, source, dest): # CFPropertyListCreateFromXMLData(): Old-style plist parser: missing # semicolon in dictionary. # on invalid files. Do the same kind of validation. - import CoreFoundation + import CoreFoundation # noqa: PLC0415 with open(source, "rb") as in_file: s = in_file.read() diff --git a/gyp/pyproject.toml b/gyp/pyproject.toml index d6ed4c7d2b..62fb2bf8ca 100644 --- a/gyp/pyproject.toml +++ b/gyp/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "gyp-next" -version = "0.20.1" +version = "0.20.2" authors = [ { name="Node.js contributors", email="ryzokuken@disroot.org" }, ] @@ -39,7 +39,6 @@ gyp = "gyp:script_main" [tool.ruff] extend-exclude = ["pylib/packaging"] line-length = 88 -target-version = "py37" [tool.ruff.lint] select = [ diff --git a/gyp/test_gyp.py b/gyp/test_gyp.py index b7bb956b8e..8e910a2b76 100755 --- a/gyp/test_gyp.py +++ b/gyp/test_gyp.py @@ -148,13 +148,13 @@ def print_configuration_info(): print("Test configuration:") if sys.platform == "darwin": sys.path.append(os.path.abspath("test/lib")) - import TestMac + import TestMac # noqa: PLC0415 print(f" Mac {platform.mac_ver()[0]} {platform.mac_ver()[2]}") print(f" Xcode {TestMac.Xcode.Version()}") elif sys.platform == "win32": sys.path.append(os.path.abspath("pylib")) - import gyp.MSVSVersion + import gyp.MSVSVersion # noqa: PLC0415 print(" Win %s %s\n" % platform.win32_ver()[0:2]) print(" MSVS %s" % gyp.MSVSVersion.SelectVisualStudioVersion().Description())