-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathrelease.py
147 lines (130 loc) · 5.25 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
146
147
# Copyright 2012-2014 Ravello Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import, print_function
import sys
import subprocess
import argparse
import logging
from setup import version_info as vinfo
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
if sys.version_info[0] == 2:
input = raw_input
def sh(cmd, *args):
"""Execute shell command *cmd*. Exit on failure."""
if args:
cmd = cmd.format(*args)
ret = subprocess.call(cmd, shell=True)
if ret == 0:
return
logger.error('Error: cmd {0!r} exited with status {1}'.format(cmd, ret), file=sys.stderr)
sys.exit(1)
def confirm(prompt):
"""Get a confirmation from the user for an action."""
response = None
prompt += ' (y/n) '
while True:
response = input(prompt)
if response in 'yn':
break
logger.info('Please answer "y" or "n"')
return response == 'y'
def get_release_versions(script_bool):
"""Prompt the user for the current and next release versions."""
version = vinfo['version']
if version.endswith('.dev'):
logger.info('Current development version: {0}'.format(version))
relver = version[:-4]
if not script_bool:
override = input('What version do you want to release [{0}]: '.format(relver))
if override:
relver = override
else:
logger.info('Current version is NOT a development version: {0}'.format(version))
if not script_bool and not confirm('Do you want to release this version?'):
return None, None
relver = version
try:
nums = list(map(int, relver.split('.')))
nums[-1] += 1
nextver = '.'.join(map(str, nums))
except ValueError:
nextver = ''
if not script_bool:
override = input('What will be the next version [{0}]: '.format(nextver))
if override:
nextver = override
logger.info('Version to release: {0}'.format(relver))
logger.info('New version to start: {0}'.format(nextver or '(none)'))
if not script_bool and not confirm('Is this correct?'):
return None, None
return relver, nextver
def confirm_file_list(script_bool):
"""Confirm differences between files in Git and in the sdist."""
sh('git ls-files | sort > files.git')
logger.info('Comparing files in git against the source distribution...')
sh('python setup.py sdist >/dev/null 2>&1')
sh('tar tvfz dist/ravello-sdk-{0}.tar.gz'
' | sed -e \'s/^.*{0}\///\' -e \'/\/$/d\' -e \'/^$/d\''
' | sort > files.sdist', vinfo['version'])
sh('diff -u files.git files.sdist || true')
sh('rm files.git; rm files.sdist')
if not script_bool:
return confirm('Are these changes OK?')
else:
return True
def make_release(relver, nextver):
"""Make a release for *relver*. Next version will be *nextver*."""
logger.info('Creating the release..')
if relver != vinfo['version']:
sh('sed -i -e \'s/{0}/{1}/\' setup.py', vinfo['version'], relver)
sh('git add setup.py')
sh('git commit -m "version {0}"', relver)
sh('git tag -a -m "version {0}" {1}-{0}', relver, vinfo['name'])
sh('python setup.py sdist upload >/dev/null')
if nextver:
sh('sed -i -e \'s/{0}/{1}.dev/\' setup.py', relver, nextver)
sh('git add setup.py')
sh('git commit -m "start working on {0}"', nextver)
sh('git push')
sh('git push --tags')
logger.info('Done!')
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-s', action='store_true', default=False,
dest='script_mode',
help='Run the release in script mode , non-interactive')
parser.add_argument('-c', action='store', dest='current_version',
help='Current version')
parser.add_argument('-n', action='store', dest='next_version',
help='Next version')
results = parser.parse_args()
logger.info('script_mode = %s' % results.script_mode)
logger.info('current_version = %s' % results.current_version)
logger.info('next_version = %s' % results.next_version)
if results.current_version is not None or results.next_version is not None:
if results.current_version is not None:
relver=results.current_version
if results.next_version is not None:
nextver=results.next_version
logger.info('Version to release: {0}'.format(relver))
logger.info('New version to start: {0}'.format(nextver or '(none)'))
else:
relver, nextver = get_release_versions(results.script_mode)
if relver is None:
return
if not confirm_file_list(results.script_mode):
return
make_release(relver, nextver)
main()