Use tox for building

This commit is contained in:
Timmy Welch 2023-04-22 17:54:58 -07:00
parent 5b3e9c9026
commit c4b7411261
No known key found for this signature in database
30 changed files with 437 additions and 494 deletions

View File

@ -1,6 +0,0 @@
[flake8]
max-line-length = 120
extend-ignore = E203, E501, A003
extend-exclude = venv, scripts, build, dist, comictaggerlib/ctversion.py
per-file-ignores =
comictaggerlib/cli.py: T20

View File

@ -1,8 +1,8 @@
name: CI
env:
PIP: pip
PYTHON: python
PKG_CONFIG_PATH: /usr/local/opt/icu4c/lib/pkgconfig
LC_COLLATE: en_US.UTF-8
on:
pull_request:
push:
@ -23,24 +23,18 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- uses: syphar/restore-virtualenv@v1.2
id: cache-virtualenv
- uses: syphar/restore-pip-download-cache@v1
if: steps.cache-virtualenv.outputs.cache-hit != 'true'
- name: Install build dependencies
run: |
python -m pip install --upgrade --upgrade-strategy eager -r requirements_dev.txt
python -m pip install flake8
- uses: reviewdog/action-setup@v1
with:
@ -57,72 +51,45 @@ jobs:
os: [ubuntu-latest, macos-10.15, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- uses: syphar/restore-virtualenv@v1.2
id: cache-virtualenv
- uses: syphar/restore-pip-download-cache@v1
if: steps.cache-virtualenv.outputs.cache-hit != 'true'
- name: Install build dependencies
- name: Install tox
run: |
python -m pip install --upgrade --upgrade-strategy eager -r requirements_dev.txt
python -m pip install --upgrade --upgrade-strategy eager tox
- name: Install Windows build dependencies
run: |
choco install -y zip
if: runner.os == 'Windows'
- name: Install macos dependencies
run: |
brew install icu4c pkg-config
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
python -m pip install --no-binary=pyicu pyicu
# export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
# export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
if: runner.os == 'macOS'
- name: Install linux dependencies
run: |
sudo apt-get install pkg-config libicu-dev libqt5gui5 libfuse2
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
python -m pip install --no-binary=pyicu pyicu
# export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
# export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
if: runner.os == 'Linux'
- name: Build and install PyPi packages
run: |
make clean pydist
python -m pip install "dist/$(python setup.py --fullname)-py3-none-any.whl[all]"
- name: build
run: |
make dist
- name: build appimage
run: |
make appimage
if: runner.os == 'Linux'
python -m tox r -m build
- name: Archive production artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: "${{ format('ComicTagger-{0}', runner.os) }}"
path: |
dist/*.zip
- name: Archive production artifacts - appimage
uses: actions/upload-artifact@v2
with:
name: "${{ format('ComicTagger-{0}', runner.os) }}"
path: |
dist/*.AppImage
- name: PyTest
run: |
python -m pytest
python -m tox r

View File

@ -1,8 +1,8 @@
name: Package
env:
PIP: pip
PYTHON: python
PKG_CONFIG_PATH: /usr/local/opt/icu4c/lib/pkgconfig
LC_COLLATE: en_US.UTF-8
on:
push:
tags:
@ -18,66 +18,41 @@ jobs:
os: [ubuntu-latest, macos-10.15, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- uses: syphar/restore-virtualenv@v1.2
id: cache-virtualenv
- uses: syphar/restore-pip-download-cache@v1
if: steps.cache-virtualenv.outputs.cache-hit != 'true'
- name: Install build dependencies
- name: Install tox
run: |
python -m pip install --upgrade --upgrade-strategy eager -r requirements_dev.txt
python -m pip install --upgrade --upgrade-strategy eager tox
- name: Install Windows build dependencies
run: |
choco install -y zip
if: runner.os == 'Windows'
- name: Install macos dependencies
run: |
brew install icu4c pkg-config
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
python -m pip install --no-binary=pyicu pyicu
# export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
# export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
if: runner.os == 'macOS'
- name: Install linux dependencies
run: |
sudo apt-get install pkg-config libicu-dev libqt5gui5
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
python -m pip install --no-binary=pyicu pyicu
# export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig";
# export PATH="/usr/local/opt/icu4c/bin:/usr/local/opt/icu4c/sbin:$PATH"
if: runner.os == 'Linux'
- name: Build, Install and Test PyPi packages
run: |
make clean pydist
python -m pip install "dist/$(python setup.py --fullname)-py3-none-any.whl[all]"
python -m flake8
python -m pytest
- name: "Publish distribution 📦 to PyPI"
if: startsWith(github.ref, 'refs/tags/') && runner.os == 'Linux'
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: dist
- name: Build PyInstaller package
run: |
make dist
- name: Build AppImage package
run: |
make appimage
if: runner.os == 'Linux'
python -m tox r
python -m tox r -m release
env:
TWINE_USERNAME=__token__
TWINE_PASSWORD=${{ secrets.PYPI_API_TOKEN }}
- name: Get release name
if: startsWith(github.ref, 'refs/tags/')

View File

@ -13,25 +13,25 @@ repos:
rev: v2.2.0
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
args: [--af,--add-import, 'from __future__ import annotations']
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- repo: https://github.com/PyCQA/autoflake
rev: v2.0.1
hooks:
- id: autoflake
args: [-i, --remove-all-unused-imports, --ignore-init-module-imports]
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
args: [--af,--add-import, 'from __future__ import annotations']
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:

View File

@ -1,59 +0,0 @@
language: python
# Only build tags
if: type = pull_request OR tag IS present
branches:
only:
- develop
- /^\d+\.\d+\.\d+.*$/
env:
global:
- PYTHON=python3
- PIP=pip3
- SETUPTOOLS_SCM_PRETEND_VERSION=$TRAVIS_TAG
- MAKE=make
matrix:
include:
- os: linux
python: 3.8
- name: "Python: 3.7"
os: osx
language: shell
python: 3.7
env: PYTHON=python3 PIP="python3 -m pip"
cache:
- directories:
- $HOME/Library/Caches/pip
- os: windows
language: bash
env: PATH=/C/Python37:/C/Python37/Scripts:$PATH MAKE=mingw32-make PIP=pip PYTHON=python
before_install:
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then choco install -y python --version 3.7.9; choco install -y mingw zip; fi
install:
- $PIP install -r requirements_dev.txt
- $PIP install -r requirements-GUI.txt
- $PIP install -r requirements-CBR.txt
script:
- if [ "$TRAVIS_OS_NAME" != "linux" ]; then $MAKE dist ; fi
deploy:
- name: "$TRAVIS_TAG"
body: Released ComicTagger $TRAVIS_TAG
provider: releases
skip_cleanup: true
api_key:
secure: RgohcOJOfLhXXT12bMWaLwOqhe+ClSCYXjYuUJuWK4/E1fdd1xu1ebdQU+MI/R8cZ0Efz3sr2n3NkO/Aa8gN68xEfuF7RVRMm64P9oPrfZgGdsD6H43rU/6kN8bgaDRmCYpLTfXaJ+/gq0x1QDkhWJuceF2BYEGGvL0BvS/TUsLyjVxs8ujTplLyguXHNEv4/7Yz7SBNZZmUHjBuq/y+l8ds3ra9rSgAVAN1tMXoFKJPv+SNNkpTo5WUNMPzBnN041F1rzqHwYDLog2V7Krp9JkXzheRFdAr51/tJBYzEd8AtYVdYvaIvoO6A4PiTZ7MpsmcZZPAWqLQU00UTm/PhT/LVR+7+f8lOBG07RgNNHB+edjDRz3TAuqyuZl9wURWTZKTPuO49TkZMz7Wm0DRNZHvBm1IXLeSG7Tll2YL1+WpZNZg+Dhro2J1QD3vxDXafhMdTCB4z0q5aKpG93IT0p6oXOO0oEGOPZYbA2c5R3SXWSyqd1E1gdhbVjIZr59h++TEf1zz07tvWHqPuAF/Ly/j+dIcY2wj0EzRWaSASWgUpTnMljAkHtWhqDw4GXGDRkRUWRJl1d0/JyVqCeIdRzDQNl8/q7BcO3F1zqr1PgnYdz0lfwWxL1/ekw2vHOJE/GOdkyvX0aJrnaOV338mjJbfGHYv4ESc9ow1kdtIbiU=
file_glob: true
file: dist/*.zip
draft: true
on:
tags: true
condition: $TRAVIS_OS_NAME != "linux"
- provider: pypi
user: __token__
password:
secure: h+y5WkE8igf864dnsbGPFvOBkyPkuBYtnDRt+EgxHd71EZnV2YP7ns2Cx12su/SVVDdZCBlmHVtkhl6Jmqy+0rTkSYx+3mlBOqyl8Cj5+BlP/dP7Bdmhs2uLZk2YYL1avbC0A6eoNJFtCkjurnB/jCGE433rvMECWJ5x2HsQTKchCmDAEdAZbRBJrzLFsrIC+6NXW1IJZjd+OojbhLSyVar2Jr32foh6huTcBu/x278V1+zIC/Rwy3W67+3c4aZxYrI47FoYFza0jjFfr3EoSkKYUSByMTIvhWaqB2gIsF0T160jgDd8Lcgej+86ACEuG0v01VE7xoougqlOaJ94eAmapeM7oQXzekSwSAxcK3JQSfgWk/AvPhp07T4pQ8vCZmky6yqvVp1EzfKarTeub1rOnv+qo1znKLrBtOoq6t8pOAeczDdIDs51XT/hxaijpMRCM8vHxN4Kqnc4DY+3KcF7UFyH1ifQJHQe71tLBsM/GnAcJM5/3ykFVGvRJ716p4aa6IoGsdNk6bqlysNh7nURDl+bfm+CDXRkO2jkFwUFNqPHW7JwY6ZFx+b5SM3TzC3obJhfMS7OC37fo2geISOTR0xVie6NvpN6TjNAxFTfDxWJI7yH3Al2w43B3uYDd97WeiN+B+HVWtdaER87IVSRbRqFrRub+V+xrozT0y0=
skip_existing: true
skip_cleanup: true
on:
tags: true
condition: $TRAVIS_OS_NAME = "linux"

View File

@ -41,7 +41,7 @@ Please open a [GitHub Pull Request](https://github.com/comictagger/comictagger/p
Currently only python 3.9 is supported however 3.10 will probably work if you try it
Those on linux should install `Pillow` from the system package manager if possible and if the GUI and/or the CBR/RAR comicbooks are going to be used `pyqt5` and `unrar-cffi` should be installed from the system package manager
Those on linux should install `Pillow` from the system package manager if possible and if the GUI `pyqt5` should be installed from the system package manager
Those on macOS will need to ensure that you are using python3 in x86 mode either by installing an x86 only version of python or using the universal installer and using `python3-intel64` instead of `python3`
@ -50,10 +50,10 @@ Those on macOS will need to ensure that you are using python3 in x86 mode either
git clone https://github.com/comictagger/comictagger.git
```
2. It is preferred to use a virtual env for running from source, adding the `--system-site-packages` allows packages already installed via the system package manager to be used:
2. It is preferred to use a virtual env for running from source:
```
python3 -m venv --system-site-packages venv
python3 -m venv venv
```
3. Activate the virtual env:
@ -65,73 +65,34 @@ or if on windows PowerShell
. venv/bin/activate.ps1
```
4. install dependencies:
4. Install tox:
```bash
pip install -r requirements_dev.txt -r requirements.txt
# if installing optional dependencies
pip install -r requirements-GUI.txt -r requirements-CBR.txt
pip install tox
```
5. install ComicTagger
5. If you are on an M1 Mac you will need to export two environment variables for tests to pass.
```
pip install .
export tox_python=python3.9-intel64
export tox_env=m1env
```
6. (optionally) run pytest to ensure that their are no failures (xfailed means expected failure)
6. install ComicTagger
```
$ pytest
============================= test session starts ==============================
platform darwin -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0
rootdir: /Users/timmy/build/source/comictagger
collected 61 items
tests/test_FilenameParser.py ..x......x.xxx.xx....xxxxxx.xx.x..xxxxxxx [ 67%]
tests/test_comicarchive.py x... [ 73%]
tests/test_rename.py ..xxx.xx..XXX.XX [100%]
================== 27 passed, 29 xfailed, 5 xpassed in 2.68s ===================
tox run -e venv
```
7. Make your changes
8. run code tools and correct any issues
8. Build to ensure that your changes work: this will produce a binary build in the dist folder
```bash
black .
isort .
flake8 .
pytest
tox run -m build
```
black: formats all of the code consistently so there are no surprises<br>
The build runs these formatters and linters automatically
setup-cfg-fmt: Formats the setup.cfg file
autoflake: Removes unused imports
isort: sorts imports so that you can always find where an import is located<br>
black: formats all of the code consistently so there are no surprises<br>
flake8: checks for code quality and style (warns for unused imports and similar issues)<br>
mypy: checks the types of variables and functions to catch errors
pytest: runs tests for ComicTagger functionality
if on mac or linux most of this can be accomplished by running
```
make install
# or make PYTHON=python3-intel64 install
. venv/bin/activate
make CI
```
There is also `make check` which will run all of the code tools in a read-only capacity
```
$ make check
venv/bin/black --check .
All done! ✨ 🍰 ✨
52 files would be left unchanged.
venv/bin/isort --check .
Skipped 6 files
venv/bin/flake8 .
venv/bin/pytest
============================= test session starts ==============================
platform darwin -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0
rootdir: /Users/timmy/build/source/comictagger
collected 61 items
tests/test_FilenameParser.py ..x......x.xxx.xx....xxxxxx.xx.x..xxxxxxx [ 67%]
tests/test_comicarchive.py x... [ 73%]
tests/test_rename.py ..xxx.xx..XXX.XX [100%]
================== 27 passed, 29 xfailed, 5 xpassed in 2.68s ===================
```

View File

@ -1,7 +0,0 @@
include README.md
include release_notes.txt
include requirements.txt
recursive-include scripts *.py *.txt
recursive-include desktop-integration *
include windows/app.ico
include mac/app.icns

View File

@ -1,76 +0,0 @@
PIP ?= pip3
PYTHON ?= python3
VERSION_STR := $(shell $(PYTHON) setup.py --version)
SITE_PACKAGES := $(shell $(PYTHON) -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])')
PACKAGE_PATH = $(SITE_PACKAGES)/comictagger.egg-link
VENV := $(shell echo $${VIRTUAL_ENV-venv})
PY3 := $(shell command -v $(PYTHON) 2> /dev/null)
PYTHON_VENV := $(VENV)/bin/python
INSTALL_STAMP := $(VENV)/.install.stamp
ifeq ($(OS),Windows_NT)
PYTHON_VENV := $(VENV)/Scripts/python.exe
OS_VERSION=win-$(PROCESSOR_ARCHITECTURE)
APP_NAME=comictagger.exe
FINAL_NAME=ComicTagger-$(VERSION_STR)-$(OS_VERSION).exe
else ifeq ($(shell uname -s),Darwin)
OS_VERSION=osx-$(shell defaults read loginwindow SystemVersionStampAsString)-$(shell uname -m)
APP_NAME=ComicTagger.app
FINAL_NAME=ComicTagger-$(VERSION_STR)-$(OS_VERSION).app
else
APP_NAME=comictagger
FINAL_NAME=ComicTagger-$(VERSION_STR)-$(shell uname -s)
endif
.PHONY: all clean pydist dist CI check appimage
all: clean dist
$(PYTHON_VENV):
@if [ -z $(PY3) ]; then echo "Python 3 could not be found."; exit 2; fi
$(PY3) -m venv $(VENV)
clean:
find . -maxdepth 4 -type d -name "__pycache__" -print -depth -exec rm -rf {} \;
rm -rf $(PACKAGE_PATH) $(INSTALL_STAMP) build dist MANIFEST comictaggerlib/ctversion.py
$(MAKE) -C mac clean
CI: install
$(PYTHON_VENV) -m black .
$(PYTHON_VENV) -m isort .
$(PYTHON_VENV) -m flake8 .
$(PYTHON_VENV) -m pytest
check: install
$(PYTHON_VENV) -m black --check .
$(PYTHON_VENV) -m isort --check .
$(PYTHON_VENV) -m flake8 .
$(PYTHON_VENV) -m pytest
pydist:
$(PYTHON_VENV) -m build
install: $(INSTALL_STAMP)
$(INSTALL_STAMP): $(PYTHON_VENV) requirements.txt requirements_dev.txt
$(PYTHON_VENV) -m pip install -r requirements_dev.txt
$(PYTHON_VENV) -m pip install -e .
touch $(INSTALL_STAMP)
dist: dist/$(FINAL_NAME).zip
dist/$(FINAL_NAME).zip:
pyinstaller -y comictagger.spec
cd dist && zip -r $(FINAL_NAME).zip $(APP_NAME)
dist/appimagetool:
curl -L https://github.com/AppImage/AppImageKit/releases/latest/download/appimagetool-x86_64.AppImage > dist/appimagetool
chmod +x dist/appimagetool
appimage: dist dist/appimagetool
rm -rf dist/appimage && cp -a dist/comictagger dist/appimage
cd dist/appimage/ && ln -s comictaggerlib/graphics/app.png app.png && ln -s comictagger AppRun
sed -e 's|/usr/local/share/comictagger/app.png|app|g' -e 's|%%CTSCRIPT%% %F|./comictagger|g' desktop-integration/linux/ComicTagger.desktop > dist/appimage/AppRun.desktop
cd dist && ./appimagetool appimage

View File

@ -35,7 +35,7 @@ For details, screen-shots, and more, visit [the Wiki](https://github.com/comicta
### Binaries
Windows and macOS binaries are provided in the [Releases Page](https://github.com/comictagger/comictagger/releases).
Windows, Linux and MacOS binaries are provided in the [Releases Page](https://github.com/comictagger/comictagger/releases).
Just unzip the archive in any folder and run, no additional installation steps are required.
@ -47,7 +47,14 @@ A pip package is provided, you can install it with:
$ pip3 install comictagger[GUI]
```
There are two optional dependencies GUI and CBR. You can install the optional dependencies by specifying one or more of `GUI`,`CBR` or `all` in braces e.g. `comictagger[CBR,GUI]`
There are optional dependencies. You can install the optional dependencies by specifying one or more of them in braces e.g. `comictagger[CBR,GUI]`
Optional dependencies:
1. `ICU`: Ensures that comic pages are supported correctly. This should always be installed. *Currently only exists in the latest alpha release *
1. `CBR`: Provides support for CBR/RAR files.
1. `GUI`: Installs the GUI.
1. `7Z`: Provides support for CB7/7Z files.
1. `all`: Installs all of the above optional dependencies.
### Chocolatey installation (Windows only)
@ -59,8 +66,7 @@ choco install comictagger
1. Ensure you have python 3.9 installed
2. Clone this repository `git clone https://github.com/comictagger/comictagger.git`
3. `pip3 install -r requirements_dev.txt`
7. `pip3 install .` or `pip3 install .[GUI]`
7. `pip3 install .[ICU]` or `pip3 install .[GUI,ICU]`
## Contributors

View File

@ -3,7 +3,7 @@ Encoding=UTF-8
Name=ComicTagger
GenericName=Comic Metadata Editor
Comment=A cross-platform GUI/CLI app for writing metadata to comic archives
Exec=%%CTSCRIPT%% %F
Exec=comictagger %F
Icon=/usr/local/share/comictagger/app.png
Terminal=false
Type=Application

View File

@ -9,7 +9,7 @@ block_cipher = None
a = Analysis(
["comictaggerlib/__main__.py"],
["../comictaggerlib/__main__.py"],
pathex=[],
binaries=[],
datas=[],
@ -237,5 +237,5 @@ if platform.system() not in ["Windows"]:
},
],
},
bundle_identifier=None,
bundle_identifier="com.comictagger",
)

View File

@ -0,0 +1,26 @@
from __future__ import annotations
import os
import pathlib
import stat
import requests
def urlretrieve(url: str, dest: str) -> None:
resp = requests.get(url)
if resp.status_code == 200:
pathlib.Path(dest).write_bytes(resp.content)
APPIMAGETOOL = "build/appimagetool-x86_64.AppImage"
if os.path.exists(APPIMAGETOOL):
raise SystemExit(0)
urlretrieve(
"https://github.com/AppImage/AppImageKit/releases/latest/download/appimagetool-x86_64.AppImage", APPIMAGETOOL
)
os.chmod(APPIMAGETOOL, stat.S_IRWXU)
if not os.path.exists(APPIMAGETOOL):
raise SystemExit(1)

View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -0,0 +1,47 @@
from __future__ import annotations
import os
import pathlib
import platform
import zipfile
from comictaggerlib.ctversion import __version__
app = "ComicTagger"
exe = app.casefold()
if platform.system() == "Windows":
os_version = f"win-{platform.machine()}"
app_name = f"{exe}.exe"
final_name = f"{app}-{__version__}-{os_version}.exe"
elif platform.system() == "Darwin":
ver = platform.mac_ver()
os_version = f"osx-{ver[0]}-{ver[2]}"
app_name = f"{app}.app"
final_name = f"{app}-{__version__}-{os_version}.app"
else:
app_name = exe
final_name = f"ComicTagger-{__version__}-{platform.system()}"
path = f"dist/{app_name}"
zip_file = pathlib.Path(f"dist/{final_name}.zip")
def addToZip(zf, path, zippath):
if os.path.isfile(path):
zf.write(path, zippath)
elif os.path.isdir(path):
if zippath:
zf.write(path, zippath)
for nm in sorted(os.listdir(path)):
addToZip(zf, os.path.join(path, nm), os.path.join(zippath, nm))
# else: ignore
zip_file.unlink(missing_ok=True)
with zipfile.ZipFile(zip_file, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=8) as zf:
zippath = os.path.basename(path)
if not zippath:
zippath = os.path.basename(os.path.dirname(path))
if zippath in ("", os.curdir, os.pardir):
zippath = ""
addToZip(zf, path, zippath)

View File

@ -20,6 +20,7 @@ import logging
import os
import pathlib
import string
from collections.abc import Mapping, Sequence
from typing import Any, cast
from pathvalidate import Platform, normalize_platform, sanitize_filename
@ -94,8 +95,8 @@ class MetadataFormatter(string.Formatter):
def _vformat(
self,
format_string: str,
args: list[Any],
kwargs: dict[str, Any],
args: Sequence[Any],
kwargs: Mapping[str, Any],
used_args: set[Any],
recursion_depth: int,
auto_arg_index: int = 0,

View File

@ -1,4 +0,0 @@
This file is a placeholder that will automatically be replaced with a symlink to
the local machine's Python framework python binary.
When pip does an uninstall, it will remove the link.

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>main.sh</string>
<key>CFBundleIconFile</key>
<string>app.icns</string>
<key>CFBundleIdentifier</key>
<string>org.comictagger.comictagger</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ComicTagger</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>%%CTVERSION%%</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>%%CTVERSION%%</string>
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -1,17 +0,0 @@
#!/bin/sh
# This is a lot of hoop-jumping to get the absolute path
# of this script, so that we can use the Symlinked python
# binary to call the CT script. This is all so that the
# Mac menu doesn't say "Python".
realpath()
{
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
CTSCRIPT=%%CTSCRIPT%%
THIS=$(realpath $0)
THIS_FOLDER=$(dirname $THIS)
"$THIS_FOLDER/ComicTagger" "$CTSCRIPT"

View File

@ -1,4 +0,0 @@
This file is a placeholder that will automatically be replaced with a Windows
shortcut on the user's desktop.
When pip does an uninstall, it will remove the shortcut file.

View File

@ -1 +0,0 @@
py7zr

View File

@ -1 +0,0 @@
rarfile>=4.0

View File

@ -1 +0,0 @@
PyQt5

View File

@ -1,14 +0,0 @@
appdirs==1.4.4
beautifulsoup4>=4.1
importlib_metadata>=3.3.0
natsort>=8.1.0
pathvalidate
pillow>=9.1.0, <10
pycountry
#pyicu; sys_platform == 'linux' or sys_platform == 'darwin'
rapidfuzz>=2.12.0
requests==2.*
settngs==0.6.2
text2digits
typing_extensions
wordninja

View File

@ -1,12 +0,0 @@
black>=22
build
flake8==4.*
flake8-black
flake8-encodings
flake8-isort
isort>=5.10
pyinstaller>=5.6.2
pytest==7.*
setuptools>=42
setuptools_scm[toml]>=3.4
wheel

281
setup.cfg Normal file
View File

@ -0,0 +1,281 @@
[metadata]
name = comictagger
description = A cross-platform GUI/CLI app for writing metadata to comic archives
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/comictagger/comictagger
author = ComicTagger team
author_email = comictagger@gmail.com
license = Apache License 2.0
classifiers =
Development Status :: 4 - Beta
Environment :: Console
Environment :: MacOS X
Environment :: Win32 (MS Windows)
Environment :: X11 Applications :: Qt
Intended Audience :: End Users/Desktop
License :: OSI Approved :: Apache Software License
Natural Language :: English
Operating System :: OS Independent
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
Topic :: Multimedia :: Graphics
Topic :: Other/Nonlisted Topic
Topic :: Utilities
keywords =
comictagger
comics
comic
metadata
tagging
tagger
[options]
packages = find:
install_requires =
appdirs==1.4.4
beautifulsoup4>=4.1
importlib-metadata>=3.3.0
natsort>=8.1.0
pathvalidate
pillow>=9.1.0,<10
pycountry
rapidfuzz>=2.12.0
requests==2.*
settngs==0.6.2
text2digits
typing-extensions
wordninja
python_requires = >=3.9
[options.packages.find]
exclude = tests; testing
[options.entry_points]
console_scripts = comictagger=comictaggerlib.main:main
comicapi.archiver =
zip = comicapi.archivers.zip:ZipArchiver
sevenzip = comicapi.archivers.sevenzip:SevenZipArchiver
rar = comicapi.archivers.rar:RarArchiver
folder = comicapi.archivers.folder:FolderArchiver
comictagger.talker =
comicvine = comictalker.talkers.comicvine:ComicVineTalker
pyinstaller40 =
hook-dirs = comictaggerlib.__pyinstaller:get_hook_dirs
[options.extras_require]
7Z =
py7zr
CBR =
rarfile>=4.0
GUI =
PyQt5
ICU =
pyicu;sys_platform == 'linux' or sys_platform == 'darwin'
all =
PyQt5
py7zr
rarfile>=4.0
pyicu;sys_platform == 'linux' or sys_platform == 'darwin'
[options.package_data]
comicapi =
data/*
comictaggerlib =
ui/*
graphics/*
[tox:tox]
env_list =
format
py3.9-{none,gui,7z,cbr,icu,all}
minversion = 4.4.12
basepython = {env:tox_python:python3.9}
[testenv]
description = run the tests with pytest
package = wheel
wheel_build_env = .pkg
deps =
pytest>=7
extras =
7z: 7Z
cbr: CBR
gui: GUI
icu: ICU
all: all
commands =
python -m pytest {tty:--color=yes} {posargs}
icu,all: python -c 'import importlib,platform; importlib.import_module("icu") if platform.system() != "Windows" else ...' # Sanity check for icu
[m1env]
description = run the tests with pytest
package = wheel
wheel_build_env = .pkg
deps =
pytest>=7
icu,all: pyicu-binary
extras =
7z: 7Z
cbr: CBR
gui: GUI
all: 7Z,CBR,GUI
[testenv:py3.9-{icu,all}]
base = {env:tox_env:testenv}
[testenv:format]
labels =
release
build
skip_install = true
deps =
black>=22
isort>=5.10
setup-cfg-fmt
autoflake
pyupgrade
commands =
-setup-cfg-fmt setup.cfg
-python -m autoflake -i --remove-all-unused-imports --ignore-init-module-imports .
-python -m isort --af --add-import 'from __future__ import annotations' .
-python -m black .
[testenv:lint]
labels =
release
skip_install = true
depends = format
deps =
flake8==4.*
flake8-black
flake8-encodings
flake8-isort
mypy
types-setuptools
types-requests
commands =
python -m flake8 .
python -m mypy --ignore-missing-imports comicapi comictaggerlib comictalker
[testenv:clean]
description = Clean development outputs
labels =
release
build
depends =
format
lint
skip_install = true
commands =
-python -c 'import shutil,pathlib; \
shutil.rmtree("./build/", ignore_errors=True); \
shutil.rmtree("./dist/", ignore_errors=True); \
pathlib.Path("./comictaggerlib/ctversion.py").unlink(missing_ok=True); \
pathlib.Path("comictagger.spec").unlink(missing_ok=True)'
[testenv:wheel]
description = Generate wheel and tar.gz
labels =
release
build
depends = clean
skip_install = true
deps =
build
commands =
python -m build
[testenv:pypi-upload]
description = Upload wheel to PyPi
platform = Linux
labels =
release
skip_install = true
depends = wheel
deps =
twine
passenv =
TWINE_*
setenv =
TWINE_NON_INTERACTIVE=true
commands =
python -m twine upload dist/*.whl dist/*.tar.gz
[testenv:pyinstaller]
description = Generate pyinstaller executable
labels =
release
build
base = {env:tox_env:testenv}
depends =
clean
pypi-upload
deps =
pyinstaller>=5.6.2
extras =
all
commands =
python -c 'import importlib,platform; importlib.import_module("icu") if platform.system() != "Windows" else ...' # Sanity check for icu
pyinstaller -y build-tools/comictagger.spec
[testenv:appimage]
description = Generate appimage executable
skip_install = true
platform = Linux
base = {env:tox_env:testenv}
labels =
release
build
depends =
clean
pypi-upload
pyinstaller
deps =
requests
extras =
all
commands =
python -c 'import importlib,platform; importlib.import_module("icu") if platform.system() != "Windows" else ...' # Sanity check for icu
-python -c 'import shutil; shutil.rmtree("./build/", ignore_errors=True)'
python -c 'import shutil,pathlib; shutil.copytree("./dist/comictagger/", "./build/appimage", dirs_exist_ok=True); \
shutil.copy("./comictaggerlib/graphics/app.png", "./build/appimage/app.png"); \
pathlib.Path("./build/appimage/AppRun").symlink_to("comictagger"); \
pathlib.Path("./build/appimage/AppRun.desktop").write_text( \
pathlib.Path("build-tools/ComicTagger.desktop").read_text() \
.replace("/usr/local/share/comictagger/app.png", "app") \
.replace("Exec=comictagger", "Exec=./comictagger"))'
python ./build-tools/get_appimage.py
./build/appimagetool ./build/appimage
[testenv:zip_artifacts]
description = Zip release artifacts
labels =
release
build
depends =
wheel
pyinstaller
appimage
commands =
python ./build-tools/zip_artifacts.py
[testenv:venv]
envdir = venv
deps =
flake8==4.*
flake8-black
flake8-encodings
flake8-isort
mypy
types-setuptools
types-requests
build
pyinstaller>=5.6.2
[flake8]
max-line-length = 120
extend-ignore = E203, E501, A003
extend-exclude = venv, scripts, build, dist, comictaggerlib/ctversion.py
per-file-ignores =
comictaggerlib/cli.py: T20

View File

@ -1,92 +1,5 @@
# Setup file for comictagger python source (no wheels yet)
#
# An entry point script called "comictagger" will be created
#
# Currently commented out, an experiment at desktop integration.
# It seems that post installation tweaks are broken by wheel files.
# Kept here for further research
from __future__ import annotations
import glob
import os
from setuptools import setup
from setuptools import find_packages, setup
def read(fname: str) -> str:
"""
Read the contents of a file.
Parameters
----------
fname : str
Path to file.
Returns
-------
str
File contents.
"""
with open(os.path.join(os.path.dirname(__file__), fname), encoding="utf-8") as f:
return f.read()
install_requires = read("requirements.txt").splitlines()
# Dynamically determine extra dependencies
extras_require = {}
extra_req_files = glob.glob("requirements-*.txt")
for extra_req_file in extra_req_files:
name = os.path.splitext(extra_req_file)[0].removeprefix("requirements-")
extras_require[name] = read(extra_req_file).splitlines()
# If there are any extras, add a catch-all case that includes everything.
# This assumes that entries in extras_require are lists (not single strings),
# and that there are no duplicated packages across the extras.
if extras_require:
extras_require["all"] = sorted({x for v in extras_require.values() for x in v})
setup(
name="comictagger",
install_requires=install_requires,
extras_require=extras_require,
python_requires=">=3.9",
description="A cross-platform GUI/CLI app for writing metadata to comic archives",
author="ComicTagger team",
author_email="comictagger@gmail.com",
url="https://github.com/comictagger/comictagger",
packages=find_packages(exclude=["tests", "testing"]),
package_data={"comictaggerlib": ["ui/*", "graphics/*"], "comicapi": ["data/*"]},
entry_points={
"console_scripts": ["comictagger=comictaggerlib.main:main"],
"pyinstaller40": ["hook-dirs = comictaggerlib.__pyinstaller:get_hook_dirs"],
"comicapi.archiver": [
"zip = comicapi.archivers.zip:ZipArchiver",
"sevenzip = comicapi.archivers.sevenzip:SevenZipArchiver",
"rar = comicapi.archivers.rar:RarArchiver",
"folder = comicapi.archivers.folder:FolderArchiver",
],
"comictagger.talker": [
"comicvine = comictalker.talkers.comicvine:ComicVineTalker",
],
},
classifiers=[
"Development Status :: 4 - Beta",
"Environment :: Console",
"Environment :: Win32 (MS Windows)",
"Environment :: MacOS X",
"Environment :: X11 Applications :: Qt",
"Intended Audience :: End Users/Desktop",
"License :: OSI Approved :: Apache Software License",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.9",
"Topic :: Utilities",
"Topic :: Other/Nonlisted Topic",
"Topic :: Multimedia :: Graphics",
],
keywords=["comictagger", "comics", "comic", "metadata", "tagging", "tagger"],
license="Apache License 2.0",
long_description=read("README.md"),
long_description_content_type="text/markdown",
)
setup()