Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions PYPI_README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
.. docs-index-start

.. |pypi-release| image:: https://img.shields.io/pypi/v/cloup.svg
:alt: Latest release on PyPI
:target: https://pypi.org/project/cloup/

.. |tests-status| image:: https://github.com/janLuke/cloup/workflows/Tests/badge.svg
:alt: Tests status
:target: https://github.com/janLuke/cloup/actions?query=workflow%3ATests

.. |coverage| image:: https://codecov.io/github/janLuke/cloup/coverage.svg?branch=master
:alt: Coverage Status
:target: https://app.codecov.io/github/janluke/cloup/tree/master

.. |python-versions| image:: https://img.shields.io/pypi/pyversions/cloup.svg
:alt: Supported versions
:target: https://pypi.org/project/cloup

.. |dev-docs| image:: https://readthedocs.org/projects/cloup/badge/?version=latest
:alt: Documentation Status (master branch)
:target: https://cloup.readthedocs.io/en/latest/

.. |release-docs| image:: https://readthedocs.org/projects/cloup/badge/?version=stable
:alt: Documentation Status (latest release)
:target: https://cloup.readthedocs.io/en/stable/

.. |downloads| image:: https://static.pepy.tech/personalized-badge/cloup?period=week&units=international_system&left_color=grey&right_color=blue&left_text=downloads%20/%20week
:alt: PyPI - Downloads
:target: https://pepy.tech/project/cloup

========
Overview
========
|pypi-release| |downloads| |tests-status| |coverage| |dev-docs|

**Cloup** — originally from "**Cl**\ick + option gr\ **oup**\s" — enriches
`Click <https://github.com/pallets/click>`_ with several features that make it
more expressive and configurable:

- **option groups** and an (optional) help section for positional arguments

- **constraints**, like ``mutually_exclusive``, that can be applied to option groups
or to any group of parameters, even *conditionally*

- **subcommand aliases**

- **subcommands sections**, i.e. the possibility of organizing the subcommands of a
``Group`` in multiple help sections

- a **themeable HelpFormatter** that:

- has more parameters for adjusting widths and spacing, which can be provided
at the context and command level
- use a different layout when the terminal width is below a certain threshold
in order to improve readability

- suggestions like "did you mean <subcommand>?" when you mistype a subcommand.

Moreover, Cloup improves on **IDE support** providing decorators with *detailed*
type hints and adding the static methods ``Context.settings()`` and
``HelpFormatter.settings()`` for creating dictionaries of settings.

Cloup is **statically type-checked** with MyPy in strict mode and extensively **tested**
against multiple versions of Python with nearly 100% coverage.


A simple example
================

.. code-block:: python

from cloup import (
HelpFormatter, HelpTheme, Style,
command, option, option_group
)
from cloup.constraints import RequireAtLeast, mutually_exclusive

# Check the docs for all available arguments of HelpFormatter and HelpTheme.
formatter_settings = HelpFormatter.settings(
theme=HelpTheme(
invoked_command=Style(fg='bright_yellow'),
heading=Style(fg='bright_white', bold=True),
constraint=Style(fg='magenta'),
col1=Style(fg='bright_yellow'),
)
)

# In a multi-command app, you can pass formatter_settings as part
# of your context_settings so that they are propagated to subcommands.
@command(formatter_settings=formatter_settings)
@option_group(
"Cool options",
option('--foo', help='This text should describe the option --foo.'),
option('--bar', help='This text should describe the option --bar.'),
constraint=mutually_exclusive,
)
@option_group(
"Other cool options",
"This is the optional description of this option group.",
option('--pippo', help='This text should describe the option --pippo.'),
option('--pluto', help='This text should describe the option --pluto.'),
constraint=RequireAtLeast(1),
)
def cmd(**kwargs):
"""This is the command description."""
pass

if __name__ == '__main__':
cmd(prog_name='invoked-command')


.. image:: https://raw.githubusercontent.com/janLuke/cloup/master/docs/_static/basic-example.png
:alt: Basic example --help screenshot

If you don't provide ``--pippo`` or ``--pluto``:

.. code-block:: text

Usage: invoked-command [OPTIONS]
Try 'invoked-command --help' for help.

Error: at least 1 of the following parameters must be set:
--pippo
--pluto

This simple example just scratches the surface. Read more in the documentation
(links below).

.. docs-index-end


Links
=====

* Documentation (release_ | development_)
* `Changelog <https://cloup.readthedocs.io/en/stable/pages/changelog.html>`_
* `GitHub repository <https://github.com/janLuke/cloup>`_
* `Q&A and discussions <https://github.com/janLuke/cloup/discussions>`_

.. _release: https://cloup.readthedocs.io/en/stable/#user-guide
.. _development: https://cloup.readthedocs.io/en/latest/#user-guide
74 changes: 74 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[build-system]
requires = ["setuptools>=80", "setuptools-scm>=8"]
build-backend = "setuptools.build_meta"

[tool.setuptools_scm]
version_file = "cloup/_version.py"

[project]
name = "cloup"
dynamic = ["version"]

description = "Adds features to Click: option groups, constraints, subcommand sections and help themes."
readme = { file = "PYPI_README.rst", content-type = "text/x-rst" }
license = { text = "BSD 3-Clause" }

requires-python = ">= 3.9"
authors = [
{ name = "Gianluca Gippetto", email = "[email protected]" },
]

classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Natural Language :: English",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]


dependencies = [
"click>=8.0,<9.0",
]


[dependency-groups]
dev = [
"build",
"flake8",
"flake8-pyproject",
"mypy",
"pytest",
"pytest-cov",
"pytest-html",
"setuptools-scm",
"typing_extensions; python_version <= '3.10'",
"tox<4",
"twine",
]

[tool.flake8]
exclude = "docs"
max-line-length = 90

ignore = [
"E241",
"E251",
"W503",
]

[tool.mypy]
ignore_missing_imports = true


[tool.coverage.report]
exclude_lines = [
"pragma: no covver",
"raise NotImplementedError",
"...",
"if TYPE_CHECKING:",
]
20 changes: 0 additions & 20 deletions setup.cfg

This file was deleted.

52 changes: 0 additions & 52 deletions setup.py

This file was deleted.

5 changes: 4 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[tox]
isolated_build = true
envlist =
lint
mypy
Expand Down Expand Up @@ -35,7 +36,9 @@ commands =

[testenv:lint]
skip_install = true
deps = flake8
deps =
flake8
flake8-pyproject
commands = flake8 cloup tests examples

[testenv:mypy]
Expand Down