From d7c2f2bf1f51287e23881417bda8fefd05e17797 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 3 Jul 2024 22:45:20 +0200 Subject: [PATCH] Use PDM & Ruff instead of Poetry+Black+Flake8+isort --- .github/workflows/main.yml | 109 +++++++++++++++------------------ .gitignore | 3 +- .pre-commit-config.yaml | 21 ++----- pyproject.toml | 119 ++++++++++++++++++++++++------------- tasks.py | 75 ++++++++++++----------- tox.ini | 3 - 6 files changed, 171 insertions(+), 159 deletions(-) delete mode 100644 tox.ini diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 37ddfa7..ba41c23 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,102 +7,89 @@ env: jobs: test: - name: Test - ${{ matrix.python-version }} + name: Test - Python ${{ matrix.python-version }} runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} & PDM + uses: pdm-project/setup-pdm@v4 with: python-version: ${{ matrix.python-version }} - - name: Set up Pip cache - uses: actions/cache@v3 - id: pip-cache - with: - path: ~/.cache/pip - key: pip-${{ hashFiles('**/pyproject.toml') }} - - name: Upgrade Pip - run: python -m pip install --upgrade pip - - name: Install Poetry - run: python -m pip install poetry - - name: Set up Poetry cache - uses: actions/cache@v3 - id: poetry-cache - with: - path: ~/.cache/pypoetry/virtualenvs - key: poetry-${{ hashFiles('**/poetry.lock') }} - - name: Install dependencies - run: | - poetry run pip install --upgrade pip - poetry install - - name: Run tests - run: poetry run invoke tests + cache: true + cache-dependency-path: ./pyproject.toml + - name: Install dependencies + run: pdm install + + - name: Run tests + run: pdm run invoke tests lint: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - name: Validate links in Markdown files uses: JustinBeckwith/linkinator-action@v1 with: retry: true - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.9" - - name: Set Poetry cache - uses: actions/cache@v3 - id: poetry-cache - with: - path: ~/.cache/pypoetry/virtualenvs - key: poetry-${{ hashFiles('**/poetry.lock') }} - - name: Upgrade Pip - run: python -m pip install --upgrade pip - - name: Install Poetry - run: python -m pip install poetry - - name: Install dependencies - run: | - poetry run pip install --upgrade pip - poetry install - - name: Run linters - run: poetry run invoke lint + - name: Set up Python & PDM + uses: pdm-project/setup-pdm@v4 + with: + python-version: "3.10" + + - name: Install dependencies + run: pdm install + + - name: Run linters + run: pdm run invoke lint --diff deploy: name: Deploy environment: Deployment needs: [test, lint] runs-on: ubuntu-latest - if: ${{ github.ref=='refs/heads/main' && github.event_name!='pull_request' }} + if: github.ref=='refs/heads/main' && github.event_name!='pull_request' + + permissions: + contents: write + id-token: write steps: - - uses: actions/checkout@v3 - - name: Setup Python - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 with: - python-version: "3.9" + token: ${{ secrets.GH_TOKEN }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Check release id: check_release run: | - python -m pip install --upgrade pip - python -m pip install poetry githubrelease httpx==0.16.1 autopub - echo "##[set-output name=release;]$(autopub check)" + python -m pip install autopub httpx + python -m pip install https://github.com/scikit-build/github-release/archive/master.zip + autopub check + - name: Publish - if: ${{ steps.check_release.outputs.release=='' }} + if: ${{ steps.check_release.outputs.autopub_release=='true' }} env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - git remote set-url origin https://$GITHUB_TOKEN@github.com/${{ github.repository }} autopub prepare - poetry build autopub commit + autopub build autopub githubrelease - poetry publish -u __token__ -p $PYPI_PASSWORD + + - name: Upload package to PyPI + if: ${{ steps.check_release.outputs.autopub_release=='true' }} + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.gitignore b/.gitignore index c04bc49..12568d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -poetry.lock +.pdm-python +pdm.lock diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50d10db..9cdbf84 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,6 +10,7 @@ repos: - id: check-added-large-files - id: check-ast - id: check-case-conflict + - id: check-docstring-first - id: check-merge-conflict - id: check-toml - id: check-yaml @@ -19,19 +20,9 @@ repos: - id: forbid-new-submodules - id: trailing-whitespace - - repo: https://github.com/psf/black - rev: 24.4.2 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.0 hooks: - - id: black - - - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 - hooks: - - id: flake8 - args: [--max-line-length=88] - language_version: python3 - - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort + - id: ruff + - id: ruff-format + args: ["--check"] diff --git a/pyproject.toml b/pyproject.toml index 1c1dc0c..48209dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,53 +1,63 @@ -[tool.poetry] +[project] name = "pelican-share-post" version = "1.1.0" description = "A Pelican plugin to create share URLs of article" -authors = ["Talha Mansoor ", "Justin Mayer "] -license = "MIT" +authors = [{name = "Talha Mansoor", email = "talha131@gmail.com"}, {name = "Justin Mayer", email = "entroP@gmail.com"}] +license = {text = "MIT"} readme = "README.md" keywords = ["pelican", "plugin", "social"] -repository = "https://github.com/pelican-plugins/share-post" -documentation = "https://docs.getpelican.com" -packages = [ - { include = "pelican" }, -] - classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Framework :: Pelican", "Framework :: Pelican :: Plugins", "Intended Audience :: End Users/Desktop", + "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules", ] +requires-python = ">=3.8.1,<4.0" +dependencies = [ + "pelican>=4.5", + "beautifulsoup4>=4.9.3", +] -[tool.poetry.urls] -"Funding" = "https://donate.getpelican.com/" +[project.urls] +Homepage = "https://github.com/pelican-plugins/share-post" "Issue Tracker" = "https://github.com/pelican-plugins/share-post/issues" +Funding = "https://donate.getpelican.com/" -[tool.poetry.dependencies] -python = ">=3.7,<4.0" -pelican = ">=4.5" -markdown = {version = ">=3.2.2", optional = true} -beautifulsoup4 = "^4.9.3" -# Avoid PyPI/Poetry problem: https://github.com/python-poetry/poetry/issues/9293 -docutils = "!=0.21.post1" +[project.optional-dependencies] +markdown = ["markdown>=3.4"] -[tool.poetry.dev-dependencies] -black = ">=22.3.0" -flake8 = "^3.9" -flake8-black = "^0.3" -invoke = "^2.1" -isort = "^5.4" -markdown = "^3.4" -pytest = "^6.0" -pytest-cov = "^2.8" -pytest-sugar = "^0.9.7" +[tool.pdm] -[tool.poetry.extras] -markdown = ["markdown"] +[tool.pdm.dev-dependencies] +lint = [ + "invoke>=2.2", + "ruff>=0.5.0,<0.6.0" +] +test = [ + "markdown>=3.4", + "pytest>=7.0", + "pytest-cov>=4.0", + "pytest-sugar>=1.0", +] + +[tool.pdm.build] +source-includes = [ + "CHANGELOG.md", + "CONTRIBUTING.md", +] +includes = ["pelican/"] +excludes = ["**/.DS_Store", "**/test_data/**", "tasks.py"] [tool.autopub] project-name = "Share Post" @@ -55,18 +65,45 @@ git-username = "botpub" git-email = "52496925+botpub@users.noreply.github.com" append-github-contributor = true -[tool.isort] -# Maintain compatibility with Black -profile = "black" -multi_line_output = 3 +[tool.ruff.lint] +select = [ + "B", # flake8-bugbear + "BLE", # flake8-blind-except + "C4", # flake8-comprehensions + "D", # pydocstyle + "E", # pycodestyle + "F", # pyflakes + "I", # isort + "ICN", # flake8-import-conventions + "ISC", # flake8-implicit-str-concat + "PGH", # pygrep-hooks + "PL", # pylint + "RET", # flake8-return + "RUF", # ruff-specific rules + "SIM", # flake8-simplify + "T10", # flake8-debugger + "T20", # flake8-print + "TID", # flake8-tidy-imports + "TRY", # tryceratops + "UP", # pyupgrade + "W", # pycodestyle + "YTT", # flake8-2020 +] -# Sort imports within their section independent of the import type -force_sort_within_sections = true +ignore = [ + "D100", # missing docstring in public module + "D103", # missing docstring in public method + "D104", # missing docstring in public package + "D203", # blank line before class docstring + "D213", # multi-line docstring summary should start at the second line + "ISC001", # disabled so `ruff format` works without warning +] -# Designate "pelican" as separate import section -known_pelican = "pelican" -sections = "FUTURE,STDLIB,THIRDPARTY,PELICAN,FIRSTPARTY,LOCALFOLDER" +[tool.ruff.lint.isort] +combine-as-imports = true +force-sort-within-sections = true +known-first-party = ["pelican"] [build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +requires = ["pdm-backend"] +build-backend = "pdm.backend" diff --git a/tasks.py b/tasks.py index f0fbc52..3a8b167 100644 --- a/tasks.py +++ b/tasks.py @@ -1,14 +1,15 @@ from inspect import cleandoc +import logging import os from pathlib import Path from shutil import which -import sys from invoke import task +logger = logging.getLogger(__name__) + PKG_NAME = "share_post" PKG_PATH = Path(f"pelican/plugins/{PKG_NAME}") -TOOLS = ("poetry", "pre-commit") ACTIVE_VENV = os.environ.get("VIRTUAL_ENV", None) VENV_HOME = Path(os.environ.get("WORKON_HOME", "~/.local/share/virtualenvs")) @@ -16,52 +17,50 @@ VENV_PATH = Path(ACTIVE_VENV) if ACTIVE_VENV else (VENV_HOME.expanduser() / PKG_ VENV = str(VENV_PATH.expanduser()) BIN_DIR = "bin" if os.name != "nt" else "Scripts" VENV_BIN = Path(VENV) / Path(BIN_DIR) -POETRY = which("poetry") if which("poetry") else (VENV_BIN / "poetry") -CMD_PREFIX = f"{VENV_BIN}/" if ACTIVE_VENV else f"{POETRY} run " + +TOOLS = ("pdm", "pre-commit") +PDM = which("pdm") if which("pdm") else (VENV_BIN / "pdm") +CMD_PREFIX = f"{VENV_BIN}/" if ACTIVE_VENV else f"{PDM} run " PRECOMMIT = which("pre-commit") if which("pre-commit") else f"{CMD_PREFIX}pre-commit" -PTY = True if os.name != "nt" else False +PTY = os.name != "nt" @task -def tests(c): - """Run the test suite.""" - c.run(f"{CMD_PREFIX}pytest", pty=PTY) +def tests(c, deprecations=False): + """Run the test suite, optionally with `--deprecations`.""" + deprecations_flag = "" if deprecations else "-W ignore::DeprecationWarning" + c.run(f"{CMD_PREFIX}pytest {deprecations_flag}", pty=PTY) @task -def black(c, check=False, diff=False): - """Run Black auto-formatter, optionally with `--check` or `--diff`.""" +def format(c, check=False, diff=False): + """Run Ruff's auto-formatter, optionally with `--check` or `--diff`.""" check_flag, diff_flag = "", "" if check: check_flag = "--check" if diff: diff_flag = "--diff" - c.run(f"{CMD_PREFIX}black {check_flag} {diff_flag} {PKG_PATH} tasks.py") + c.run( + f"{CMD_PREFIX}ruff format {check_flag} {diff_flag} {PKG_PATH} tasks.py", pty=PTY + ) @task -def isort(c, check=False, diff=False): - """Ensure imports are sorted according to project standards.""" - check_flag, diff_flag = "", "" - if check: - check_flag = "-c" +def ruff(c, fix=False, diff=False): + """Run Ruff to ensure code meets project standards.""" + diff_flag, fix_flag = "", "" + if fix: + fix_flag = "--fix" if diff: diff_flag = "--diff" - c.run(f"{CMD_PREFIX}isort {check_flag} {diff_flag} .") + c.run(f"{CMD_PREFIX}ruff check {diff_flag} {fix_flag} .", pty=PTY) @task -def flake8(c): - """Check code for PEP8 compliance via Flake8.""" - c.run(f"{CMD_PREFIX}flake8 {PKG_PATH} tasks.py") - - -@task -def lint(c, diff=False): +def lint(c, fix=False, diff=False): """Check code style via linting tools.""" - isort(c, check=True, diff=diff) - black(c, check=True, diff=diff) - flake8(c) + ruff(c, fix=fix, diff=diff) + format(c, check=(not fix), diff=diff) @task @@ -69,34 +68,34 @@ def tools(c): """Install development tools in the virtual environment if not already on PATH.""" for tool in TOOLS: if not which(tool): - print(f"** Installing {tool}.") + logger.info(f"** Installing {tool} **") c.run(f"{CMD_PREFIX}pip install {tool}") @task def precommit(c): - """Install pre-commit hooks to `.git/hooks/pre-commit`.""" - print("** Installing pre-commit hooks.") + """Install pre-commit hooks to .git/hooks/pre-commit.""" + logger.info("** Installing pre-commit hooks **") c.run(f"{PRECOMMIT} install") @task def setup(c): """Set up the development environment.""" - if which("poetry") or ACTIVE_VENV: + if which("pdm") or ACTIVE_VENV: tools(c) - c.run(f"{CMD_PREFIX}python -m pip install --upgrade pip") - c.run(f"{POETRY} install") + c.run(f"{CMD_PREFIX}python -m pip install --upgrade pip", pty=PTY) + c.run(f"{PDM} update --dev", pty=PTY) precommit(c) - print("\nDevelopment environment should now be set up and ready!\n") + logger.info("\nDevelopment environment should now be set up and ready!\n") else: error_message = """ - Poetry is not installed, and there is no active virtual environment available. + PDM is not installed, and there is no active virtual environment available. You can either manually create and activate a virtual environment, or you can - install Poetry via: + install PDM via: - curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python - + curl -sSL https://raw.githubusercontent.com/pdm-project/pdm/main/install-pdm.py | python3 - Once you have taken one of the above two steps, run `invoke setup` again. """ # noqa: E501 - sys.exit(cleandoc(error_message)) + raise SystemExit(cleandoc(error_message)) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index abbd0dc..0000000 --- a/tox.ini +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -max-line-length = 88 -ignore = E203, W503