Skip to content

Commit 5216f88

Browse files
committed
chore: Template upgrade
1 parent de2ef32 commit 5216f88

13 files changed

Lines changed: 678 additions & 285 deletions

.copier-answers.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Changes here will be overwritten by Copier
2-
_commit: 309bc30
2+
_commit: 4aa16ef
33
_src_path: gh:pawamoy/copier-poetry
44
author_email: pawamoy@pm.me
55
author_fullname: "Timoth\xE9e Mazzucotelli"

.coverage.corsair.2191500.610956

-52 KB
Binary file not shown.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ pip-wheel-metadata/
1212
.python-version
1313
site/
1414
poetry.lock
15-
.mypy_cache
15+
.mypy_cache/
16+
.venv/

CHANGELOG.md

Lines changed: 60 additions & 60 deletions
Large diffs are not rendered by default.

Makefile

Lines changed: 31 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,37 @@
11
.DEFAULT_GOAL := help
2+
SHELL := bash
3+
4+
INVOKE_OR_POETRY = $(shell ! command -v invoke &>/dev/null && echo poetry run) invoke
5+
INVOKE_AND_POETRY = $(shell [ ! -n "${VIRTUAL_ENV}" ] && echo poetry run) invoke
6+
7+
POETRY_TASKS = \
8+
changelog \
9+
check \
10+
check-code-quality \
11+
check-dependencies \
12+
check-docs \
13+
check-types \
14+
combine \
15+
coverage \
16+
docs \
17+
docs-deploy \
18+
docs-regen \
19+
docs-serve \
20+
format \
21+
release \
22+
test
23+
24+
INVOKE_TASKS = \
25+
clean \
26+
setup
227

