aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGertjan van den Burg <gertjanvandenburg@gmail.com>2020-03-06 16:06:06 +0000
committerGertjan van den Burg <gertjanvandenburg@gmail.com>2020-03-06 16:06:06 +0000
commitc0f546edb5f10a5deea56c23b5e63239a840f657 (patch)
treea1d14049cc7e2bc34362ab72a5748e37590db65e
parentRemoving windows builds from travis for now (diff)
parentUpdate Makefile to current workflow (diff)
downloadpygensvm-c0f546edb5f10a5deea56c23b5e63239a840f657.tar.gz
pygensvm-c0f546edb5f10a5deea56c23b5e63239a840f657.zip
Merge branch 'master' into packaging
-rw-r--r--Makefile56
-rw-r--r--make_release.py268
2 files changed, 293 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index 7dc84b5..8a6181b 100644
--- a/Makefile
+++ b/Makefile
@@ -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()