From 575c43f933e296a6f1f6ada4e21d8b9dc41a8b85 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 | 64 +++++++++++++++++++++---------------- beetsplug/alternatives.py | 16 ++++++++++ test/cli_test.py | 23 ++++++------- test/helper.py | 20 +++++++++++- 4 files changed, 81 insertions(+), 42 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index e2cebe0..b867c83 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 pytest + # - run: poetry run ruff format --check + # - run: poetry run ruff check + # - run: poetry run pyright --warnings + - run: poetry run pytest -k "ExternalCopyTest or ExternalConvertTest" - 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 457a99d..89494dc 100644 --- a/test/cli_test.py +++ b/test/cli_test.py @@ -1,5 +1,6 @@ import os import os.path +import platform import shutil import pytest @@ -7,7 +8,7 @@ from beets.ui import UserError from beets.util import bytestring_path, syspath from confuse import ConfigValueError -from helper import TestHelper, control_stdin +from helper import TestHelper, control_stdin, convert_command from mediafile import MediaFile from typeguard import check_type @@ -21,8 +22,7 @@ def test_external(self): external_dir = os.path.join(self.mkdtemp(), "myplayer") self.config["convert"]["formats"] = { "aac": { - "command": "bash -c \"cp '$source' '$dest';" - + "printf ISAAC >> '$dest'\"", + "command": convert_command("ISAAC"), "extension": "m4a", }, } @@ -97,6 +97,7 @@ def test_external(self): self.assertFileTag(external_beet, b"ISAAC") +@pytest.mark.skipif(platform.system() == "Windows", reason="no symlinks on windows") class SymlinkViewTest(TestHelper): """Test alternatives with the ``link`` format producing symbolic links.""" @@ -296,14 +297,13 @@ def test_move_after_path_format_update(self): self.assertIsFile(old_path) self.external_config["paths"] = {"default": "$album/$title"} - self.runcli("alt", "update", "myexternal") item.load() new_path = self.get_path(item) self.assertIsNotFile(old_path) self.assertIsFile(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) self.assertIsFile(old_path) @@ -311,7 +311,7 @@ def test_move_and_write_after_tags_changed(self): item["title"] = "a new title" item.store() item.try_write() # Required to update mtime. - self.runcli("alt", "update", "myexternal") + print(self.runcli("alt", "update", "myexternal")) item.load() new_path = self.get_path(item) @@ -319,6 +319,7 @@ def test_move_and_write_after_tags_changed(self): self.assertIsFile(new_path) mediafile = MediaFile(syspath(new_path)) assert mediafile.title == "a new title" + assert False def test_prune_after_move(self): item = self.add_external_track("myexternal") @@ -399,7 +400,7 @@ def touch_art(item, image_path): # affect the repository. image_dir = bytestring_path(self.mkdtemp()) image_path = os.path.join(image_dir, b"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. @@ -464,9 +465,7 @@ class ExternalConvertTest(TestHelper): def setUp(self): super().setUp() external_dir = self.mkdtemp() - 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, @@ -531,9 +530,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("MP3")} 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 c14cd7d..6b9c582 100644 --- a/test/helper.py +++ b/test/helper.py @@ -1,4 +1,5 @@ import os +import platform import shutil import sys import tempfile @@ -83,7 +84,9 @@ def assertFileTag(self, path, tag): self.assertIsFile(path) with open(syspath(path), "rb") as f: f.seek(-5, os.SEEK_END) - assert f.read() == tag + x = f.read() + print("tag", x) + assert x == tag def assertNotFileTag(self, path, tag): self.assertIsFile(path) @@ -322,3 +325,18 @@ def submit(self, *args, **kwargs): def shutdown(self, wait=True): pass + + +def convert_command(tag: str) -> str: + match platform.system(): + case "Windows": + return ( + 'powershell -Command "' + "Copy-Item -Path '$source' -Destination '$dest' -NoNewline;" + f"Add-Content -Path '$dest' -Value {tag}" + '"' + ) + case "Linux": + return f"bash -c\" cp '$source' '$dest'; printf {tag} >> '$dest' \"" + case system: + raise Exception(f"Unsupported system: {system}")