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)