From 451c907c69c2bf33aea9c54dd3019d45d3e53096 Mon Sep 17 00:00:00 2001 From: Jeff Dairiki Date: Tue, 6 Sep 2022 18:26:33 -0700 Subject: [PATCH] Documentation updates for Lektor PR lektor/lektor#1065 --- content/docs/plugins/dev/contents.lr | 54 ++++++---- content/docs/plugins/publishing/contents.lr | 113 ++++++++++---------- 2 files changed, 88 insertions(+), 79 deletions(-) diff --git a/content/docs/plugins/dev/contents.lr b/content/docs/plugins/dev/contents.lr index 9b9729b9..cc1df1b2 100644 --- a/content/docs/plugins/dev/contents.lr +++ b/content/docs/plugins/dev/contents.lr @@ -44,31 +44,43 @@ package in the packages folder. Alternatively you can manually create a `packages/hello-world/` folder. -Once that is done, we need to create a `setup.py` file which tells Lektor -what your plugin needs to run. This will already be created for you if -you used the wizard. +Once that is done, we need to create `pyproject.toml` and `setup.cfg` files. +These files tell the python packaging tools what your plugin needs to run +and tell Lektor how to run your plugin. These files will already have been created +for you if you used the `lektor dev new-plugin` wizard. -```python -from setuptools import setup +! Note that these days there are many different tools that can be used to build +distributions (and even more ways to configure those tools.) Since Lektor version 3.4, +you may use any packaging tool that supports PEP-517 and PEP-660. + +`pyproject.toml` +```toml +[build-system] +requires = ["setuptools>=45"] +build-backend = "setuptools.build_meta" +``` + +`setup.cfg` +```ini +[metadata] +name = lektor-hello-world +version = 0.1 + +[options] +py_modules = lektor_hello_world +install_requires = + +[options.entry_points] +lektor.plugins = + hello-world = lektor_hello_world:HelloWorldPlugin -setup( - name='lektor-hello-world', - version='0.1', - py_modules=['lektor_hello_world'], - entry_points={ - 'lektor.plugins': [ - 'hello-world = lektor_hello_world:HelloWorldPlugin', - ] - }, - install_requires=[] -) ``` So going line by line, these are what the things mean: -* `setuptools` is a module that helps us install the package with the - Python interpreter that Lektor uses. We only need the setup function - from it for this example. +* `setuptools` is a package that helps us install the package with the + Python interpreter that Lektor uses. The above `pyproject.toml` declares + that we are using setuptools to build and install our plugin. * `name` is the name of the plugin when it's published to the Python package index where all Lektor plugins go. As such it should be prefixed with `lektor-` to make it not clash with other packages on the index. @@ -76,13 +88,13 @@ So going line by line, these are what the things mean: matter what you write here, but it will play a role once you start publishing your packages. Users need to reference exact versions of these plugins when using them. -* `py_modules`: this is a list of modules that your plugin needs to run. +* `py_modules`: this is a list of modules that are part of your plugin's _distribution_. This should always be exactly one module named `lektor_XXX` where `XXX` is your plugin name with underscores instead of dashes as separators. If you need more than one module you should use a package instead. This is not covered here, but you can find this in the [setuptools documentation :ext](https://setuptools.pypa.io/en/latest/). -* `entry_points`: this is meta data that is needed to associate our package +* `entry_points`: this is metadata that is needed to associate our package with Lektor. Lektor will load all plugins in the `lektor.plugins` list. It can be a list of definitions in the form `plugin-name = import_path`. The plugin name is what will show up in the plugin list in Lektor, diff --git a/content/docs/plugins/publishing/contents.lr b/content/docs/plugins/publishing/contents.lr index c5703faf..0baaaa84 100644 --- a/content/docs/plugins/publishing/contents.lr +++ b/content/docs/plugins/publishing/contents.lr @@ -8,79 +8,76 @@ body: Once you are happy with a plugin you can publish it so that other people can use it. Publishing of plugins happens through the -[Python Package Index :ext](https://pypi.org/) and can be -automatically done with the help of the lektor shell command. +[Python Package Index :ext](https://pypi.org/). -## Enhance your setup.py + +## Enhance your setup.cfg Before you can go about publishing your plugin there needs to be at least -some information added about it to your `setup.py`. At least the keys -`name`, `version`, `author`, `author_email`, `url` and `description` need to be -set. Here is an example of doing this, largely taken from what is given by -the CLI command `lektor dev new-plugin`: +some information added about it to your `setup.cfg` (or whatever file it is +you use to configure your distributions metadata — other files where metadata +may be declared include `setup.py` and/or `pyproject.toml`). At least the keys +`name`, `version`, `author`, `author_email`, `url` and `description` should to be +set. Here is an example of doing this, largely taken from the `setup.cfg` which +is generated by the +[`lektor dev new-plugin`](https://www.getlektor.com/docs/plugins/dev/#creating-a-package "See: Creating a Package") +sub-command. -```python -import ast -import io -import re +```ini +[metadata] +name = lektor-hello-world +version = 1.0 +description = This is a simple demo Lektor plugin +url = http://github.com/youruser/lektor-yourplugin +author = Your Name +author_email = your.email@example.com +license = MIT +keywords = Lektor plugin static-site blog +long_description = file: README.md +long_description_content_type = text/markdown +classifiers = + Framework :: Lektor + Environment :: Plugins + Environment :: Web Environment + License :: OSI Approved :: MIT License -from setuptools import setup, find_packages +[options] +py_modules = lektor_hello_world -with io.open('README.md', 'rt', encoding="utf8") as f: - readme = f.read() - -_description_re = re.compile(r'description\s+=\s+(?P.*)') - -with open('lektor_hello_world.py', 'rb') as f: - description = str(ast.literal_eval(_description_re.search( - f.read().decode('utf-8')).group(1))) - -setup( - author='Your Name', - author_email='your.email@your.domain.invalid', - description=description, - keywords='Lektor plugin static-site blog', - license='MIT', - long_description=readme, - long_description_content_type='text/markdown', - name='lektor-hello-world', - packages=find_packages(), - py_modules=['lektor_hello_world'], - url='http://github.com/youruser/lektor-yourplugin', - version='1.0', - classifiers=[ - 'Framework :: Lektor', - 'Environment :: Web Environment', - 'Environment :: Plugins', - 'License :: OSI Approved :: MIT License', - ], - entry_points={ - 'lektor.plugins': [ - 'hello-world = lektor_hello_world:HelloWorldPlugin', - ] - } -) +[options.entry_points] +lektor.plugins = + hello-world = lektor_hello_world:HelloWorldPlugin ``` -This is not the most basic `setup.py` that is strictly necessary, but instead a more full, ideal `setup.py` that will help your plugin be discovered and and understood most easily. Note that is assumes there is a `README.md` file, and that `name` and `description` are defined in your plugin's `.py` module file, which is their preferred location for Lektor. +This is not the most basic `setup.cfg` that is strictly necessary, but instead a more full, closer-to-ideal `setup.cfg` that will help your plugin be discovered and understood most easily. Note that it assumes there is a `README.md` file. ## Publishing -Once you augmented your `setup.py` you can go ahead with the publishing. First -you need to make sure you have a PyPI account. If you do not, you can -create one at [pypi.python.org :ext](https://pypi.python.org/pypi?%3Aaction=register_form). +Once you augmented your `setup.cfg` you can go ahead publishing your new plugin to [PyPI :ext](https://pypi.org/ "The Python Package Index"). +Detailed instructions on how to do this may be found in the [Packaging Tutorial :ext](https://packaging.python.org/en/latest/tutorials/packaging-projects/) +(which is part of the [Python Packaging User Guide :ext](https://packaging.python.org/en/latest/)). -Once you have done that, you can publish the plugin from the command line -with the `lektor` command: +The general steps involved are: -``` -$ cd path/to/your/plugin -$ lektor dev publish-plugin -``` +1. Create an account on PyPI (if you do not already have one.) -When you use this for the first time it will prompt you for your login -credentials for `pypi`. Next time it will have remembered them. +2. Install the latest versions of `build` and `twine` into a virtualenv. + ```sh + pip install --upgrade build twine + ``` +3. Build the distribution, the upload it to PyPI + ```sh + cd /path/to/your/plugin + # clean out any old built distribution + rm -r dist + # Build a wheel and sdist (dist/*.whl, dist/*.tar.gz) + python -m build + # Upload your newly built distribution files + python -m twine upload dist/* + ``` + +! Note that the `lektor dev publish-plugin` sub-command has been removed as of Lektor version 3.4. ## Listing on this site