forked from Xion/callee
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtasks.py
127 lines (104 loc) · 3.92 KB
/
tasks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
Automation tasks, aided by the Invoke package.
"""
import logging
import os
import webbrowser
import sys
from invoke import task
from invoke.exceptions import Exit
from invoke.runners import Result
try:
input = raw_input
except NameError:
pass # Python 3, input() already works like raw_input() in 2.x.
DOCS_DIR = 'docs'
DOCS_OUTPUT_DIR = os.path.join(DOCS_DIR, '_build')
@task(default=True, help={
'all': "Whether to run the tests on all environments (using tox)",
'verbose': "Whether to enable verbose output",
})
def test(ctx, all=False, verbose=False):
"""Run the tests."""
cmd = 'tox' if all else 'py.test'
if verbose:
cmd += ' -v'
return ctx.run(cmd, pty=True).return_code
@task
def lint(ctx):
"""Run the linter."""
return ctx.run('flake8 callee tests', pty=True).return_code
@task(help={
'output': "Documentation output format to produce",
'rebuild': "Whether to rebuild the documentation from scratch",
'show': "Whether to show the docs in the browser (default: yes)",
'verbose': "Whether to enable verbose output",
})
def docs(ctx, output='html', rebuild=False, show=True, verbose=True):
"""Build the docs and show them in default web browser."""
sphinx_build = ctx.run(
'sphinx-build -b {output} {all} {verbose} docs docs/_build'.format(
output=output,
all='-a -E' if rebuild else '',
verbose='-v' if verbose else ''))
if not sphinx_build.ok:
fatal("Failed to build the docs", cause=sphinx_build)
if show:
path = os.path.join(DOCS_OUTPUT_DIR, 'index.html')
if sys.platform == 'darwin':
path = 'file://%s' % os.path.abspath(path)
webbrowser.open_new_tab(path)
# TODO: remove this when PyPI upload from Travis CI is verified to work
@task(help={
'yes': "Whether to actually perform the upload. "
"By default, a confirmation is necessary.",
})
def upload(ctx, yes=False):
"""Upload the package to PyPI.
This is done by adding a Git tag for the current non-dev version
and pushing to GitHub, which triggers the Travis build & deploy pipeline.
"""
import callee
version = callee.__version__
# check the packages version
# TODO: add a 'release' to automatically bless a version as release one
if version.endswith('-dev'):
fatal("Can't upload a development version (%s) to PyPI!", version)
# run the upload if it has been confirmed by the user
if not yes:
answer = input("Do you really want to upload to PyPI [y/N]? ")
yes = answer.strip().lower() == 'y'
if not yes:
logging.warning("Aborted -- not uploading to PyPI.")
return -2
# add a Git tag and push
logging.debug("Tagging current HEAD as %s..." % version)
git_tag = ctx.run('git tag %s' % version)
if not git_tag.ok:
fatal("Failed to add a Git tag for uploaded version %s", version,
cause=git_tag)
git_push = ctx.run('git push && git push --tags')
if not git_push.ok:
fatal("Failed to push the release upstream.", cause=git_push)
logging.info("New version (%s) successfully pushed." % version)
# Utility functions
def fatal(*args, **kwargs):
"""Log an error message and exit.
Following arguments are keyword-only.
:param exitcode: Optional exit code to use
:param cause: Optional Invoke's Result object, i.e.
result of a subprocess invocation
"""
# determine the exitcode to return to the operating system
exitcode = None
if 'exitcode' in kwargs:
exitcode = kwargs.pop('exitcode')
if 'cause' in kwargs:
cause = kwargs.pop('cause')
if not isinstance(cause, Result):
raise TypeError(
"invalid cause of fatal error: expected %r, got %r" % (
Result, type(cause)))
exitcode = exitcode or cause.return_code
logging.error(*args, **kwargs)
raise Exit(exitcode or -1)