-
Notifications
You must be signed in to change notification settings - Fork 4
/
release.py
executable file
·145 lines (114 loc) · 4.42 KB
/
release.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python
import base64
import collections
import httplib
import json
import mimetypes
import os
import sys
import subprocess
mimetypes.init()
this_dir = os.path.dirname(os.path.abspath(__file__))
dist_dir = os.path.join(this_dir, "dist")
setup_py = os.path.join(this_dir, "setup.py")
def ordered_hook(pairs):
ordered = collections.OrderedDict()
for pair in pairs:
ordered[pair[0]] = pair[1]
return ordered
class ReleaseCommand(object):
def __init__(self):
self.package = json.load(open("setup.json", "r"),
object_pairs_hook = ordered_hook)
self.tarball_name = "%s-%s.tar.gz" % \
(self.package["name"], self.package["version"])
self.tarball = os.path.join(dist_dir, self.tarball_name)
def run(self, *args):
print "-> %s" % " ".join(args)
return subprocess.check_output(args)
def read_access_token(self):
access_token = self.run("git", "config", "github.files.accesstoken")
self.access_token = access_token.strip()
def github_api(self, path, data):
body = json.dumps(data)
connection = httplib.HTTPSConnection("api.github.com")
auth = base64.encodestring('%s:%s' % (self.access_token, 'x-oauth-basic')).replace('\n', '')
connection.request("POST", path, body, {
"Authorization": "Basic %s" % auth,
})
response = connection.getresponse()
response_body = response.read()
connection.close()
data = json.loads(response_body)
if "errors" in data:
print >>sys.stderr, "Github Response Failed: %s" % data["message"]
for error in data["errors"]:
print >>sys.stderr, " Error: %s\n" % error["code"]
return data
def github_upload(self):
self.read_access_token()
description = "%s version %s" % \
(self.package["name"], self.package["version"])
data = self.github_api("/repos/marshall/logcat-color/releases", {
"tag_name": "v%s" % self.package["version"],
"name": self.package["version"],
"body": description,
})
print data
upload_url = data["upload_url"].replace("{?name}", "?name=%s" % self.tarball_name)
self.run("curl",
"-u", "%s:x-oauth-basic" % self.access_token,
"-F", "Content-Type=%s" % mimetypes.guess_type(self.tarball)[0],
"-F", "file=@%s" % self.tarball,
upload_url)
def help(self):
print """
Usage: %s <command> [args]
Supported commands:
help view this help message
build build source distribution tarball
push push the release tarball to github and pypi, and push git tags
bump [version] bump to [version] in setup.json, stage, and prepare a commit message
""" % sys.argv[0]
def build(self):
# build sdist
self.run(sys.executable, setup_py, "sdist")
print "%s succesfully built. to tag, use %s tag\n" % \
(self.tarball_name, sys.argv[0])
def push(self):
# upload source tarball->github, and setup.py upload for pypi
self.github_upload()
self.run(sys.executable, setup_py, "sdist", "upload")
print "%s successfully uploaded, and v%s tag pushed. to bump, use %s bump\n" % \
(self.tarball_name, self.package["version"], sys.argv[0])
def bump(self):
if len(sys.argv) < 3:
print >>sys.stderr, "Error: bump requires a version to bump to"
sys.exit(1)
bump_version = sys.argv[2]
self.package["version"] = bump_version
setup_json = json.dumps(self.package,
separators = (',', ': '),
indent = 4)
open("setup.json", "w").write(setup_json)
message = "bump to version %s" % bump_version
self.run("git", "add", "setup.json")
# TODO -- full path is needed for execv, detect this
git = "/usr/bin/git"
os.execv(git, (git, "commit", "-v", "-m", message, "-e"))
def main(self):
command = "help"
if len(sys.argv) > 1:
command = sys.argv[1]
if command == "help":
self.help()
elif command == "build":
self.build()
elif command == "tag":
self.tag()
elif command == "push":
self.push()
elif command == "bump":
self.bump()
if __name__ == "__main__":
ReleaseCommand().main()