Add a python standalone template & tools

This commit is contained in:
Freezed 2022-04-15 14:35:32 +02:00
parent 7be87997a7
commit 37086a3bed
5 changed files with 211 additions and 0 deletions

33
Makefile Normal file
View File

@ -0,0 +1,33 @@
VBIN=${VIRTUAL_ENV}/bin
help: # Print help on Makefile
@grep '^[^.#]\+:\s\+.*#' Makefile | \
sed "s/\(.\+\):\s*\(.*\) #\s*\(.*\)/`printf "\e[1;33;4;40m"`\1`printf "\033[0m"` \3/" | \
expand -t20
clean: # Remove files not tracked in source control
find . -type f -name "*.orig" -delete
find . -type f -name "*.pyc" -delete
find . -type d -name "__pycache__" -delete
find . -type d -empty -delete
format: # Format the code and lint it
${VBIN}/black *.py
.git/hooks/pre-commit
init-pre_commit: # Set up git pre-commit hook
echo "make --no-print-directory --quiet lint" > .git/hooks/pre-commit && chmod u+x .git/hooks/pre-commit
lint: # Lint code
${VBIN}/black --quiet --check *.py && echo "✅ black" || echo "🚨 black"
${VBIN}/pflake8 --config=pyproject.toml && echo "✅ pflake8" || echo "🚨 pflake8"
${VBIN}/pydocstyle && echo "✅ pydocstyle" || echo "🚨 pydocstyle"
${VBIN}/pylint --rcfile=pyproject.toml *.py && echo "✅ pylint" || echo "🚨 pylint"
open_all: # Open all projects files
${EDITOR} ${VBIN}/activate
${EDITOR} main.py Makefile pyproject.toml README.md requirements-dev.txt requirements.txt
${EDITOR} .git/hooks/p*-commit
pre_commit: # Run the pre-commit hook
bash .git/hooks/pre-commit

View File

@ -3,6 +3,7 @@ Python Boilerplate
Stuff used for a new python project 🐍
💡 Idea
-------
@ -10,6 +11,46 @@ Stuff used for a new python project 🐍
1. Ease new project start
1. Give a try to the _GitLab_ group organisation
🚀 Use quick-start
-----------------
Get the source & edit settings:
```bash
git clone git@<GIT REPO URL>:<GIT REPO PATH>.git && cd <GIT REPO NAME>
cp client.sample.py client.py
${EDITOR} client.py
```
Set up environment & run help:
```bash
mkdir ~/.venvs && python3 -m venv ~/.venvs/<GIT REPO NAME>
source ~/.venvs/<GIT REPO NAME>/bin/activate
pip install -r requirements.txt
./main.py -h
```
🚧 Development
--------------
### 🚀 Quick-start
- Built with `Python 3.8`
- Code linting with [`flake8`](https://pypi.org/project/flake8/), [`pylint`](https://pypi.org/project/pylint), [`black`](https://pypi.org/project/black) & [`pydocstyle`](https://pypi.org/project/pydocstyle/).
- Install development tools:
* `pip install -r requirements-dev.txt`
- A `Makefile` with tools: run `make help` to have a look
- Use the `pre-commit` git hook
* `make init-pre-commit`
### 📌 Dependences
Details in [`requirements.txt`](requirements.txt) & [`requirements-dev.txt`](requirements-dev.txt)
### 🤝 Contributing
- Roadmap ➡️ [_project kanban_](https://gitlab.com/forga/devel/boilerplate/python/-/boards)

127
main.py Executable file
View File

@ -0,0 +1,127 @@
#!/usr/bin/env python3
# coding: utf8
"""<SCRIPT_NAME>.
<SHORT_DESCRIPTION>
Author: {developer} <{mail}> {date}
Licence: GNU AGPL v3: http://www.gnu.org/licenses/
This file is part of [`<GIT REPO NAME>`](<GIT REPO URL>)
"""
import argparse
import sys
from pprint import pprint as pp
class CustomFormatter(
argparse.RawDescriptionHelpFormatter, argparse.ArgumentDefaultsHelpFormatter
):
"""This convert file docstring into help text."""
pass # pylint: disable=W0107
def parse_args(args=sys.argv[1:]): # pylint: disable=W0102
"""Argument parser.
Put values & describe parameters here not in your code
Ease usage with help & docs
"""
parser = argparse.ArgumentParser(
description=sys.modules[__name__].__doc__, formatter_class=CustomFormatter
)
group = parser.add_argument_group("foobar settings")
group.add_argument(
"-d",
"--debug",
action="store_true",
default=False,
help="Log activity in console",
)
group.add_argument(
"-f",
"--foo",
action="store_true",
default=False,
dest="foo",
help="Using foo",
)
group.add_argument(
"-b",
"--bar",
help="Using bar",
metavar="BAR",
nargs="?",
type=str,
)
if len(sys.argv) == 1:
parser.print_help(sys.stderr)
sys.exit(1)
return parser.parse_args(args)
def i_am_bar(option):
"""Print a variable string.
Add some doctests to ensure this is doing what you expects:
:Tests:
>>> i_am_bar("FOOBAR")
'I am FOOBAR'
>>> i_am_bar()
Traceback (most recent call last):
...
TypeError: i_am_bar() missing 1 required positional argument: 'option'
"""
return f"I am {str(option)}"
def i_am_foo():
"""Print a constant string.
Add some doctests to ensure this is doing what you expects:
:Tests:
>>> i_am_foo()
'I am foo'
>>> i_am_foo("FOO")
Traceback (most recent call last):
...
TypeError: i_am_foo() takes 0 positional arguments but 1 was given
"""
return "I am foo"
def main():
"""CLI function, options passed as arguments.
Add some doctests to ensure this is doing what you expects:
:Tests:
>>> var = 1
>>> var + 1
2
"""
pargs = parse_args()
if pargs.foo:
pp(i_am_foo())
elif pargs.bar:
pp(i_am_bar(pargs.bar))
if pargs.debug and pargs:
pp(pargs)
if __name__ == "__main__":
import doctest
doctest.testmod()
sys.exit(main())

5
pyproject.toml Normal file
View File

@ -0,0 +1,5 @@
[tool.flake8]
max-line-length = 90
[tool.pylint.reports]
score = false

5
requirements-dev.txt Normal file
View File

@ -0,0 +1,5 @@
black
pydocstyle
pylint
pyproject-flake8
toml