@@ 1,15 1,9 @@
APP := foobee
-# =============================================================================
-
export LC_ALL := en_US.UTF-8
+export PYTHONIOENCODING := UTF-8:replace
-VIRTUALENV := virtualenv --python=python3
-ECHO := echo
-SED := sed
-FIND := find
-
-.DEFAULT_GOAL := build
+.DEFAULT_GOAL := help
# =============================================================================
# help
@@ 17,7 11,7 @@ FIND := find
.PHONY: help
help:
- @$(ECHO) -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | $(SED) -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)"
+ @echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)"
# =============================================================================
# clean up
@@ 26,7 20,7 @@ help:
.PHONY: clean
clean: ## clean up binary files and other stuff to trigger a fast rebuild
clean:
- $(FIND) src \( -name '*.pyc' -o -name '*.pyo' -o -name '*~' \) -delete
+ find src \( -name '*.pyc' -o -name '*.pyo' -o -name '*~' \) -delete
touch setup.py
touch requirements.txt
rm -f env/_done_*
@@ 34,7 28,6 @@ clean:
.PHONY: distclean
distclean: ## remove everything ever created by this make file
distclean: clean
- rm -f bin
rm -rf env
# =============================================================================
@@ 42,17 35,14 @@ distclean: clean
# =============================================================================
env/bin/python:
- $(VIRTUALENV) env
+ python3 -m venv env
env/_done_requirements: requirements.txt
env/bin/pip install -U -r requirements.txt
touch $@
-bin:
- ln -s env/bin
-
.PHONY: env
-env: env/bin/python bin
+env: env/bin/python
env: env/_done_requirements
# =============================================================================
@@ 62,10 52,18 @@ env: env/_done_requirements
define SETUP
from setuptools import setup, find_packages
+with open(os.path.join(os.path.dirname(__file__), 'README.md')) as fp:
+ longdesc = fp.read()
+
setup(
name="$(APP)",
- version='1',
+ version='0.1', # set automatically by `make release`
+ python_requires='>=3',
+ long_description=longdesc,
+ long_description_content_type='text/markdown',
author='Oben Sonne',
+ author_email='obensonne@gmail.com',
+ url='https://hg.sr.ht/~obensonne/$(APP)',
packages=find_packages('src'),
package_dir={'': 'src'},
install_requires=[],
@@ 78,12 76,19 @@ setup(
endef
export SETUP
+define MANIFEST
+include README.md
+endef
+export MANIFEST
+
define HGIGNORE
syntax: glob
env
.project
.pydevproject
.settings
+.idea
+.pytest_cache
*.egg-info
*.pyc
*.pyo
@@ 91,7 96,6 @@ env
*.swp
__pycache__
SNAPSHOT
-bin
endef
export HGIGNORE
@@ 106,10 110,31 @@ flake8
flake8-commas
flake8-docstrings
isort
-nose
+pytest
+setuptools
+twine
+wheel
endef
export REQUIREMENTS
+define README
+$(APP)
+======
+
+*$(APP) is ...
+
+[![image](https://builds.sr.ht/~obensonne/$(APP).svg?search=0.1)](https://builds.sr.ht/~obensonne/$(APP)?search=0.1)
+
+Changes
+-------
+
+### Version 0.1
+
+- Initial release
+
+endef
+export README
+
define FLAKE8
[flake8]
ignore =
@@ 127,9 152,15 @@ export FLAKE8
setup.py:
@echo "$$SETUP" > $@
+MANIFEST.in:
+ @echo "$$MANIFEST" > $@
+
requirements.txt:
echo "$$REQUIREMENTS" > $@
+README.md:
+ echo "$$README" > $@
+
.flake8:
echo "$$FLAKE8" > $@
@@ 139,17 170,20 @@ src/$(APP):
touch $@/cli.py
mkdir $@/tests
touch $@/tests/__init__.py
- touch $@/tests/cli_tests.py
+ touch $@/tests/test_cli.py
.PHONY: init
-init: | .hgignore requirements.txt setup.py src/$(APP) .hg/hgrc .flake8
+init: | .hgignore requirements.txt README.md setup.py src/$(APP) .hg/hgrc .flake8
.PHONY: initclean
initclean:
rm -f .hgignore
+ rm -f .flake8
rm -rf src
rm -f setup.py
rm -f requirements.txt
+ rm -f MANIFEST.in
+ rm -f README.md
# =============================================================================
# build
@@ 188,10 222,30 @@ style:
# tests
# =============================================================================
-items := $(APP)
-options :=
+.PHONY: test
+test: ## run the test suite
+test: build
+ env/bin/pytest --pyargs $(APP)
+
+# =============================================================================
+# pypi releases
+# =============================================================================
+
+version := unset
-.PHONY: test
-test: ## run the test suite (use items=... to name packages and options=... to control nose)
-test: build
- env/bin/nosetests $(items) $(options)
+release: ## make a release for PyPi
+release: clean test
+ @test -z "$(shell hg status -n)" || { echo 'uncommited changes'; exit 1; }
+ @grep -qPzo '\nChanges\n--+\n\n#+ Version $(version)\n' README.md || { echo 'Changelog in README not updated' ; exit 1; }
+ sed -ri -e "s/version='([0-9.]+)'/version='$(version)'/" setup.py
+ hg commit -m 'Update version in setup.py' setup.py
+ sed -ri -e 's/$(APP)\.svg\?search=([0-9.]+)/$(APP).svg?search=$(version)/' README.md
+ sed -ri -e 's/$(APP)\?search=([0-9.]+)/$(APP)?search=$(version)/' README.md
+ hg commit -m 'Update build status badge' README.md
+ env/bin/python setup.py clean build sdist
+ hg tag $(version)
+ hg phase --public .
+ env/bin/twine check dist/*
+ env/bin/twine upload dist/*
+ hg push -r .
+