3-
PY_SRC := src/ tests/ scripts/
4-
CI ?= false
5-
TESTING ?= false
6-
7-
.PHONY: changelog
8-
changelog: ## Update the changelog in-place with latest commits.
9-
@poetry run failprint -t "Updating changelog" -- python scripts/update_changelog.py \
10-
CHANGELOG.md "<!-- insertion marker -->" "^## \[(?P<version>[^\]]+)"
11-
12-
.PHONY: check
13-
check: check-docs check-code-quality check-types check-dependencies ## Check it all!
14-
15-
.PHONY: check-code-quality
16-
check-code-quality: ## Check the code quality.
17-
@poetry run failprint -t "Checking code quality" -- flake8 --config=config/flake8.ini $(PY_SRC)
18-
19-
.PHONY: check-dependencies
20-
check-dependencies: ## Check for vulnerabilities in dependencies.
21-
@SAFETY=safety; \
22-
if ! $(CI); then \
23-
if ! command -v $$SAFETY &>/dev/null; then \
24-
SAFETY="pipx run safety"; \
25-
fi; \
26-
fi; \
27-
poetry export -f requirements.txt --without-hashes | \
28-
poetry run failprint --no-pty -t "Checking dependencies" -- $$SAFETY check --stdin --full-report
29-
30-
.PHONY: check-docs
31-
check-docs: ## Check if the documentation builds correctly.
32-
@poetry run failprint -t "Building documentation" -- mkdocs build -s
33-
34-
.PHONY: check-types
35-
check-types: ## Check that the code is correctly typed.
36-
@poetry run failprint -t "Type-checking" -- mypy --config-file config/mypy.ini $(PY_SRC)
37-
38-
.PHONY: clean
39-
clean: ## Delete temporary files.
40-
@rm -rf build 2>/dev/null
41-
@rm -rf .coverage* 2>/dev/null
42-
@rm -rf dist 2>/dev/null
43-
@rm -rf .mypy_cache 2>/dev/null
44-
@rm -rf pip-wheel-metadata 2>/dev/null
45-
@rm -rf .pytest_cache 2>/dev/null
46-
@rm -rf src/*.egg-info 2>/dev/null
47-
@rm -rf src/mkdocstrings/__pycache__ 2>/dev/null
48-
@rm -rf scripts/__pycache__ 2>/dev/null
49-
@rm -rf site 2>/dev/null
50-
@rm -rf tests/__pycache__ 2>/dev/null
51-
@find . -name "*.rej" -delete 2>/dev/null
52-
53-
.PHONY: docs
54-
docs: docs-regen ## Build the documentation locally.
55-
@poetry run mkdocs build
56-
57-
.PHONY: docs-regen
58-
docs-regen: ## Regenerate some documentation pages.
59-
@poetry run python scripts/regen_docs.py
60-
61-
.PHONY: docs-serve
62-
docs-serve: docs-regen ## Serve the documentation (localhost:8000).
63-
@poetry run mkdocs serve
64-
65-
.PHONY: docs-deploy
66-
docs-deploy: docs-regen ## Deploy the documentation on GitHub pages.
67-
@poetry run mkdocs gh-deploy
6828

6929
.PHONY: help
70-
help: ## Print this help.
71-
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort
72-
73-
.PHONY: format
74-
format: ## Run formatting tools on the code.
75-
@poetry run failprint -t "Formatting code" -- black $(PY_SRC)
76-
@poetry run failprint -t "Ordering imports" -- isort -y -rc $(PY_SRC)
77-
78-
.PHONY: release
79-
release: ## Create a new release (commit, tag, push, build, publish, deploy docs).
80-
ifndef v
81-
$(error Pass the new version with 'make release v=0.0.0')
82-
endif
83-
@poetry run failprint -t "Bumping version" -- poetry version $(v)
84-
@poetry run failprint -t "Staging files" -- git add pyproject.toml CHANGELOG.md
85-
@poetry run failprint -t "Committing changes" -- git commit -m "chore: Prepare release $(v)"
86-
@poetry run failprint -t "Tagging commit" -- git tag v$(v)
87-
@poetry run failprint -t "Building dist/wheel" -- poetry build
88-
-@if ! $(CI) && ! $(TESTING); then \
89-
poetry run failprint -t "Pushing commits" -- git push; \
90-
poetry run failprint -t "Pushing tags" -- git push --tags; \
91-
poetry run failprint -t "Publishing version" -- poetry publish; \
92-
poetry run failprint -t "Deploying docs" -- poetry run mkdocs gh-deploy; \
93-
fi
30+
help:
31+
@$(INVOKE) --list
9432

95-
.PHONY: setup
96-
setup: ## Setup the development environment (install dependencies).
97-
@if ! $(CI); then \
98-
if ! command -v poetry &>/dev/null; then \
99-
if ! command -v pipx &>/dev/null; then \
100-
pip install --user pipx; \
101-
fi; \
102-
pipx install poetry; \
103-
fi; \
104-
fi; \
105-
poetry install -v
33+
$(POETRY_TASKS):
34+
@$(INVOKE_AND_POETRY) $@ $(args)
10635

107-
.PHONY: test
108-
test: ## Run the test suite and report coverage.
109-
@poetry run pytest -c config/pytest.ini -n auto -k "$(K)" 2>/dev/null
110-
-@poetry run coverage html --rcfile=config/coverage.ini
36+
$(INVOKE_TASKS):
37+
@$(INVOKE_OR_POETRY) $@ $(args)

config/pytest.ini

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,3 @@ python_files =
99
test_*.py
1010
*_test.py
1111
tests.py
12-
addopts =
13-
--cov
14-
--cov-config config/coverage.ini

pyproject.toml

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,50 @@ mkdocs = "^1.1"
2525
pymdown-extensions = ">=6.3, <9.0"
2626
pytkdocs = ">=0.2.0, <0.8.0"
2727

28+
coverage = { version = "^5.0.4", optional = true }
29+
invoke = { version = "^1.4.1", optional = true }
30+
mypy = { version = "^0.770", optional = true }
31+
pytest = { version = "^4.3", optional = true }
32+
pytest-randomly = { version = "^3.4.1", optional = true }
33+
pytest-sugar = { version = "^0.9.2", optional = true }
34+
pytest-xdist = { version = "^1.26", optional = true }
35+
36+
[tool.poetry.extras]
37+
tests = ["coverage", "invoke", "mypy", "pytest", "pytest-randomly", "pytest-sugar", "pytest-xdist"]
38+
2839
[tool.poetry.dev-dependencies]
29-
bandit = "^1.5"
30-
black = "^19.10b0"
40+
autoflake = "^1.3.1"
41+
black = "^20.8b1"
3142
coverage = "^5.0.4"
3243
failprint = "^0.3.0"
33-
flake8 = "^3.6"
34-
flake8-bandit = "^2.1.2"
35-
flake8-black = "^0.1.1"
36-
flake8-builtins = "^1.5.2"
37-
flake8-comprehensions = "^3.2.2"
38-
flake8-docstrings = "^1.5.0"
39-
flake8-isort = "^3.0.0"
44+
flakehell = "^0.6.0"
45+
flake8-black = "^0.2.1"
46+
flake8-builtins = "^1.5.3"
4047
flake8-tidy-imports = "^4.1.0"
4148
flake8-variables-names = "^0.0.3"
49+
flake8-pytest-style = "^1.3.0"
4250
git-changelog = "^0.4.0"
51+
httpx = "^0.13.3"
52+
invoke = "^1.4.1"
4353
ipython = "^7.2"
4454
isort = { version = "^4.3", extras = ["pyproject"] }
4555
jinja2-cli = "^0.7.0"
4656
mkdocs-material = ">=4.5, <6.0"
4757
mypy = "^0.770"
4858
pytest = "^4.3"
49-
pytest-cov = "^2.8"
59+
pytest-randomly = "^3.4.1"
5060
pytest-sugar = "^0.9.2"
5161
pytest-xdist = "^1.26"
52-
requests = "^2.23.0"
5362
toml = "^0.10.0"
63+
wemake-python-styleguide = "^0.14.1"
64+
wrapt = "^1.12.1"
5465

5566
[tool.poetry.plugins."mkdocs.plugins"]
5667
mkdocstrings = "mkdocstrings.plugin:MkdocstringsPlugin"
5768

5869
[tool.black]
5970
line-length = 120
71+
exclude = "tests/fixtures"
6072

6173
[tool.isort]
6274
line_length = 120
@@ -67,3 +79,39 @@ balanced_wrapping = true
6779
default_section = "THIRDPARTY"
6880
known_first_party = "mkdocstrings"
6981
include_trailing_comma = true
82+
83+
[tool.flakehell]
84+
format = "colored"
85+
max_line_length = 132
86+
show_source = false
87+
exclude = ["tests/fixtures"]
88+
89+
[tool.flakehell.plugins]
90+
"*" = [
91+
"+*",
92+
"-RST*", # we write docstrings in markdown, not rst
93+
"-A001", # redundant with W0622 (builtin override), which is more precise about line number
94+
"-D105", # missing docstring in magic method
95+
"-D212", # multi-line docstring summary should start at the first line
96+
"-E203", # whitespace before ‘:’ (incompatible with Black)
97+
"-Q000", # black already deals with quoting
98+
"-S101", # use of assert
99+
"-W503", # line break before binary operator (incompatible with Black)
100+
"-C0116", # redunant with D102 (missing docstring)
101+
"-C0301", # line too long
102+
"-R0903", # too few public methods
103+
"-R0913", # too many methods
104+
"-R0914", # too many local variables
105+
"-W0611", # redundant with F401 (unused import)
106+
"-WPS305", # f-strings
107+
"-WPS125", # redundant with W0622 (builtin override), which is more precise about line number
108+
"-WPS202", # too many module members
109+
"-WPS210", # too many local variables
110+
"-WPS213", # too many expressions
111+
"-WPS220", # too deep nesting
112+
"-WPS226", # string over-use: can't disable it per file?
113+
"-WPS326", # implicit string concatenation
114+
"-WPS336", # explicit string concatenation
115+
"-WPS412", # __init__ modules with logic
116+
"-WPS433", # redundant with C0415 (not top-level import)
117+
]

scripts/gen_credits_data.py

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,80 @@
1-
#!/usr/bin/env python
21
"""Generate data to render the credits template."""
2+
# noqa: WPS226 ("name" over-use)
33

44
import json
5+
import sys
56
from itertools import chain
67
from pathlib import Path
78

8-
import requests
9+
import httpx
910
import toml
10-
from pip._internal.commands.show import search_packages_info
11+
from pip._internal.commands.show import search_packages_info # noqa: WPS436 (better way?)
1112

1213

13-
def clean_info(package_dict):
14-
"""Only keep `name` and `home-page` keys."""
15-
return {k: v for k, v in package_dict.items() if k in ("name", "home-page")}
14+
def clean_info(package_dict: dict) -> dict:
15+
"""
16+
Only keep `name` and `home-page` keys.
1617
18+
Arguments:
19+
package_dict: Package information.
1720
18-
def get_data():
19-
"""Return data used to generate the credits file."""
20-
metadata = toml.load(Path(__file__).parent.parent / "pyproject.toml")["tool"]["poetry"]
21-
project_name = metadata["name"]
22-
direct_dependencies = sorted(
23-
_.lower() for _ in chain(metadata["dependencies"].keys(), metadata["dev-dependencies"].keys())
24-
)
25-
direct_dependencies.remove("python")
21+
Returns:
22+
Cleaned-up information.
23+
"""
24+
return {_: package_dict[_] for _ in ("name", "home-page")}
2625

27-
lock_data = toml.load(Path(__file__).parent.parent / "poetry.lock")
28-
indirect_dependencies = sorted(p["name"] for p in lock_data["package"] if p["name"] not in direct_dependencies)
2926

30-
package_info = {p["name"]: clean_info(p) for p in search_packages_info(direct_dependencies + indirect_dependencies)}
27+
def get_data() -> dict:
28+
"""
29+
Return data used to generate the credits file.
3130
32-
for dependency in direct_dependencies + indirect_dependencies:
33-
# poetry.lock seems to always use lowercase for packages names
34-
if dependency not in [_.lower() for _ in package_info.keys()]:
35-
info = requests.get(f"https://pypi.python.org/pypi/{dependency}/json").json()["info"]
36-
package_info[info["name"]] = {
37-
"name": info["name"],
38-
"home-page": info["home_page"] or info["project_url"] or info["package_url"],
39-
}
31+
Returns:
32+
Data required to render the credits template.
33+
"""
34+
project_dir = Path(__file__).parent.parent
35+
metadata = toml.load(project_dir / "pyproject.toml")["tool"]["poetry"]
36+
lock_data = toml.load(project_dir / "poetry.lock")
37+
project_name = metadata["name"]
4038

41-
lower_package_info = {}
42-
for package_name, package in package_info.items():
43-
lower = package_name.lower()
44-
if lower != package_name:
45-
lower_package_info[lower] = package
39+
poetry_dependencies = chain(metadata["dependencies"].keys(), metadata["dev-dependencies"].keys())
40+
direct_dependencies = sorted(dep.lower() for dep in poetry_dependencies)
41+
direct_dependencies.remove("python")
4642

47-
package_info.update(lower_package_info)
43+
indirect_dependencies = sorted(
44+
pkg["name"] for pkg in lock_data["package"] if pkg["name"] not in direct_dependencies
45+
)
46+
47+
dependencies = direct_dependencies + indirect_dependencies
48+
packages = {pkg["name"]: clean_info(pkg) for pkg in search_packages_info(dependencies)}
49+
# poetry.lock seems to always use lowercase for packages names
50+
packages.update({name.lower(): pkg for name, pkg in packages.items()}) # noqa: WPS221 (not that complex)
51+
52+
for dependency in dependencies:
53+
if dependency not in packages:
54+
pkg_data = httpx.get(f"https://pypi.python.org/pypi/{dependency}/json").json()["info"]
55+
home_page = pkg_data["home_page"] or pkg_data["project_url"] or pkg_data["package_url"]
56+
pkg_name = pkg_data["name"]
57+
pkg = {"name": pkg_name, "home-page": home_page}
58+
packages.update({pkg_name: pkg, pkg_name.lower(): pkg})
4859

4960
return {
5061
"project_name": project_name,
5162
"direct_dependencies": direct_dependencies,
5263
"indirect_dependencies": indirect_dependencies,
53-
"package_info": package_info,
64+
"package_info": packages,
5465
}
5566

5667

57-
def main():
58-
"""Dump data as JSON."""
59-
print(json.dumps(get_data()))
68+
def main() -> int:
69+
"""
70+
Dump data as JSON.
71+
72+
Returns:
73+
An exit code.
74+
"""
75+
print(json.dumps(get_data())) # noqa: WPS421 (side-effect)
76+
return 0
6077

6178

6279
if __name__ == "__main__":
63-
main()
80+
sys.exit(main())

0 commit comments

Comments
 (0)