From 473091605c9b5c3469b4fd018c7c3552523fe64e Mon Sep 17 00:00:00 2001 From: Dan Yeaw Date: Sun, 12 Jan 2025 13:45:38 -0500 Subject: [PATCH 1/4] Bump pre-commit hooks, enable pyupgrade --- .pre-commit-config.yaml | 8 ++++---- gvsbuild/build.py | 9 ++++----- gvsbuild/deps.py | 4 +--- gvsbuild/list.py | 3 +-- .../meson-scripts/extract-libtool-version.py | 2 +- gvsbuild/projects/ffmpeg.py | 3 +-- gvsbuild/projects/gettext.py | 7 +------ gvsbuild/projects/gtk.py | 2 +- gvsbuild/projects/libfido2.py | 2 +- gvsbuild/projects/libvpx.py | 8 +------- gvsbuild/projects/x264.py | 7 +------ gvsbuild/tools.py | 2 +- gvsbuild/utils/base_builders.py | 2 +- gvsbuild/utils/base_project.py | 10 +++++----- gvsbuild/utils/builder.py | 19 +++++-------------- pyproject.toml | 1 + 16 files changed, 30 insertions(+), 59 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 440873bf4..16337d304 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,19 +1,19 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0 hooks: - id: check-yaml - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.10.0.1 + rev: a23f6b85d0fdd5bb9d564e2579e678033debbdff # frozen: v0.10.0.1 hooks: - id: shellcheck args: [--exclude, SC1017] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.2 + rev: bbc3dc1f890007061f18f17e2334f216ea9e5df7 # frozen: v1.14.1 hooks: - id: mypy - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.6.8' + rev: '18ba2d02dcafd1cc608bd83eff6c17fb0108ca71' # frozen: v0.9.1 hooks: - id: ruff args: [--fix] diff --git a/gvsbuild/build.py b/gvsbuild/build.py index fc8aef5a5..b6b9d3fde 100644 --- a/gvsbuild/build.py +++ b/gvsbuild/build.py @@ -15,7 +15,6 @@ from enum import Enum from pathlib import Path -from typing import Dict, List import typer @@ -59,7 +58,7 @@ def __get_projects_to_build(opts): return to_build -def __parse_extra_opts(extra_opts: List[str]) -> Dict[str, List[str]]: +def __parse_extra_opts(extra_opts: list[str]) -> dict[str, list[str]]: if extra_opts is None: return {} parsed_opts = {} @@ -102,7 +101,7 @@ class WinSdkVersion(str, Enum): def build( - projects: List[str] = typer.Argument(..., help="The project to build"), + projects: list[str] = typer.Argument(..., help="The project to build"), platform: Platform = typer.Option(Platform.x64, help="The platform to build for"), configuration: Configuration = typer.Option( Configuration.debug_optimized, @@ -205,7 +204,7 @@ def build( help="Command line options to pass to msbuild.", rich_help_panel="Options to Pass to Build Systems", ), - skip: List[str] = typer.Option( + skip: list[str] = typer.Option( None, help="Project to avoid building, can be run multiple times.", rich_help_panel="Skip and Cleanup Options", @@ -314,7 +313,7 @@ def build( help="Command line options to pass to cargo", rich_help_panel="Options to Pass to Build Systems", ), - extra_opts: List[str] = typer.Option( + extra_opts: list[str] = typer.Option( None, help="Additional command line options to pass to specific project." " Example: --extra_opts :[;...]", diff --git a/gvsbuild/deps.py b/gvsbuild/deps.py index 719c6dc1c..87e95ca68 100644 --- a/gvsbuild/deps.py +++ b/gvsbuild/deps.py @@ -15,8 +15,6 @@ """gvsbuild deps print / .gv graph.""" -from typing import List - import typer # Verify we can import from the script directory @@ -214,7 +212,7 @@ def deps( invert: bool = typer.Option( False, help="Invert the dependencies", rich_help_panel="Graphing Options" ), - skip: List[str] = typer.Option( + skip: list[str] = typer.Option( None, help="A comma separated list of projects not to graph", rich_help_panel="Graphing Options", diff --git a/gvsbuild/list.py b/gvsbuild/list.py index 8261dd4d8..350987acf 100644 --- a/gvsbuild/list.py +++ b/gvsbuild/list.py @@ -14,7 +14,6 @@ # along with this program; if not, see . import json -from typing import List import typer @@ -22,7 +21,7 @@ def list_( - projects_names: List[str] = typer.Argument(None, help="The projects to list"), + projects_names: list[str] = typer.Argument(None, help="The projects to list"), project_type: ProjectType = typer.Option( None, "--type", diff --git a/gvsbuild/patches/libffi/meson-scripts/extract-libtool-version.py b/gvsbuild/patches/libffi/meson-scripts/extract-libtool-version.py index 8449a5be6..6fe0fa736 100644 --- a/gvsbuild/patches/libffi/meson-scripts/extract-libtool-version.py +++ b/gvsbuild/patches/libffi/meson-scripts/extract-libtool-version.py @@ -2,7 +2,7 @@ import sys -with open(sys.argv[1], "r") as f: +with open(sys.argv[1]) as f: for line in f.readlines(): line = line.strip() if line and not line.startswith("#"): diff --git a/gvsbuild/projects/ffmpeg.py b/gvsbuild/projects/ffmpeg.py index 621a46649..8c23a4cdb 100644 --- a/gvsbuild/projects/ffmpeg.py +++ b/gvsbuild/projects/ffmpeg.py @@ -49,8 +49,7 @@ def build(self): ) msys_path = Project.get_tool_path("msys2") self.exec_vs( - r"%s\bash build\build.sh %s %s %s %s" - % ( + r"{}\bash build\build.sh {} {} {} {}".format( msys_path, convert_to_msys(self.pkg_dir), convert_to_msys(self.builder.gtk_dir), diff --git a/gvsbuild/projects/gettext.py b/gvsbuild/projects/gettext.py index 3d773f474..f93c4ced0 100644 --- a/gvsbuild/projects/gettext.py +++ b/gvsbuild/projects/gettext.py @@ -47,12 +47,7 @@ def build(self): self.pop_location() self.push_location( - r".\nmake\vs%s\%s\%s" - % ( - self.builder.opts.vs_ver, - self.builder.opts.configuration, - self.builder.opts.platform, - ) + rf".\nmake\vs{self.builder.opts.vs_ver}\{self.builder.opts.configuration}\{self.builder.opts.platform}" ) self.install(r".\asprintf.dll bin") self.install(r".\asprintf.pdb bin") diff --git a/gvsbuild/projects/gtk.py b/gvsbuild/projects/gtk.py index ad42119d3..a7e8d5f08 100644 --- a/gvsbuild/projects/gtk.py +++ b/gvsbuild/projects/gtk.py @@ -39,7 +39,7 @@ def make_all_mo(self): self.builder.exec_cmd(cmd, working_dir=self._get_working_dir()) self.pop_location() - self.install(r".\COPYING share\doc\%s" % self.name) + self.install(rf".\COPYING share\doc\{self.name}") @project_add diff --git a/gvsbuild/projects/libfido2.py b/gvsbuild/projects/libfido2.py index 2ec47b055..ba30ff56c 100644 --- a/gvsbuild/projects/libfido2.py +++ b/gvsbuild/projects/libfido2.py @@ -55,4 +55,4 @@ def build(self): cmake_params = f"-DWITH_ZLIB=ON -DCBOR_INCLUDE_DIRS={include_dirs} -DCRYPTO_INCLUDE_DIRS={include_dirs} -DZLIB_INCLUDE_DIRS={include_dirs} -DCBOR_LIBRARY_DIRS={lib_dirs} -DCRYPTO_LIBRARY_DIRS={lib_dirs} -DZLIB_LIBRARY_DIRS={lib_dirs} -DCBOR_BIN_DIRS={bin_dirs} -DCRYPTO_BIN_DIRS={bin_dirs} -DZLIB_BIN_DIRS={bin_dirs} -DCRYPTO_LIBRARIES=libcrypto {build_params}" CmakeProject.build(self, cmake_params=cmake_params, use_ninja=True) - self.install(r"output\%s\static\* ." % (arch)) + self.install(rf"output\{arch}\static\* .") diff --git a/gvsbuild/projects/libvpx.py b/gvsbuild/projects/libvpx.py index 1f45747c1..23242cf0d 100644 --- a/gvsbuild/projects/libvpx.py +++ b/gvsbuild/projects/libvpx.py @@ -53,13 +53,7 @@ def build(self): msys_path = Project.get_tool_path("msys2") self.exec_vs( - r"%s\bash ./configure --target=%s --prefix=%s %s" - % ( - msys_path, - target, - convert_to_msys(self.builder.gtk_dir), - configure_options, - ), + rf"{msys_path}\bash ./configure --target={target} --prefix={convert_to_msys(self.builder.gtk_dir)} {configure_options}", add_path=msys_path, ) self.exec_vs(r"make", add_path=msys_path) diff --git a/gvsbuild/projects/x264.py b/gvsbuild/projects/x264.py index 62b1d5c10..366bb6df7 100644 --- a/gvsbuild/projects/x264.py +++ b/gvsbuild/projects/x264.py @@ -43,12 +43,7 @@ def build(self): ) msys_path = Project.get_tool_path("msys2") self.exec_vs( - r"%s\bash build\build.sh %s %s" - % ( - msys_path, - convert_to_msys(self.builder.gtk_dir), - configuration, - ), + rf"{msys_path}\bash build\build.sh {convert_to_msys(self.builder.gtk_dir)} {configuration}", add_path=msys_path, ) diff --git a/gvsbuild/tools.py b/gvsbuild/tools.py index 13b1d320f..0d86c8468 100644 --- a/gvsbuild/tools.py +++ b/gvsbuild/tools.py @@ -49,7 +49,7 @@ def unpack(self): env["CARGO_HOME"] = self.build_dir toolchain = ( - f'{self.version}-{"i686" if self.opts.x86 else "x86_64"}-pc-windows-msvc' + f"{self.version}-{'i686' if self.opts.x86 else 'x86_64'}-pc-windows-msvc" ) subprocess.run( f"{self.archive_file} --no-modify-path --default-toolchain {toolchain} -y", diff --git a/gvsbuild/utils/base_builders.py b/gvsbuild/utils/base_builders.py index cd193d2dd..fb2353528 100644 --- a/gvsbuild/utils/base_builders.py +++ b/gvsbuild/utils/base_builders.py @@ -222,7 +222,7 @@ def make_single_gir(self, prj_name, prj_dir=None): log.message(f"Unable to find detectenv-msvc.mak for {prj_name}") return - cmd = f'nmake -f {prj_name}-introspection-msvc.mak CFG={self.builder.opts.configuration} PREFIX={self.builder.gtk_dir} PYTHON={Project.get_tool_executable("python")} install-introspection' + cmd = f"nmake -f {prj_name}-introspection-msvc.mak CFG={self.builder.opts.configuration} PREFIX={self.builder.gtk_dir} PYTHON={Project.get_tool_executable('python')} install-introspection" self.push_location(b_dir) self.exec_vs(cmd) diff --git a/gvsbuild/utils/base_project.py b/gvsbuild/utils/base_project.py index ce070bfe5..239467383 100644 --- a/gvsbuild/utils/base_project.py +++ b/gvsbuild/utils/base_project.py @@ -21,7 +21,7 @@ import re import shutil from enum import Enum -from typing import Dict, Generic, List, Tuple, TypeVar +from typing import Generic, TypeVar from .simple_ui import log from .utils import _rmtree_error_handler @@ -138,13 +138,13 @@ def __init__(self, name, **kwargs): # register version params for use from derived classes self.version_params = version_params - _projects: List[P] = [] - _names: List[str] = [] - _dict: Dict[str, P] = {} + _projects: list[P] = [] + _names: list[str] = [] + _dict: dict[str, P] = {} _ver_res = None name_len = 0 # List of class/type to add, now not at import time but after some options are parsed - _reg_prj_list: List[Tuple[P, ProjectType]] = [] + _reg_prj_list: list[tuple[P, ProjectType]] = [] # build option opts = Options() diff --git a/gvsbuild/utils/builder.py b/gvsbuild/utils/builder.py index df7380451..af19c42aa 100644 --- a/gvsbuild/utils/builder.py +++ b/gvsbuild/utils/builder.py @@ -131,10 +131,7 @@ def __init__(self, opts): def _create_msbuild_opts(self, python): rt = [f"/nologo /p:Platform={self.opts.platform}"] if python: - rt.append( - '/p:PythonPath="%(python_dir)s" /p:PythonDir="%(python_dir)s"' - % {"python_dir": python} - ) + rt.append(f'/p:PythonPath="{python}" /p:PythonDir="{python}"') if log.verbose_on(): rt.append("/v:normal") @@ -269,8 +266,7 @@ def __check_tools(self, opts): # oops cmd = "pacman -S " + " ".join(missing) log.error_exit( - "Missing package(s) from msys2 installation, try with\n '%s'\nin a msys2 shell." - % (cmd,) + f"Missing package(s) from msys2 installation, try with\n '{cmd}'\nin a msys2 shell." ) self.patch = msys_path / "usr" / "bin" / "patch.exe" @@ -321,7 +317,7 @@ def restore_env(self, saved): del self.vs_env[key] def __dump_vs_loc(self): - vswhere = r"%s\Microsoft Visual Studio\Installer\vswhere.exe" % ( + vswhere = r"{}\Microsoft Visual Studio\Installer\vswhere.exe".format( os.environ.get("ProgramFiles(x86)", r"C:\Program Files (x86)") ) log.log("Trying to find Visual Studio installations ...") @@ -783,12 +779,7 @@ def __check_hash(self, proj): hc = self.__hashfile(proj.archive_file) if hc != proj.hash: log.error_exit( - "Hash mismatch on %s:\n Calculated '%s'\n Expected '%s'\n" - % ( - proj.archive_file, - hc, - proj.hash, - ) + f"Hash mismatch on {proj.archive_file}:\n Calculated '{hc}'\n Expected '{proj.hash}'\n" ) return True @@ -989,7 +980,7 @@ def exec_cargo( # set platform rustup = os.path.join(cargo_home, "rustup.exe") self.__execute( - f'{rustup} default {rust_version}-{"i686" if self.x86 else "x86_64"}-pc-windows-msvc', + f"{rustup} default {rust_version}-{'i686' if self.x86 else 'x86_64'}-pc-windows-msvc", env=env, ) diff --git a/pyproject.toml b/pyproject.toml index 747d697a5..3605fd5b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,6 +75,7 @@ select = [ "C", "E", "F", + "UP", "W", ] extend-select = ["I"] From 9e9a49786ccdf480693b2ac3a3cabcde54fcf84f Mon Sep 17 00:00:00 2001 From: Dan Yeaw Date: Sun, 12 Jan 2025 13:51:14 -0500 Subject: [PATCH 2/4] Re-enable tests, mark ones requiring Windows --- tests/test_build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 976e093e2..83b8f4b53 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -12,18 +12,17 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, see . +import sys import pytest -@pytest.mark.xfail(reason="https://github.com/Textualize/rich/issues/2559") def test_build_help(typer_app, runner): result = runner.invoke(typer_app, ["build", "--help"], color=True) assert result.exit_code == 0 assert "--help" in result.output -@pytest.mark.xfail(reason="https://github.com/Textualize/rich/issues/2559") def test_wrong_project_name(typer_app, runner): result = runner.invoke(typer_app, ["build", "bad-name"], color=True) assert result.exit_code == 1 @@ -36,6 +35,7 @@ def test_no_project(typer_app, runner): assert "Missing argument" in result.output +@pytest.mark.skipif(not sys.platform.startswith("win"), reason="windll only available on Windows") def test_platform(tmp_dir, typer_app, runner): assert tmp_dir.exists() result = runner.invoke( From b9630e89173318bf270d192f848ee303bcb3aab2 Mon Sep 17 00:00:00 2001 From: Dan Yeaw Date: Sun, 12 Jan 2025 13:51:50 -0500 Subject: [PATCH 3/4] Fix wrong Python version with choco --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ea5a0d596..fffb07cb3 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ Note: Visual Studio versions 2013 (not for all projects), 2015, 2017, 2019, and With your admin PowerShell terminal: ```PowerShell -choco install python312 +choco install python313 ``` 2. Open a PowerShell terminal as a normal user and check the python version: From 835263242280934cd48b8224892211507a4fc7c8 Mon Sep 17 00:00:00 2001 From: Dan Yeaw Date: Sun, 12 Jan 2025 18:27:10 -0500 Subject: [PATCH 4/4] Replace old style strings with f-strings --- gvsbuild/utils/base_project.py | 4 ++-- gvsbuild/utils/builder.py | 37 ++++++++-------------------------- gvsbuild/utils/simple_ui.py | 25 ++++------------------- tests/test_build.py | 4 +++- 4 files changed, 17 insertions(+), 53 deletions(-) diff --git a/gvsbuild/utils/base_project.py b/gvsbuild/utils/base_project.py index 239467383..d2dce5fb0 100644 --- a/gvsbuild/utils/base_project.py +++ b/gvsbuild/utils/base_project.py @@ -207,7 +207,7 @@ def exec_msbuild(self, cmd, configuration=None, add_path=None): add_path=add_path, ) - def _msbuild_make_search_replace(self, org_platform): + def _msbuild_make_search_replace(self, org_platform: str) -> tuple[bytes, bytes]: """Return the search & replace strings (converted to bytes to update the platform Toolset version (v140, v141, ...) to use a new compiler, e.g. to use vs2017 solution's files for vs2019. @@ -226,7 +226,7 @@ def _msbuild_make_search_replace(self, org_platform): dst_platform = "143" else: dst_platform = f"{ver}0" - search = (">v%u" % (org_platform,)).encode("utf-8") + search = f">v{org_platform}".encode() replace = f">v{dst_platform}".encode() return search, replace diff --git a/gvsbuild/utils/builder.py b/gvsbuild/utils/builder.py index af19c42aa..51f48a164 100644 --- a/gvsbuild/utils/builder.py +++ b/gvsbuild/utils/builder.py @@ -533,7 +533,7 @@ def build(self, projects): if self.opts.check_hash: return - # List of all the project we can mark for build because of a dependend + # List of all the project we can mark for build because of a dependent self.prj_to_mark = [x for x in Project._projects if x.is_project()] self.prj_done = [] @@ -551,11 +551,7 @@ def build(self, projects): if self.__build_one(p): self.prj_skipped.append(p.name) else: - msg = "%-*s (%.3f s)" % ( - Project.name_len, - p.name, - time.time() - st, - ) + msg = f"{p.name:{Project.name_len}} ({time.time() - st:.3f})" self.prj_done.append(msg) except KeyboardInterrupt: traceback.print_exc() @@ -597,8 +593,7 @@ def build(self, projects): log.message(f" {p}") miss += len(self.prj_dropped) - # Don't fool appveyor - log.error_exit("%u project(s) missing ;(" % (miss,)) + log.error_exit("%d project(s) missing ;(") log.close() @@ -798,21 +793,14 @@ def __download_progress(self, count, block_size, total_size): if perc != self._old_perc: perc = min(perc, 100) self._old_perc = perc - sp = "%s (%u k) - %u%%" % ( - self._downloading_file, - total_size / 1024, - self._old_perc, - ) + sp = f"{self._downloading_file} ({total_size / 1024}k) - {self._old_perc:.0f}%" print(sp, end="\r") if len(sp) > self._old_print: # Save the len to delete the line when we change file self._old_print = len(sp) else: # Only the current, we don't know the size - sp = "%s - %u k" % ( - self._downloading_file, - c_size / 1024, - ) + sp = f"{self._downloading_file} - {c_size / 1024:.0f} k" print(sp, end="\r") if len(sp) > self._old_print: self._old_print = len(sp) @@ -837,14 +825,7 @@ def urlretrieve(self, url, filename, reporthook, ssl_ignore_cert=False): msg = f"Opening {url} ..." print(msg, end="\r") with contextlib.closing(urlopen(url, None, context=ssl_ctx)) as fp: - print( - "%*s" - % ( - len(msg), - "", - ), - end="\r", - ) + print(f"{'':>{len(msg)}}", end="\r") headers = fp.info() with open(filename, "wb") as tfp: @@ -870,7 +851,7 @@ def urlretrieve(self, url, filename, reporthook, ssl_ignore_cert=False): if size >= 0 and read < size: raise ContentTooShortError( - "retrieval incomplete: got only %i out of %i bytes" % (read, size), + f"retrieval incomplete: got only {read} out of {size} bytes", result, ) @@ -920,9 +901,7 @@ def __download_one(self, proj): raise log.end() - print( - "%-*s" % (self._old_print, f"{proj.archive_file} - Download finished"), - ) + print(f"{proj.archive_file:{self._old_print}} - Download finished") return self.__check_hash(proj) def __sub_vars(self, s): diff --git a/gvsbuild/utils/simple_ui.py b/gvsbuild/utils/simple_ui.py index 266931e89..bce93ec46 100644 --- a/gvsbuild/utils/simple_ui.py +++ b/gvsbuild/utils/simple_ui.py @@ -131,14 +131,9 @@ def _create_log(self, file_path, single, max_size_kb, opts): self._output_val("Vs path", opts.vs_install_path) self._output_val("Sdk ver", opts.win_sdk_ver) - def _get_delta(self, start, end=None): - if not end: - end = datetime.datetime.now() + def _get_delta(self, start): dt = datetime.datetime.now() - start - return "%u.%03u" % ( - dt.seconds, - dt.microseconds / 1000, - ) + return f"{dt.seconds}.{dt.microseconds // 1000:03}" def _indend_check(self): if self.operations: @@ -205,13 +200,7 @@ def _output(self, msg, add_date=True, check_indent=True): now_val = datetime.datetime.now() self.fo.write(f"{now_val.strftime('%Y-%m-%d %H:%M:%S')} {msg}\n") else: - self.fo.write( - "%19s %s\n" - % ( - "", - msg, - ) - ) + self.fo.write(f"{msg:<20}") return False else: print(msg) @@ -219,13 +208,7 @@ def _output(self, msg, add_date=True, check_indent=True): return True def _output_val(self, msg, val): - self._output( - "%16s: %s" - % ( - msg, - val, - ) - ) + self._output(f"{msg:<16}: {val}") def message_indent(self, msg): if self._output(msg, add_date=False): diff --git a/tests/test_build.py b/tests/test_build.py index 83b8f4b53..29db488ca 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -35,7 +35,9 @@ def test_no_project(typer_app, runner): assert "Missing argument" in result.output -@pytest.mark.skipif(not sys.platform.startswith("win"), reason="windll only available on Windows") +@pytest.mark.skipif( + not sys.platform.startswith("win"), reason="windll only available on Windows" +) def test_platform(tmp_dir, typer_app, runner): assert tmp_dir.exists() result = runner.invoke(