Skip to content

Commit fb7e7ac

Browse files
author
shlomi_h
committed
python package template
0 parents  commit fb7e7ac

30 files changed

+1304
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Revision History
2+
3+
## 0.0.0 (YYYY/MM/DD)
4+
5+
- TBD

CONTRIBUTING.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# For Contributors
2+
3+
## Setup
4+
5+
### Requirements
6+
7+
* Make:
8+
* Windows: http://mingw.org/download/installer
9+
* Mac: http://developer.apple.com/xcode
10+
* Linux: http://www.gnu.org/software/make
11+
* pipenv: http://docs.pipenv.org
12+
* Graphviz: http://www.graphviz.org/Download.php
13+
14+
To confirm these system dependencies are configured correctly:
15+
16+
```sh
17+
$ make doctor
18+
```
19+
20+
### Installation
21+
22+
Install project dependencies into a virtual environment:
23+
24+
```sh
25+
$ make install
26+
```
27+
28+
## Development Tasks
29+
30+
### Testing
31+
32+
Manually run the tests:
33+
34+
```sh
35+
$ make test
36+
```
37+
38+
or keep them running on change:
39+
40+
```sh
41+
$ make watch
42+
```
43+
44+
> In order to have OS X notifications, `brew install terminal-notifier`.
45+
46+
### Documentation
47+
48+
Build the documentation:
49+
50+
```sh
51+
$ make docs
52+
```
53+
54+
### Static Analysis
55+
56+
Run linters and static analyzers:
57+
58+
```sh
59+
$ make pylint
60+
$ make pycodestyle
61+
$ make pydocstyle
62+
$ make check # includes all checks
63+
```
64+
65+
## Continuous Integration
66+
67+
The CI server will report overall build status:
68+
69+
```sh
70+
$ make ci
71+
```
72+
73+
## Release Tasks
74+
75+
Release to PyPI:
76+
77+
```sh
78+
$ make upload
79+
```

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
**The MIT License (MIT)**
2+
3+
Copyright © 2018, Shlomi Hod
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include *.rst *.txt *.md
2+
recursive-include docs *.rst *.txt *.md
3+
graft */files
4+
graft */*/files

Makefile

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# Project settings
2+
PROJECT := ethically
3+
PACKAGE := ethically
4+
REPOSITORY := shlomihod/ethically
5+
6+
# Project paths
7+
PACKAGES := $(PACKAGE) tests
8+
CONFIG := $(wildcard *.py)
9+
MODULES := $(wildcard $(PACKAGE)/*.py)
10+
11+
# Virtual environment paths
12+
export PIPENV_VENV_IN_PROJECT=true
13+
export PIPENV_IGNORE_VIRTUALENVS=true
14+
VENV := .venv
15+
16+
# MAIN TASKS ##################################################################
17+
18+
SNIFFER := pipenv run sniffer
19+
20+
.PHONY: all
21+
all: install
22+
23+
.PHONY: ci
24+
ci: check test ## Run all tasks that determine CI status
25+
26+
.PHONY: watch
27+
watch: install .clean-test ## Continuously run all CI tasks when files chanage
28+
$(SNIFFER)
29+
30+
.PHONY: run ## Start the program
31+
run: install
32+
pipenv run python $(PACKAGE)/__main__.py
33+
34+
# SYSTEM DEPENDENCIES #########################################################
35+
36+
.PHONY: doctor
37+
doctor: ## Confirm system dependencies are available
38+
bin/verchew
39+
40+
# PROJECT DEPENDENCIES ########################################################
41+
42+
DEPENDENCIES = $(VENV)/.pipenv-$(shell bin/checksum Pipfile* setup.py)
43+
44+
.PHONY: install
45+
install: $(DEPENDENCIES)
46+
47+
$(DEPENDENCIES):
48+
pipenv run python setup.py develop
49+
pipenv install --dev
50+
@ touch $@
51+
52+
# CHECKS ######################################################################
53+
54+
ISORT := pipenv run isort
55+
PYLINT := pipenv run pylint
56+
PYCODESTYLE := pipenv run pycodestyle
57+
PYDOCSTYLE := pipenv run pydocstyle
58+
59+
.PHONY: check
60+
check: isort pylint pycodestyle pydocstyle ## Run linters and static analysis
61+
62+
.PHONY: isort
63+
isort: install
64+
$(ISORT) $(PACKAGES) $(CONFIG) --recursive --apply
65+
66+
.PHONY: pylint
67+
pylint: install
68+
$(PYLINT) $(PACKAGES) $(CONFIG) --rcfile=.pylint.ini
69+
70+
.PHONY: pycodestyle
71+
pycodestyle: install
72+
$(PYCODESTYLE) $(PACKAGES) $(CONFIG) --config=.pycodestyle.ini
73+
74+
.PHONY: pydocstyle
75+
pydocstyle: install
76+
$(PYDOCSTYLE) $(PACKAGES) $(CONFIG)
77+
78+
# TESTS #######################################################################
79+
80+
PYTEST := pipenv run py.test
81+
COVERAGE := pipenv run coverage
82+
COVERAGE_SPACE := pipenv run coverage.space
83+
84+
RANDOM_SEED ?= $(shell date +%s)
85+
FAILURES := .cache/v/cache/lastfailed
86+
87+
PYTEST_OPTIONS := --random --random-seed=$(RANDOM_SEED)
88+
ifdef DISABLE_COVERAGE
89+
PYTEST_OPTIONS += --no-cov --disable-warnings
90+
endif
91+
PYTEST_RERUN_OPTIONS := --last-failed --exitfirst
92+
93+
.PHONY: test
94+
test: test-all ## Run unit and integration tests
95+
96+
.PHONY: test-unit
97+
test-unit: install
98+
@ ( mv $(FAILURES) $(FAILURES).bak || true ) > /dev/null 2>&1
99+
$(PYTEST) $(PACKAGE) $(PYTEST_OPTIONS)
100+
@ ( mv $(FAILURES).bak $(FAILURES) || true ) > /dev/null 2>&1
101+
$(COVERAGE_SPACE) $(REPOSITORY) unit
102+
103+
.PHONY: test-int
104+
test-int: install
105+
@ if test -e $(FAILURES); then $(PYTEST) tests $(PYTEST_RERUN_OPTIONS); fi
106+
@ rm -rf $(FAILURES)
107+
$(PYTEST) tests $(PYTEST_OPTIONS)
108+
$(COVERAGE_SPACE) $(REPOSITORY) integration
109+
110+
.PHONY: test-all
111+
test-all: install
112+
@ if test -e $(FAILURES); then $(PYTEST) $(PACKAGES) $(PYTEST_RERUN_OPTIONS); fi
113+
@ rm -rf $(FAILURES)
114+
$(PYTEST) $(PACKAGES) $(PYTEST_OPTIONS)
115+
$(COVERAGE_SPACE) $(REPOSITORY) overall
116+
117+
.PHONY: read-coverage
118+
read-coverage:
119+
bin/open htmlcov/index.html
120+
121+
# DOCUMENTATION ###############################################################
122+
123+
PYREVERSE := pipenv run pyreverse
124+
MKDOCS := pipenv run mkdocs
125+
126+
MKDOCS_INDEX := site/index.html
127+
128+
.PHONY: docs
129+
docs: uml mkdocs ## Generate documentation
130+
131+
.PHONY: uml
132+
uml: install docs/*.png
133+
docs/*.png: $(MODULES)
134+
$(PYREVERSE) $(PACKAGE) -p $(PACKAGE) -a 1 -f ALL -o png --ignore tests
135+
- mv -f classes_$(PACKAGE).png docs/classes.png
136+
- mv -f packages_$(PACKAGE).png docs/packages.png
137+
138+
.PHONY: mkdocs
139+
mkdocs: install $(MKDOCS_INDEX)
140+
$(MKDOCS_INDEX): mkdocs.yml docs/*.md
141+
ln -sf `realpath README.md --relative-to=docs` docs/index.md
142+
ln -sf `realpath CHANGELOG.md --relative-to=docs/about` docs/about/changelog.md
143+
ln -sf `realpath CONTRIBUTING.md --relative-to=docs/about` docs/about/contributing.md
144+
ln -sf `realpath LICENSE.md --relative-to=docs/about` docs/about/license.md
145+
$(MKDOCS) build --clean --strict
146+
147+
.PHONY: mkdocs-live
148+
mkdocs-live: mkdocs
149+
eval "sleep 3; bin/open http://127.0.0.1:8000" &
150+
$(MKDOCS) serve
151+
152+
# BUILD #######################################################################
153+
154+
PYINSTALLER := pipenv run pyinstaller
155+
PYINSTALLER_MAKESPEC := pipenv run pyi-makespec
156+
157+
DIST_FILES := dist/*.tar.gz dist/*.whl
158+
EXE_FILES := dist/$(PROJECT).*
159+
160+
.PHONY: build
161+
build: dist
162+
163+
.PHONY: dist
164+
dist: install $(DIST_FILES)
165+
$(DIST_FILES): $(MODULES)
166+
rm -f $(DIST_FILES)
167+
pipenv run python setup.py check --strict --metadata
168+
pipenv run python setup.py sdist
169+
pipenv run python setup.py bdist_wheel
170+
171+
.PHONY: exe
172+
exe: install $(EXE_FILES)
173+
$(EXE_FILES): $(MODULES) $(PROJECT).spec
174+
# For framework/shared support: https://github.com/yyuu/pyenv/wiki
175+
$(PYINSTALLER) $(PROJECT).spec --noconfirm --clean
176+
177+
$(PROJECT).spec:
178+
$(PYINSTALLER_MAKESPEC) $(PACKAGE)/__main__.py --onefile --windowed --name=$(PROJECT)
179+
180+
# RELEASE #####################################################################
181+
182+
TWINE := pipenv run twine
183+
184+
.PHONY: upload
185+
upload: dist ## Upload the current version to PyPI
186+
git diff --name-only --exit-code
187+
$(TWINE) upload dist/*.*
188+
bin/open https://pypi.org/project/$(PROJECT)
189+
190+
# CLEANUP #####################################################################
191+
192+
.PHONY: clean
193+
clean: .clean-build .clean-docs .clean-test .clean-install ## Delete all generated and temporary files
194+
195+
.PHONY: clean-all
196+
clean-all: clean
197+
rm -rf $(VENV)
198+
199+
.PHONY: .clean-install
200+
.clean-install:
201+
find $(PACKAGES) -name '*.pyc' -delete
202+
find $(PACKAGES) -name '__pycache__' -delete
203+
rm -rf *.egg-info
204+
205+
.PHONY: .clean-test
206+
.clean-test:
207+
rm -rf .cache .pytest .coverage htmlcov xmlreport
208+
209+
.PHONY: .clean-docs
210+
.clean-docs:
211+
rm -rf *.rst docs/apidocs *.html docs/*.png site
212+
213+
.PHONY: .clean-build
214+
.clean-build:
215+
rm -rf *.spec dist build
216+
217+
# HELP ########################################################################
218+
219+
.PHONY: help
220+
help: all
221+
@ grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
222+
223+
.DEFAULT_GOAL := help

Pipfile

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[[source]]
2+
3+
url = "https://pypi.org/simple"
4+
verify_ssl = true
5+
name = "pypi"
6+
7+
[requires]
8+
9+
python_version = "3.6"
10+
11+
[dev-packages]
12+
13+
# Linters
14+
isort = "*"
15+
pylint = "*"
16+
pycodestyle = "*"
17+
pydocstyle = "*"
18+
19+
# Testing
20+
pytest = "~= 3.3"
21+
pytest-describe = "*"
22+
pytest-expecter = "*"
23+
pytest-random = "*"
24+
pytest-cov = "*"
25+
freezegun = "*"
26+
27+
# Reports
28+
coverage-space = "*"
29+
30+
# Documentation
31+
mkdocs = "*"
32+
docutils = "*"
33+
pygments = "*"
34+
35+
# Build
36+
wheel = "*"
37+
pyinstaller = "*"
38+
39+
# Release
40+
setuptools = ">= 38.6.0"
41+
twine = ">= 1.11.0"
42+
43+
# Tooling
44+
sniffer = "*"
45+
MacFSEvents = { version = "*", sys_platform = "== 'darwin'" }
46+
pync = { version = "*", sys_platform = "== 'darwin'" }

0 commit comments

Comments
 (0)