|
| 1 | +# Makefile.rules version 1.0 (2017-12-19) |
| 2 | +# |
| 3 | +# Helpful Makefile rules for releasing Python packages. |
| 4 | + |
| 5 | +# You might want to change these |
| 6 | +FILE_WITH_VERSION ?= setup.py |
| 7 | +FILE_WITH_CHANGELOG ?= CHANGES.rst |
| 8 | +CHANGELOG_DATE_FORMAT ?= %Y-%m-%d |
| 9 | +CHANGELOG_FORMAT ?= $(changelog_ver) ($(changelog_date)) |
| 10 | + |
| 11 | +# These should be fine |
| 12 | +PYTHON ?= python |
| 13 | +PYPI_PUBLISH ?= rm -rf dist && $(PYTHON) setup.py -q sdist bdist_wheel && twine upload dist/* && $(VCS_TAG) `$(PYTHON) setup.py --version` |
| 14 | + |
| 15 | +# These should be fine, as long as you use Git |
| 16 | +VCS_GET_LATEST ?= git pull |
| 17 | +VCS_STATUS ?= git status --porcelain |
| 18 | +VCS_EXPORT ?= git archive --format=tar --prefix=tmp/tree/ HEAD | tar -xf - |
| 19 | +VCS_TAG ?= git tag -s |
| 20 | +VCS_COMMIT_AND_PUSH ?= git commit -av -m "Post-release version bump" && git push && git push --tags |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | +.PHONY: dist |
| 25 | +dist: |
| 26 | + $(PYTHON) setup.py -q sdist bdist_wheel |
| 27 | + |
| 28 | +.PHONY: distcheck |
| 29 | +distcheck: distcheck-vcs distcheck-sdist |
| 30 | + |
| 31 | +.PHONY: distcheck-vcs |
| 32 | +distcheck-vcs: |
| 33 | + # Bit of a chicken-and-egg here, but if the tree is unclean, make |
| 34 | + # distcheck-sdist will fail. |
| 35 | +ifndef FORCE |
| 36 | + @test -z "`$(VCS_STATUS) 2>&1`" || { echo; echo "Your working tree is not clean:" 1>&2; $(VCS_STATUS) 1>&2; exit 1; } |
| 37 | +endif |
| 38 | + |
| 39 | +# NB: do not use $(MAKE) because then make -n distcheck will actually run |
| 40 | +# it instead of just printing what it does |
| 41 | + |
| 42 | +# TBH this could (and probably should) be replaced by check-manifest |
| 43 | + |
| 44 | +.PHONY: distcheck-sdist |
| 45 | +distcheck-sdist: |
| 46 | + make dist |
| 47 | + pkg_and_version=`$(PYTHON) setup.py --name`-`$(PYTHON) setup.py --version` && \ |
| 48 | + rm -rf tmp && \ |
| 49 | + mkdir tmp && \ |
| 50 | + $(VCS_EXPORT) && \ |
| 51 | + cd tmp && \ |
| 52 | + tar -xzf ../dist/$$pkg_and_version.tar.gz && \ |
| 53 | + diff -ur $$pkg_and_version tree -x PKG-INFO -x setup.cfg -x '*.egg-info' && \ |
| 54 | + cd $$pkg_and_version && \ |
| 55 | + make dist check && \ |
| 56 | + cd .. && \ |
| 57 | + mkdir one two && \ |
| 58 | + cd one && \ |
| 59 | + tar -xzf ../../dist/$$pkg_and_version.tar.gz && \ |
| 60 | + cd ../two/ && \ |
| 61 | + tar -xzf ../$$pkg_and_version/dist/$$pkg_and_version.tar.gz && \ |
| 62 | + cd .. && \ |
| 63 | + diff -ur one two -x SOURCES.txt && \ |
| 64 | + cd .. && \ |
| 65 | + rm -rf tmp && \ |
| 66 | + echo "sdist seems to be ok" |
| 67 | + |
| 68 | +# NB: do not use $(MAKE) because then make -n releasechecklist will |
| 69 | +# actually run the distcheck instead of just printing what it does |
| 70 | + |
| 71 | +.PHONY: check-latest-version |
| 72 | +check-latest-version: |
| 73 | + $(VCS_GET_LATEST) |
| 74 | + |
| 75 | +.PHONY: check-version-number |
| 76 | +check-version-number: |
| 77 | + @$(PYTHON) setup.py --version | grep -qv dev || { \ |
| 78 | + echo "Please remove the 'dev' suffix from the version number in $(FILE_WITH_VERSION)"; exit 1; } |
| 79 | + |
| 80 | +.PHONY: check-long-description |
| 81 | +check-long-description: |
| 82 | + @$(PYTHON) setup.py --long-description | rst2html --exit-status=2 > /dev/null |
| 83 | + |
| 84 | +changelog_ver = `$(PYTHON) setup.py --version` |
| 85 | +changelog_date = `LC_ALL=C date +'$(CHANGELOG_DATE_FORMAT)'` |
| 86 | + |
| 87 | +.PHONY: check-changelog |
| 88 | +check-changelog: |
| 89 | + @ver_and_date="$(CHANGELOG_FORMAT)" && \ |
| 90 | + grep -q "^$$ver_and_date$$" $(FILE_WITH_CHANGELOG) || { \ |
| 91 | + echo "$(FILE_WITH_CHANGELOG) has no entry for $$ver_and_date"; exit 1; } |
| 92 | + |
| 93 | +.PHONY: releasechecklist |
| 94 | +releasechecklist: check-latest-version check-version-number check-long-description check-changelog |
| 95 | + make distcheck |
| 96 | + |
| 97 | +.PHONY: release |
| 98 | +release: releasechecklist do-release |
| 99 | + |
| 100 | +.PHONY: do-release |
| 101 | +do-release: |
| 102 | + $(release_recipe) |
| 103 | + |
| 104 | +define release_recipe = |
| 105 | + # I'm chicken so I won't actually do these things yet |
| 106 | + @echo "Please run" |
| 107 | + @echo |
| 108 | + @echo " $(PYPI_PUBLISH)" |
| 109 | + @echo |
| 110 | + @echo "Please increment the version number in $(FILE_WITH_VERSION)" |
| 111 | + @echo "and add a new empty entry at the top of the changelog in $(FILE_WITH_CHANGELOG), then" |
| 112 | + @echo |
| 113 | + @echo ' $(VCS_COMMIT_AND_PUSH)' |
| 114 | + @echo |
| 115 | +endef |
0 commit comments