From 69d1bccd3e15cbe67f14648f646efc7bc50ce421 Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Mon, 1 Apr 2024 13:39:23 +0200 Subject: [PATCH] Windows CI --- .github/workflows/main.yaml | 62 +++++++++++++++++++++---------------- beetsplug/alternatives.py | 16 ++++++++++ test/cli_test.py | 22 ++++++------- test/helper.py | 20 +++++++++++- 4 files changed, 81 insertions(+), 39 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index e2cebe0..fd2c4be 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -2,47 +2,55 @@ name: Check and test on: [push, pull_request] +env: + FORCE_COLOR: 1 + jobs: build: strategy: matrix: - python-version: - - "3.8" # minimum required - - "3.12" # latest - - "3.13-dev" # next + # os: ["ubuntu-latest"] + # python-version: + # - "3.8" # minimum required + # - "3.12" # latest + # - "3.13-dev" # next + include: + - python-version: 3.8 + os: windows-2022 - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.python-version == '3.13-dev' }} steps: - - uses: actions/checkout@v3 - - run: pip install poetry - - uses: actions/setup-python@v3 + - uses: actions/checkout@v4 + - run: pipx install poetry + - uses: actions/setup-python@v5 + id: setup-python with: python-version: ${{ matrix.python-version }} cache: poetry - - run: poetry env use $(which python) + - run: poetry env use ${{ steps.setup-python.outputs.python-path }} - run: poetry install - - run: poetry run ruff format --check - - run: poetry run ruff check - - run: poetry run pyright --warnings + # - run: poetry run ruff format --check + # - run: poetry run ruff check + # - run: poetry run pyright --warnings - run: poetry run pytest - uses: coverallsapp/github-action@v2 if: github.event_name == 'pull_request' && matrix.python-version == '3.8' - build-beets-master: - runs-on: ubuntu-latest + # build-beets-master: + # runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - run: pip install poetry - - uses: actions/setup-python@v3 - with: - python-version: 3.8 - cache: poetry - - run: poetry env use $(which python) - - run: poetry install - # We cannot use `poetry add` because poetry does not install beets - # dependencies properly - - run: poetry run pip install "git+https://github.com/beetbox/beets#master" - - run: poetry run pytest + # steps: + # - uses: actions/checkout@v4 + # - run: pip install poetry + # - uses: actions/setup-python@v5 + # with: + # python-version: 3.8 + # cache: poetry + # - run: poetry env use $(which python) + # - run: poetry install + # # We cannot use `poetry add` because poetry does not install beets + # # dependencies properly + # - run: poetry run pip install "git+https://github.com/beetbox/beets#master" + # - run: poetry run pytest diff --git a/beetsplug/alternatives.py b/beetsplug/alternatives.py index 0f646ba..000c657 100644 --- a/beetsplug/alternatives.py +++ b/beetsplug/alternatives.py @@ -12,6 +12,7 @@ import argparse +import logging import os.path import threading import traceback @@ -29,6 +30,10 @@ import beetsplug.convert as convert +logger = logging.getLogger(__name__) +logger.propagate = True +logger.setLevel(logging.DEBUG) + def _remove(path, soft=True): """Remove the file. If `soft`, then no error will be raised if the @@ -213,6 +218,17 @@ def item_change_actions(self, item: Item, path: bytes, dest: bytes) -> List[Acti actions.append(Action.MOVE) item_mtime_alt = os.path.getmtime(syspath(path)) + item_mtime_lib = os.path.getmtime(syspath(item.path)) + print( + "check mtime ", + { + "prev": path, + "prev2": syspath(path), + "mtime": item_mtime_alt, + "mtime_lib": item_mtime_lib, + "lib_path": syspath(item.path), + }, + ) if item_mtime_alt < os.path.getmtime(syspath(item.path)): actions.append(Action.WRITE) album = item.get_album() diff --git a/test/cli_test.py b/test/cli_test.py index f70429c..e4b6dbe 100644 --- a/test/cli_test.py +++ b/test/cli_test.py @@ -1,7 +1,9 @@ import os import os.path +import platform import shutil from pathlib import Path +from time import sleep import pytest from beets import util @@ -22,6 +24,7 @@ assert_not_file_tag, assert_symlink, control_stdin, + convert_command, ) @@ -34,8 +37,7 @@ def test_external(self, tmp_path: Path): external_dir = str(tmp_path / "myplayer") self.config["convert"]["formats"] = { "aac": { - "command": "bash -c \"cp '$source' '$dest';" - + "printf ISAAC >> '$dest'\"", + "command": convert_command("ISAAC"), "extension": "m4a", }, } @@ -110,6 +112,7 @@ def test_external(self, tmp_path: Path): assert_file_tag(external_beet, b"ISAAC") +@pytest.mark.skipif(platform.system() == "Windows", reason="no symlinks on windows") class TestSymlinkView(TestHelper): """Test alternatives with the ``link`` format producing symbolic links.""" @@ -315,15 +318,16 @@ def test_move_after_path_format_update(self): assert_is_not_file(old_path) assert_is_file(new_path) - def test_move_and_write_after_tags_changed(self): + def test_move_and_write_after_tags_changed_xxx(self): item = self.add_external_track("myexternal") old_path = self.get_path(item) assert_is_file(old_path) + sleep(0.1) item["title"] = "a new title" item.store() item.write() - self.runcli("alt", "update", "myexternal") + print(self.runcli("alt", "update", "myexternal")) item.load() new_path = self.get_path(item) @@ -410,7 +414,7 @@ def touch_art(item, image_path): # Make a copy of the artwork, so that changing mtime/content won't # affect the repository. image_path = bytes(tmp_path / "image") - shutil.copy(self.IMAGE_FIXTURE1, check_type(syspath(image_path), bytes)) + shutil.copy(self.IMAGE_FIXTURE1, syspath(image_path)) # type: ignore touch_art(item, image_path) # Add a cover image, assert that it is being embedded. @@ -479,9 +483,7 @@ class TestExternalConvert(TestHelper): @pytest.fixture(autouse=True) def _external_convert(self, tmp_path: Path, _setup: None): external_dir = str(tmp_path) - self.config["convert"]["formats"] = { - "ogg": "bash -c \"cp '$source' '$dest';" + "printf ISOGG >> '$dest'\"" - } + self.config["convert"]["formats"] = {"ogg": convert_command("ISOGG")} self.config["alternatives"] = { "myexternal": { "directory": external_dir, @@ -546,9 +548,7 @@ def test_no_move_on_extension_change(self): item = self.add_track(myexternal="true", format="m4a") self.runcli("alt", "update", "myexternal") - self.config["convert"]["formats"] = { - "mp3": "bash -c \"cp '$source' '$dest';" + "printf ISMP3 >> '$dest'\"" - } + self.config["convert"]["formats"] = {"mp3": convert_command("ISMP3")} self.config["alternatives"]["myexternal"]["formats"] = "mp3" # Assert that this re-encodes instead of copying the ogg file diff --git a/test/helper.py b/test/helper.py index d97783d..903714e 100644 --- a/test/helper.py +++ b/test/helper.py @@ -1,4 +1,5 @@ import os +import platform import sys from concurrent import futures from contextlib import contextmanager @@ -62,7 +63,9 @@ def assert_file_tag(path, tag: bytes): assert_is_file(path) with open(syspath(path), "rb") as f: f.seek(-5, os.SEEK_END) - assert f.read() == tag + x = f.read() + print(x) + assert x == tag def assert_not_file_tag(path, tag: bytes): @@ -261,3 +264,18 @@ def submit(self, *args, **kwargs): def shutdown(self, wait=True): pass + + +def convert_command(tag: str) -> str: + system = platform.system() + if system == "Windows": + return ( + 'powershell -Command "' + "Copy-Item -Path '$source' -Destination '$dest' -NoNewline;" + f"Add-Content -Path '$dest' -Value {tag}" + '"' + ) + elif system == "Linux": + return f"bash -c \"cp '$source' '$dest'; printf {tag} >> '$dest'\"" + else: + raise Exception(f"Unsupported system: {system}")