diff options
| author | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2020-03-06 16:06:06 +0000 |
|---|---|---|
| committer | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2020-03-06 16:06:06 +0000 |
| commit | c0f546edb5f10a5deea56c23b5e63239a840f657 (patch) | |
| tree | a1d14049cc7e2bc34362ab72a5748e37590db65e | |
| parent | Removing windows builds from travis for now (diff) | |
| parent | Update Makefile to current workflow (diff) | |
| download | pygensvm-c0f546edb5f10a5deea56c23b5e63239a840f657.tar.gz pygensvm-c0f546edb5f10a5deea56c23b5e63239a840f657.zip | |
Merge branch 'master' into packaging
| -rw-r--r-- | Makefile | 56 | ||||
| -rw-r--r-- | make_release.py | 268 |
2 files changed, 293 insertions, 31 deletions
@@ -5,9 +5,10 @@ # http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html PACKAGE=gensvm -DOC_DIR='./docs/' +DOC_DIR=./docs/ +VENV_DIR=/tmp/gensvm_venv -.PHONY: help cover +.PHONY: help cover dist venv .DEFAULT_GOAL := help @@ -24,43 +25,36 @@ install: ## Install for the current user using the default python command python setup.py build_ext --inplace python setup.py install --user -install2: ## Install for the current user using the python2 command - python2 setup.py build_ext --inplace - python2 setup.py install --user +test: venv ## Run nosetests using the default nosetests command + source $(VENV_DIR)/bin/activate && green -a -vv -f -test: in ## Run nosetests using the default nosetests command - green -vvv -f +develop: ## Install a development version of the package needed for testing + python setup.py develop --user -test2: ## Run nosetests using the nosetests2 command - python2 setup.py build_ext -i - nosetests2 -v +dist: ## Make Python source distribution + python setup.py sdist -cover: test ## Test unit test coverage using default nosetests - nosetests --with-coverage --cover-package=$(PACKAGE) \ - --cover-erase --cover-inclusive --cover-branches \ - --cover-html --cover-html-dir=cover +docs: doc +doc: venv ## Build documentation with Sphinx + source $(VENV_DIR)/bin/activate && $(MAKE) -C $(DOC_DIR) html clean: ## Clean build dist and egg directories left after install - rm -rf ./dist ./build ./$(PACKAGE).egg-info - rm -rf gensvm/cython_wrapper/*.so + rm -rf ./dist + rm -rf ./build + rm -rf ./$(PACKAGE).egg-info + rm -rf ./cover + rm -rf $(VENV_DIR) rm -f MANIFEST + rm -f ./$(PACKAGE)/cython_wrapper/*.so $(MAKE) -C ./src/gensvm clean + find . -type f -iname '*.pyc' -delete + find . -type d -name '__pycache__' -empty -delete cleaner: clean rm -f ./src/wrapper.c +venv: $(VENV_DIR)/bin/activate -develop: ## Install a development version of the package needed for testing - python setup.py develop --user - -develop2: ## Install a development version of the package needed for testing (python2) - python2 setup.py develop --user - -dist: ## Make Python source distribution - python setup.py sdist - -dist2: ## Make Python 2 source distribution - python2 setup.py sdist - -docs: doc -doc: ## Build documentation with Sphinx - poetry run $(MAKE) -C $(DOC_DIR) html +$(VENV_DIR)/bin/activate: + test -d $(VENV_DIR) || virtualenv $(VENV_DIR) + source $(VENV_DIR)/bin/activate && pip install -e .[dev] + touch $(VENV_DIR)/bin/activate diff --git a/make_release.py b/make_release.py new file mode 100644 index 0000000..bfb9314 --- /dev/null +++ b/make_release.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Do-nothing script for making a release + +This idea comes from here: +https://blog.danslimmon.com/2019/07/15/do-nothing-scripting-the-key-to-gradual-automation/ + +Author: Gertjan van den Burg +Date: 2019-07-23 + +""" + +import colorama +import os +import webbrowser + +URLS = { + "RTD": "https://readthedocs.org/projects/gensvm/builds/", + "Travis": "https://travis-ci.org/GjjvdBurg/PyGenSVM", +} + + +def colored(msg, color=None, style=None): + colors = { + "red": colorama.Fore.RED, + "green": colorama.Fore.GREEN, + "cyan": colorama.Fore.CYAN, + "yellow": colorama.Fore.YELLOW, + "magenta": colorama.Fore.MAGENTA, + None: "", + } + styles = { + "bright": colorama.Style.BRIGHT, + "dim": colorama.Style.DIM, + None: "", + } + pre = colors[color] + styles[style] + post = colorama.Style.RESET_ALL + return f"{pre}{msg}{post}" + + +def cprint(msg, color=None, style=None): + print(colored(msg, color=color, style=style)) + + +def wait_for_enter(): + input(colored("\nPress Enter to continue", style="dim")) + print() + + +def get_package_name(): + with open("./setup.py", "r") as fp: + nameline = next( + (l.strip() for l in fp if l.startswith("NAME = ")), None + ) + return nameline.split("=")[-1].strip().strip('"') + + +class Step: + def pre(self, context): + pass + + def post(self, context): + wait_for_enter() + + def run(self, context): + try: + self.pre(context) + self.action(context) + self.post(context) + except KeyboardInterrupt: + cprint("\nInterrupted.", color="red") + raise SystemExit(1) + + def instruct(self, msg): + cprint(msg, color="green") + + def print_run(self, msg): + cprint("Run:", color="cyan", style="bright") + self.print_cmd(msg) + + def print_cmd(self, msg): + cprint("\t" + msg, color="cyan", style="bright") + + def do_cmd(self, cmd): + cprint(f"Going to run: {cmd}", color="magenta", style="bright") + wait_for_enter() + os.system(cmd) + + +class GitToMaster(Step): + def action(self, context): + self.instruct("Make sure you're on master and changes are merged in") + self.print_run("git checkout master") + + +class UpdateChangelog(Step): + def action(self, context): + self.instruct(f"Update change log for version {context['version']}") + self.print_run("vi CHANGELOG.md") + + +class RunTests(Step): + def action(self, context): + self.do_cmd("make test") + + +class BumpVersionPackage(Step): + def action(self, context): + self.instruct(f"Update __version__.py with new version") + self.print_run(f"vi {context['pkgname']}/__version__.py") + + def post(self, context): + wait_for_enter() + context["version"] = self._get_version(context) + + def _get_version(self, context): + # Get the version from the version file + about = {} + with open(f"{context['pkgname'].lower()}/__version__.py", "r") as fp: + exec(fp.read(), about) + return about["__version__"] + + +class MakeClean(Step): + def action(self, context): + self.do_cmd("make clean") + + +class MakeDocs(Step): + def action(self, context): + self.do_cmd("make docs") + + +class MakeDist(Step): + def action(self, context): + self.do_cmd("make dist") + + +class PushToTestPyPI(Step): + def action(self, context): + self.do_cmd( + "twine upload --repository-url https://test.pypi.org/legacy/ dist/*" + ) + + +class InstallFromTestPyPI(Step): + def action(self, context): + self.print_run("cd /tmp/") + self.print_cmd("rm -rf ./venv") + self.print_cmd("virtualenv ./venv") + self.print_cmd("source ./venv/bin/activate") + self.print_cmd( + "pip install --index-url https://test.pypi.org/simple/ " + + f"--extra-index-url https://pypi.org/simple {context['pkgname']}=={context['version']}" + ) + + +class TestPackage(Step): + def action(self, context): + self.instruct( + f"Ensure that the following command gives version {context['version']}" + ) + self.print_run( + f"python -c 'import {context['pkgname']}; print({context['pkgname']}.__version__)'" + ) + + +class DeactivateVenv(Step): + def action(self, context): + self.print_run("deactivate") + self.instruct("Go back to the project directory") + + +class GitTagVersion(Step): + def action(self, context): + self.do_cmd(f"git tag v{context['version']}") + + +class GitTagPreRelease(Step): + def action(self, context): + self.instruct("Tag version as a pre-release (increment as needed)") + self.print_run(f"git tag v{context['version']}-rc.1") + + +class GitAdd(Step): + def action(self, context): + self.instruct("Add everything to git and commit") + self.print_run("git gui") + + +class GitAddRelease(Step): + def action(self, context): + self.instruct("Add Changelog & Readme to git") + self.instruct( + f"Commit with title: PyGenSVM Release {context['version']}" + ) + self.instruct("Embed changelog in body commit message") + self.print_run("git gui") + + +class PushToPyPI(Step): + def action(self, context): + self.do_cmd("twine upload dist/*") + + +class PushToGitHub(Step): + def action(self, context): + self.do_cmd("git push -u --tags origin master") + + +class WaitForTravis(Step): + def action(self, context): + webbrowser.open(URLS["Travis"]) + self.instruct( + "Wait for Travis to complete and verify that its successful" + ) + + +class WaitForRTD(Step): + def action(self, context): + webbrowser.open(URLS["RTD"]) + self.instruct( + "Wait for ReadTheDocs to complete and verify that its successful" + ) + + +def main(): + colorama.init() + procedure = [ + GitToMaster(), + GitAdd(), + MakeClean(), + MakeDocs(), + RunTests(), + PushToGitHub(), # trigger Travis to run tests on all platforms + WaitForTravis(), + WaitForRTD(), + BumpVersionPackage(), + GitAdd(), + GitTagPreRelease(), + PushToGitHub(), # trigger Travis to run tests using cibuildwheel + WaitForTravis(), + UpdateChangelog(), + MakeClean(), + MakeDocs(), + MakeDist(), + PushToTestPyPI(), + InstallFromTestPyPI(), + TestPackage(), + DeactivateVenv(), + GitAddRelease(), + PushToPyPI(), + GitTagVersion(), + PushToGitHub(), # triggers Travis to build with cibw and push to PyPI + WaitForTravis(), + ] + context = {} + context["pkgname"] = get_package_name() + for step in procedure: + step.run(context) + cprint("\nDone!", color="yellow", style="bright") + + +if __name__ == "__main__": + main() |
