mirror of
https://github.com/beetbox/beets.git
synced 2026-07-16 17:48:54 -04:00
- Use uv tool install for poethepoet in GitHub workflows and contributor docs. - Recommend uv tool for isolated beets and plugin installs.
339 lines
8.7 KiB
TOML
339 lines
8.7 KiB
TOML
[project]
|
|
name = "beets"
|
|
version = "2.12.0"
|
|
description = "music tagger and library organizer"
|
|
authors = [{ name = "Adrian Sampson", email = "adrian@radbox.org" }]
|
|
maintainers = [{ name = "Serene-Arc" }]
|
|
license = { text = "MIT" }
|
|
readme = "README.rst"
|
|
requires-python = ">=3.10,<3.15"
|
|
classifiers = [
|
|
"Topic :: Multimedia :: Sound/Audio",
|
|
"Topic :: Multimedia :: Sound/Audio :: Players :: MP3",
|
|
"License :: OSI Approved :: MIT License",
|
|
"Environment :: Console",
|
|
"Environment :: Web Environment",
|
|
"Programming Language :: Python",
|
|
"Programming Language :: Python :: 3",
|
|
"Programming Language :: Python :: 3.10",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: 3.13",
|
|
"Programming Language :: Python :: 3.14",
|
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
]
|
|
|
|
dependencies = [
|
|
"colorama ; sys_platform == 'win32'",
|
|
"confuse>=2.2.0",
|
|
"jellyfish",
|
|
"lap>=0.5.12",
|
|
"mediafile>=0.17.0",
|
|
"numpy>=2.0.2 ; python_version < '3.13'",
|
|
"numpy>=2.3.5 ; python_version >= '3.13'",
|
|
"packaging>=24.0",
|
|
"platformdirs>=3.5.0",
|
|
"pyyaml",
|
|
"requests>=2.32.5",
|
|
"requests-ratelimiter>=0.7.0",
|
|
"typing_extensions",
|
|
"unidecode>=1.3.6",
|
|
]
|
|
|
|
[dependency-groups]
|
|
docs = [
|
|
"docutils>=0.20.1",
|
|
"pydata-sphinx-theme",
|
|
"sphinx<9",
|
|
"sphinx-lint>=1.0.0",
|
|
"sphinx-design>=0.6.1",
|
|
"sphinx-copybutton>=0.5.2",
|
|
"sphinx-toolbox>=4.1.0",
|
|
"titlecase>=2.4.1,<3",
|
|
]
|
|
test = [
|
|
"beautifulsoup4",
|
|
"codecov>=2.1.13",
|
|
"flask",
|
|
"langdetect",
|
|
"pylast",
|
|
"pytest",
|
|
"pytest-cov",
|
|
"pytest-factoryboy>=2.8.1",
|
|
"pytest-flask",
|
|
"python-mpd2",
|
|
"python3-discogs-client>=2.3.15",
|
|
"py7zr",
|
|
"pyxdg",
|
|
"rarfile",
|
|
"requests-mock>=1.12.1",
|
|
"requests-oauthlib",
|
|
"responses>=0.3.0",
|
|
"titlecase>=2.4.1,<3",
|
|
]
|
|
lint = [
|
|
"docstrfmt>=2.0.2",
|
|
"ruff>=0.13.0",
|
|
"sphinx-lint>=1.0.0",
|
|
]
|
|
typing = [
|
|
"mypy",
|
|
"types-beautifulsoup4",
|
|
"types-docutils>=0.22.2.20251006",
|
|
"types-Flask-Cors",
|
|
"types-Pillow",
|
|
"types-PyYAML",
|
|
"types-requests",
|
|
"types-urllib3",
|
|
]
|
|
release = [
|
|
"click>=8.1.7",
|
|
"tomli>=2.0.1",
|
|
]
|
|
dev = [
|
|
{ include-group = "docs" },
|
|
{ include-group = "lint" },
|
|
{ include-group = "test" },
|
|
{ include-group = "typing" },
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
# inline comments note required external / non-python dependencies
|
|
absubmit = ["requests"] # extractor binary from https://acousticbrainz.org/download
|
|
aura = ["flask", "flask-cors", "Pillow"]
|
|
autobpm = ["librosa>=0.11", "resampy>=0.4.3"]
|
|
# badfiles # mp3val and flac
|
|
beatport = ["requests-oauthlib>=0.6.1"]
|
|
bpd = [
|
|
"PyGObject ; sys_platform != 'win32'",
|
|
] # gobject-introspection, gstreamer1.0-plugins-base, python3-gst-1.0
|
|
chroma = ["pyacoustid>=1.3.1,<2"] # chromaprint or fpcalc
|
|
# convert # ffmpeg
|
|
discogs = ["python3-discogs-client>=2.3.15"]
|
|
embedart = ["Pillow"] # ImageMagick
|
|
embyupdate = ["requests"]
|
|
fetchart = ["beautifulsoup4", "langdetect", "Pillow", "requests"]
|
|
import = ["py7zr", "rarfile"]
|
|
# ipfs # go-ipfs
|
|
# keyfinder # KeyFinder
|
|
kodiupdate = ["requests"]
|
|
lastgenre = ["pylast"]
|
|
lastimport = ["pylast"]
|
|
lyrics = ["beautifulsoup4", "langdetect", "requests"]
|
|
metasync = ["dbus-python ; sys_platform != 'win32'"]
|
|
mpdstats = ["python-mpd2>=0.4.2"]
|
|
plexupdate = ["requests"]
|
|
reflink = ["reflink"]
|
|
replaygain = [
|
|
"PyGObject ; sys_platform != 'win32'",
|
|
] # python-gi and GStreamer 1.0+ or mp3gain/aacgain or Python Audio Tools or ffmpeg
|
|
scrub = ["mutagen>=1.33"]
|
|
sonosupdate = ["soco"]
|
|
tidal = ["requests-oauthlib>=0.6.1"]
|
|
titlecase = ["titlecase"]
|
|
thumbnails = ["Pillow", "pyxdg"]
|
|
web = ["flask", "flask-cors"]
|
|
|
|
[project.scripts]
|
|
beet = "beets.ui:main"
|
|
|
|
[project.urls]
|
|
Homepage = "https://beets.io/"
|
|
Repository = "https://github.com/beetbox/beets"
|
|
Documentation = "https://beets.readthedocs.io/en/stable/"
|
|
Changelog = "https://github.com/beetbox/beets/blob/master/docs/changelog.rst"
|
|
"Bug Tracker" = "https://github.com/beetbox/beets/issues"
|
|
|
|
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
packages = ["beets", "beetsplug"]
|
|
|
|
[tool.hatch.build.targets.sdist]
|
|
include = [
|
|
"beets/",
|
|
"beetsplug/",
|
|
"docs/",
|
|
"extra/",
|
|
"man/",
|
|
"test/",
|
|
]
|
|
exclude = [
|
|
"docs/_build/",
|
|
"docs/modd.conf",
|
|
"docs/**/*.css",
|
|
]
|
|
|
|
[tool.poe.tasks.build]
|
|
help = "Build the package"
|
|
shell = """
|
|
make -C docs man
|
|
rm -rf man
|
|
mv docs/_build/man .
|
|
uv build
|
|
"""
|
|
|
|
[tool.poe.tasks.bump]
|
|
help = "Bump project version and update relevant files"
|
|
cmd = "python ./extra/release.py bump $version"
|
|
args = { version = { help = "The new version to set", positional = true, required = true } }
|
|
|
|
[tool.poe.tasks.changelog]
|
|
help = "Print the latest version's changelog in Markdown"
|
|
cmd = "python ./extra/release.py changelog"
|
|
|
|
[tool.poe.tasks.check-docs-links]
|
|
help = "Check the documentation for broken URLs"
|
|
cmd = "make -C docs linkcheck"
|
|
|
|
[tool.poe.tasks.check-format]
|
|
help = "Check the code for style issues"
|
|
cmd = "ruff format --check --diff"
|
|
|
|
[tool.poe.tasks.check-types]
|
|
help = "Check the code for typing issues. Accepts mypy options."
|
|
cmd = "mypy"
|
|
|
|
[tool.poe.tasks.docs]
|
|
help = "Build documentation"
|
|
args = [{ name = "COMMANDS", positional = true, multiple = true, default = "html" }]
|
|
cmd = "make -C docs $COMMANDS"
|
|
|
|
[tool.poe.tasks.format]
|
|
help = "Format the codebase"
|
|
cmd = "ruff format --config=pyproject.toml"
|
|
|
|
[tool.poe.tasks.format-docs]
|
|
help = "Format the documentation"
|
|
cmd = "docstrfmt --preserve-adornments docs *.rst"
|
|
|
|
[tool.poe.tasks.install]
|
|
help = "Install project dependencies"
|
|
cmd = "uv sync --locked"
|
|
|
|
[tool.poe.tasks.lint]
|
|
help = "Check the code for linting issues. Accepts ruff options."
|
|
cmd = "ruff check --config=pyproject.toml"
|
|
|
|
[tool.poe.tasks.lint-docs]
|
|
help = "Lint the documentation"
|
|
interpreter = "bash"
|
|
shell = """
|
|
set -o pipefail
|
|
files=$(git ls-files '*.rst')
|
|
|
|
grep -Eno ' `[^`][^`]+`[^_]' $files |
|
|
sed 's/ .*/ Use double backticks for inline literal (double-backticks-required)/' && failed=1
|
|
sphinx-lint --enable all --disable default-role $files || failed=1
|
|
|
|
exit ${failed:-0}
|
|
"""
|
|
|
|
[tool.poe.tasks.update-dependencies]
|
|
help = "Update dependencies to their latest versions."
|
|
cmd = "uv sync --upgrade"
|
|
|
|
[tool.poe.tasks.test]
|
|
help = "Run tests with pytest"
|
|
cmd = "uv run pytest $OPTS"
|
|
env.OPTS.default = "-p no:cov"
|
|
|
|
[tool.poe.tasks.test-with-coverage]
|
|
help = "Run tests and record coverage"
|
|
ref = "test"
|
|
# record coverage in beets and beetsplug packages
|
|
# save xml for coverage upload to coveralls
|
|
# save html report for local dev use
|
|
# measure coverage across logical branches
|
|
# show which tests cover specific lines in the code (see the HTML report)
|
|
env.OPTS = """
|
|
--cov=.
|
|
--cov-report=xml:.reports/coverage.xml
|
|
--cov-report=html:.reports/html
|
|
--cov-branch
|
|
--cov-context=test
|
|
"""
|
|
|
|
[tool.poe.tasks.check-temp-files]
|
|
help = "Run each test module one by one and check for leftover temp files"
|
|
shell = """
|
|
setopt nullglob
|
|
for file in test/**/*.py; do
|
|
print Temp files created by $file && poe test $file &>/dev/null
|
|
tempfiles=(/tmp/**/tmp* /tmp/beets/**/*)
|
|
if (( $#tempfiles )); then
|
|
print -l $'\t'$^tempfiles
|
|
rm -r --interactive=never $tempfiles &>/dev/null
|
|
fi
|
|
done
|
|
"""
|
|
interpreter = "zsh"
|
|
|
|
[tool.docstrfmt]
|
|
line-length = 80
|
|
extend-exclude = [
|
|
"docs/_templates/**/*",
|
|
"docs/api/**/*",
|
|
"README_kr.rst",
|
|
]
|
|
|
|
[tool.ruff]
|
|
target-version = "py310"
|
|
line-length = 80
|
|
|
|
[tool.ruff.format]
|
|
skip-magic-trailing-comma = true
|
|
|
|
[tool.ruff.lint]
|
|
future-annotations = true
|
|
select = [
|
|
"A", # flake8-builtins
|
|
# "ARG", # flake8-unused-arguments
|
|
# "C4", # flake8-comprehensions
|
|
"E", # pycodestyle
|
|
"F", # pyflakes
|
|
# "B", # flake8-bugbear
|
|
"G", # flake8-logging-format
|
|
"I", # isort
|
|
"ISC", # flake8-implicit-str-concat
|
|
"N", # pep8-naming
|
|
"PIE", # flake8-pie
|
|
"PT", # flake8-pytest-style
|
|
"RET", # flake8-return
|
|
"RUF", # ruff
|
|
"UP", # pyupgrade
|
|
"TC", # flake8-type-checking
|
|
"W", # pycodestyle
|
|
]
|
|
ignore = [
|
|
"TC006", # no need to quote 'cast's since we use 'from __future__ import annotations'
|
|
]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"beets/**" = ["PT"]
|
|
"test/plugins/test_ftintitle.py" = ["E501"]
|
|
"test/test_util.py" = ["E501"]
|
|
"test/util/test_diff.py" = ["E501"]
|
|
"test/util/test_id_extractors.py" = ["E501"]
|
|
"test/**" = ["RUF001"] # we use Unicode characters in tests
|
|
|
|
[tool.ruff.lint.isort]
|
|
split-on-trailing-comma = false
|
|
|
|
[tool.ruff.lint.pycodestyle]
|
|
max-line-length = 88
|
|
|
|
[tool.ruff.lint.flake8-pytest-style]
|
|
fixture-parentheses = false
|
|
mark-parentheses = false
|
|
parametrize-names-type = "csv"
|
|
|
|
[tool.ruff.lint.flake8-unused-arguments]
|
|
ignore-variadic-names = true
|
|
|
|
[tool.ruff.lint.pep8-naming]
|
|
classmethod-decorators = ["cached_classproperty"]
|
|
extend-ignore-names = ["assert*", "cached_classproperty"]
|