diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d867122f80..0127982ef3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,23 +51,18 @@ jobs: lint: name: Lint runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - - name: Install Poetry - run: pipx install poetry - - name: Set up Python - uses: actions/setup-python@v4 + - uses: pdm-project/setup-pdm@v3 with: - python-version: "3.9" - cache: "poetry" - cache-dependency-path: "pyproject.toml" + python-version: 3.9 + cache: true + cache-dependency-path: ./pyproject.toml - name: Install dependencies run: | - poetry env use "3.9" - poetry install --no-interaction --no-root + pdm install --no-default --dev - name: Run linters - run: poetry run invoke lint --diff + run: pdm lint --diff docs: name: Build docs diff --git a/.gitignore b/.gitignore index b94526d649..b27f3eb92e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ htmlcov venv samples/output *.pem -poetry.lock +*.lock +.pdm-python diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 87d433a8de..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -include *.rst -recursive-include pelican *.html *.css *png *.rst *.markdown *.md *.mkd *.xml *.py *.jinja2 -include LICENSE THANKS docs/changelog.rst pyproject.toml -graft samples -global-exclude __pycache__ -global-exclude *.py[co] \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index f00ed3c2d6..8d8078a279 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,48 +2,58 @@ import os import sys -from pelican import __version__ +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + sys.path.append(os.path.abspath(os.pardir)) + +with open("../pyproject.toml", "rb") as f: + project_data = tomllib.load(f).get("project") + if project_data is None: + raise KeyError("project data is not found") + + # -- General configuration ---------------------------------------------------- -templates_path = ['_templates'] +templates_path = ["_templates"] extensions = [ "sphinx.ext.autodoc", "sphinx.ext.ifconfig", "sphinx.ext.extlinks", "sphinxext.opengraph", ] -source_suffix = '.rst' -master_doc = 'index' -project = 'Pelican' +source_suffix = ".rst" +master_doc = "index" +project = project_data.get("name").upper() year = datetime.datetime.now().date().year -copyright = f'2010–{year}' -exclude_patterns = ['_build'] -release = __version__ -version = '.'.join(release.split('.')[:1]) -last_stable = __version__ -rst_prolog = ''' -.. |last_stable| replace:: :pelican-doc:`{}` -'''.format(last_stable) - -extlinks = { - 'pelican-doc': ('https://docs.getpelican.com/en/latest/%s.html', '%s') -} +copyright = f"2010–{year}" +exclude_patterns = ["_build"] +release = project_data.get("version") +version = ".".join(release.split(".")[:1]) +last_stable = project_data.get("version") +rst_prolog = f""" +.. |last_stable| replace:: :pelican-doc:`{last_stable}` +.. |min_python| replace:: {project_data.get('requires-python').split(",")[0]} +""" + +extlinks = {"pelican-doc": ("https://docs.getpelican.com/en/latest/%s.html", "%s")} # -- Options for HTML output -------------------------------------------------- -html_theme = 'furo' -html_title = f'{project} {release}' -html_static_path = ['_static'] +html_theme = "furo" +html_title = f"{project} {release}" +html_static_path = ["_static"] html_theme_options = { - 'light_logo': 'pelican-logo.svg', - 'dark_logo': 'pelican-logo.svg', - 'navigation_with_keys': True, + "light_logo": "pelican-logo.svg", + "dark_logo": "pelican-logo.svg", + "navigation_with_keys": True, } # Output file base name for HTML help builder. -htmlhelp_basename = 'Pelicandoc' +htmlhelp_basename = "Pelicandoc" html_use_smartypants = True @@ -59,21 +69,29 @@ def setup(app): # overrides for wide tables in RTD theme - app.add_css_file('theme_overrides.css') # path relative to _static + app.add_css_file("theme_overrides.css") # path relative to _static # -- Options for LaTeX output ------------------------------------------------- latex_documents = [ - ('index', 'Pelican.tex', 'Pelican Documentation', 'Justin Mayer', - 'manual'), + ("index", "Pelican.tex", "Pelican Documentation", "Justin Mayer", "manual"), ] # -- Options for manual page output ------------------------------------------- man_pages = [ - ('index', 'pelican', 'pelican documentation', - ['Justin Mayer'], 1), - ('pelican-themes', 'pelican-themes', 'A theme manager for Pelican', - ['Mickaël Raybaud'], 1), - ('themes', 'pelican-theming', 'How to create themes for Pelican', - ['The Pelican contributors'], 1) + ("index", "pelican", "pelican documentation", ["Justin Mayer"], 1), + ( + "pelican-themes", + "pelican-themes", + "A theme manager for Pelican", + ["Mickaël Raybaud"], + 1, + ), + ( + "themes", + "pelican-theming", + "How to create themes for Pelican", + ["The Pelican contributors"], + 1, + ), ] diff --git a/docs/contribute.rst b/docs/contribute.rst index cfbfe351e5..33a62064e9 100644 --- a/docs/contribute.rst +++ b/docs/contribute.rst @@ -15,16 +15,16 @@ Setting up the development environment ====================================== While there are many ways to set up one's development environment, the following -instructions will utilize Pip_ and Poetry_. These tools facilitate managing +instructions will utilize Pip_ and PDM_. These tools facilitate managing virtual environments for separate Python projects that are isolated from one another, so you can use different packages (and package versions) for each. -Please note that Python 3.7+ is required for Pelican development. +Please note that Python |min_python| is required for Pelican development. -*(Optional)* If you prefer to `install Poetry `_ once for use with multiple projects, +*(Optional)* If you prefer to `install PDM `_ once for use with multiple projects, you can install it via:: - curl -sSL https://install.python-poetry.org | python3 - + curl -sSL https://pdm.fming.dev/install-pdm.py | python3 - Point your web browser to the `Pelican repository`_ and tap the **Fork** button at top-right. Then clone the source for your fork and add the upstream project @@ -35,7 +35,7 @@ as a Git remote:: cd ~/projects/pelican git remote add upstream https://github.com/getpelican/pelican.git -While Poetry can dynamically create and manage virtual environments, we're going +While PDM can dynamically create and manage virtual environments, we're going to manually create and activate a virtual environment:: mkdir ~/virtualenvs && cd ~/virtualenvs @@ -51,7 +51,7 @@ Install the needed dependencies and set up the project:: Your local environment should now be ready to go! .. _Pip: https://pip.pypa.io/ -.. _Poetry: https://python-poetry.org/ +.. _PDM: https://pdm.fming.dev/latest/ .. _Pelican repository: https://github.com/getpelican/pelican Development diff --git a/docs/install.rst b/docs/install.rst index ea47311f80..aa3c92d089 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -1,7 +1,7 @@ Installing Pelican ################## -Pelican currently runs best on 3.7+; earlier versions of Python are not supported. +Pelican currently runs best on |min_python|; earlier versions of Python are not supported. You can install Pelican via several different methods. The simplest is via Pip_:: diff --git a/docs/quickstart.rst b/docs/quickstart.rst index f1198b947b..686b822f07 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -8,7 +8,7 @@ Installation ------------ Install Pelican (and optionally Markdown if you intend to use it) on Python -3.7+ by running the following command in your preferred terminal, prefixing +|min_python| by running the following command in your preferred terminal, prefixing with ``sudo`` if permissions warrant:: python -m pip install "pelican[markdown]" diff --git a/pelican/tests/build_test/conftest.py b/pelican/tests/build_test/conftest.py new file mode 100644 index 0000000000..548f797046 --- /dev/null +++ b/pelican/tests/build_test/conftest.py @@ -0,0 +1,7 @@ +def pytest_addoption(parser): + parser.addoption( + "--check-wheel", + action="store", + default=False, + help="Check wheel contents.", + ) diff --git a/pelican/tests/build_test/test_wheel.py b/pelican/tests/build_test/test_wheel.py new file mode 100644 index 0000000000..a46354818d --- /dev/null +++ b/pelican/tests/build_test/test_wheel.py @@ -0,0 +1,28 @@ +from pathlib import Path +import pytest +from zipfile import ZipFile + + +@pytest.mark.skipif( + "not config.getoption('--check-wheel')", + reason="Only run when --check-wheel is given", +) +def test_wheel_contents(pytestconfig): + """ + This test, should test the contents of the wheel to make sure, + that everything that is needed is included in the final build + """ + wheel_file = pytestconfig.getoption("--check-wheel") + assert wheel_file.endswith(".whl") + files_list = ZipFile(wheel_file).namelist() + ## Check is theme files are copiedto wheel + simple_theme = Path("./pelican/themes/simple/templates") + for x in simple_theme.iterdir(): + assert str(x) in files_list + + ## Check is tool templatesare copiedto wheel + tools = Path("./pelican/tools/templates") + for x in tools.iterdir(): + assert str(x) in files_list + + assert "pelican/tools/templates/tasks.py.jinja2" in files_list diff --git a/pyproject.toml b/pyproject.toml index 02d1160eac..ac4a73dfbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,21 +1,24 @@ -[tool.poetry] +[project] name = "pelican" -version = "4.8.0" +authors = [{ name = "Justin Mayer", email = "authors@getpelican.com" }] description = "Static site generator supporting Markdown and reStructuredText" -authors = ["Justin Mayer "] -license = "AGPLv3" +version = "4.8.0" +license = { text = "AGPLv3" } readme = "README.rst" keywords = ["static site generator", "static sites", "ssg"] - -homepage = "https://getpelican.com" -repository = "https://github.com/getpelican/pelican" -documentation = "https://docs.getpelican.com" - classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Framework :: Pelican", + "Intended Audience :: End Users/Desktop", + "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", "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", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Content Management System", "Topic :: Internet :: WWW/HTTP :: Site Management", @@ -24,52 +27,31 @@ classifiers = [ "Topic :: Text Processing :: Markup :: HTML", "Topic :: Text Processing :: Markup :: reStructuredText", ] +requires-python = ">=3.8.1,<4.0" +dependencies = [ + "blinker>=1.4", + "docutils>=0.16", + "feedgenerator>=1.9", + "jinja2>=2.7", + "pygments>=2.6", + "python-dateutil>=2.8", + "rich>=10.1", + "unidecode>=1.1", + "backports-zoneinfo<1.0.0,>=0.2.1;python_version<'3.9'", + "watchfiles>=0.21.0", +] -[tool.poetry.urls] -"Funding" = "https://donate.getpelican.com/" -"Tracker" = "https://github.com/getpelican/pelican/issues" - -[tool.poetry.dependencies] -python = ">=3.7,<4.0" -blinker = ">=1.4" -docutils = ">=0.16" -feedgenerator = ">=1.9" -jinja2 = ">=2.7" -pygments = ">=2.6" -python-dateutil = ">=2.8" -rich = ">=10.1" -unidecode = ">=1.1" -markdown = {version = ">=3.1", optional = true} -backports-zoneinfo = {version = "^0.2.1", python = "<3.9"} -watchfiles = "^0.19.0" - -[tool.poetry.dev-dependencies] -BeautifulSoup4 = "^4.9" -jinja2 = "~3.1.2" -lxml = "^4.3" -markdown = "~3.4.3" -typogrify = "^2.0" -sphinx = "^5.1" -furo = "2023.03.27" -livereload = "^2.6" -psutil = {version = "^5.7", optional = true} -pygments = "~2.15" -pytest = "^7.1" -pytest-cov = "^4.0" -pytest-sugar = "^0.9.5" -pytest-xdist = "^2.0" -ruff = "^0.1.3" -tox = {version = "^3.13", optional = true} -flake8 = "^3.8" -flake8-import-order = "^0.18.1" -invoke = "^2.0" -isort = "^5.2" -black = {version = "^19.10b0", allow-prereleases = true} +[project.optional-dependencies] +markdown = ["markdown>=3.1"] -[tool.poetry.extras] -markdown = ["markdown"] +[project.urls] +Homepage = "https://getpelican.com" +Funding = "https://donate.getpelican.com/" +"Issue Tracker" = "https://github.com/getpelican/pelican/issues" +Repository = "https://github.com/getpelican/pelican" +Documentation = "https://docs.getpelican.com" -[tool.poetry.scripts] +[project.scripts] pelican = "pelican.__main__:main" pelican-import = "pelican.tools.pelican_import:main" pelican-plugins = "pelican.plugins._utils:list_plugins" @@ -83,8 +65,41 @@ git-email = "52496925+botpub@users.noreply.github.com" changelog-file = "docs/changelog.rst" changelog-header = "###############" version-header = "=" -version-strings = ["setup.py"] -build-system = "setuptools" + +[tool.pdm] + +[tool.pdm.scripts] +docbuild = "invoke docbuild" +docserve = "invoke docserve" +lint = "invoke lint" +test = "invoke tests" + +[tool.pdm.dev-dependencies] +dev = [ + "BeautifulSoup4<5.0,>=4.9", + "jinja2~=3.1.2", + "lxml<5.0,>=4.3", + "markdown~=3.4.3", + "typogrify<3.0,>=2.0", + "sphinx<6.0,>=5.1", + "furo==2023.03.27", + "livereload<3.0,>=2.6", + "psutil<6.0,>=5.7", + "pygments~=2.15", + "pytest<8.0,>=7.1", + "pytest-cov<5.0,>=4.0", + "pytest-sugar<1.0.0,>=0.9.5", + "pytest-xdist<3.0,>=2.0", + "tox<4.0,>=3.13", + "flake8<4.0,>=3.8", + "flake8-import-order<1.0.0,>=0.18.1", + "invoke<3.0,>=2.0", + "isort<6.0,>=5.2", + "black<20.0,>=19.10b0", + "ruff>=0.1.3,<1.0.0", + "tomli;python_version<'3.11'", +] [build-system] -requires = ["setuptools >= 40.6.0", "wheel"] +requires = ["pdm-backend"] +build-backend = "pdm.backend" diff --git a/requirements/docs.pip b/requirements/docs.pip index 6db7c6c8f5..961a64739c 100644 --- a/requirements/docs.pip +++ b/requirements/docs.pip @@ -2,3 +2,4 @@ sphinx<6.0 sphinxext-opengraph furo livereload +tomli;python_version<"3.11" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 2a9acf13da..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[bdist_wheel] -universal = 1 diff --git a/setup.py b/setup.py deleted file mode 100755 index 4ffee0cb84..0000000000 --- a/setup.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -from os import walk -from os.path import join, relpath - -from setuptools import find_packages, setup - - -version = "4.8.0" - -requires = [ - 'feedgenerator >= 1.9', - 'jinja2 >= 2.7', - 'pygments', - 'docutils>=0.15', - 'blinker', - 'unidecode', - 'python-dateutil', - 'rich', - 'backports-zoneinfo[tzdata] >= 0.2; python_version<"3.9"', - 'watchfiles' -] - -entry_points = { - 'console_scripts': [ - 'pelican = pelican.__main__:main', - 'pelican-import = pelican.tools.pelican_import:main', - 'pelican-quickstart = pelican.tools.pelican_quickstart:main', - 'pelican-themes = pelican.tools.pelican_themes:main', - 'pelican-plugins = pelican.plugins._utils:list_plugins' - ] -} - -README = open('README.rst', encoding='utf-8').read() -CHANGELOG = open('docs/changelog.rst', encoding='utf-8').read() - -# Relative links in the README must be converted to absolute URL's -# so that they render correctly on PyPI. -README = README.replace( - "", - "", -) - -description = '\n'.join([README, CHANGELOG]) - -setup( - name='pelican', - version=version, - url='https://getpelican.com/', - author='Justin Mayer', - author_email='authors@getpelican.com', - description="Static site generator supporting reStructuredText and " - "Markdown source content.", - project_urls={ - 'Documentation': 'https://docs.getpelican.com/', - 'Funding': 'https://donate.getpelican.com/', - 'Source': 'https://github.com/getpelican/pelican', - 'Tracker': 'https://github.com/getpelican/pelican/issues', - }, - keywords='static web site generator SSG reStructuredText Markdown', - license='AGPLv3', - long_description=description, - long_description_content_type='text/x-rst', - packages=find_packages(), - include_package_data=True, # includes all in MANIFEST.in if in package - # NOTE : This will collect any files that happen to be in the themes - # directory, even though they may not be checked into version control. - package_data={ # pelican/themes is not a package, so include manually - 'pelican': [relpath(join(root, name), 'pelican') - for root, _, names in walk(join('pelican', 'themes')) - for name in names], - }, - install_requires=requires, - extras_require={ - 'Markdown': ['markdown~=3.1.1'] - }, - entry_points=entry_points, - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Framework :: Pelican', - 'License :: OSI Approved :: GNU Affero General Public License v3', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.7', - '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', - 'Programming Language :: Python :: Implementation :: CPython', - 'Topic :: Internet :: WWW/HTTP', - 'Topic :: Software Development :: Libraries :: Python Modules', - ], - test_suite='pelican.tests', -) diff --git a/tasks.py b/tasks.py index e9f65db3cd..564616799d 100644 --- a/tasks.py +++ b/tasks.py @@ -15,8 +15,8 @@ VENV = str(VENV_PATH.expanduser()) VENV_BIN = Path(VENV) / Path(BIN_DIR) -TOOLS = ["poetry", "pre-commit", "psutil"] -POETRY = which("poetry") or VENV_BIN / "poetry" +TOOLS = ["pdm", "pre-commit", "psutil"] +PDM = which("pdm") or VENV_BIN / "pdm" PRECOMMIT = which("pre-commit") or VENV_BIN / "pre-commit" @@ -107,7 +107,7 @@ def precommit(c): def setup(c): c.run(f"{VENV_BIN}/python -m pip install -U pip", pty=PTY) tools(c) - c.run(f"{POETRY} install", pty=PTY) + c.run(f"{PDM} install", pty=PTY) precommit(c)