-
Notifications
You must be signed in to change notification settings - Fork 78
/
Copy pathupver.py
230 lines (192 loc) · 7.91 KB
/
upver.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!/usr/local/bin/python3.8
###############################################################################
#
# upver - script to up the version of the pyral package
#
USAGE = """
Usage: upver.py [--clean] x.y.z
--clean option removes any target_file.bkp (use prior to a commit)
"""
###############################################################################
import sys, os
import re
from shutil import copyfile, move
import inspect
###############################################################################
ELEMENTS_WITH_VERSION_IDENTITIERS = """
in README.rst:
$ python
Python 3.8.9 [other Python interpreter info elided ...]
>> import requests
>> import pyral
>> pyral.__version__
(1, 5, 2)
in build_dist.py:
VERSION = "1.5.2"
in setup.py:
VERSION = '1.5.2'
modifies version identifier in all pyral/*.py files
in doc/source/conf.py:
# The short X.Y version.
version = '1.5.2'
# The full version, including alpha/beta/rc tags.
release = '1.5.2'
assumes invocation is done in the base directory of the pyral dev tree
"""
FILE_VERSION_LOC = [
('README.rst' , r'^The most recent release of pyral \((\d\.\d+\.\d+)\) has been tested'),
('README.rst' , r'^\s+>> pyral.__version__\n\s+\((\d, \d+, \d+)\)'),
('README.short' , r'^The most recent release of pyral \((\d\.\d+\.\d+)\) has been tested'),
('build_dist.py' , r'^VERSION\s+= "(\d\.\d+\.\d+)"'),
('setup.py' , r'^VERSION\s+= \'(\d\.\d+\.\d+)\''),
('pyral/__init__.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/config.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/context.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/cargotruck.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/entity.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/hydrate.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/query_builder.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/rallyresp.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/restapi.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('pyral/search_utils.py' , r'^__version__ = \((\d, \d+, \d+)\)'),
('doc/source/conf.py' , r'^# The short X\.Y version\.\nversion = \'(\d\.\d+\.\d+)\'\n'),
('doc/source/conf.py' , r'^# The full version, including alpha.*? tags\.\nrelease = \'(\d\.\d+\.\d+)\'')
]
###############################################################################
def main(args):
cleanup = False
if not args:
print("ERROR: no version indentifier provided")
print(USAGE)
sys.exit(1)
options = [opt for opt in args if opt.startswith('-')]
if options and options[0] == "--clean":
args.remove("--clean")
cleanup = True
filenames = set([filename for filename, rx in FILE_VERSION_LOC])
if cleanup:
for filename in filenames:
bkp_file = "%s.bkp" % filename
if os.path.exists(bkp_file):
os.remove(bkp_file)
print("target bkp files have been washed away")
sys.exit(0)
for filename in filenames:
bkp_file = "%s.bkp" % filename
if not os.path.exists(bkp_file):
copyfile(filename, bkp_file)
major, minor, patch = args[0].split('.')
for filename, regex_pattern in FILE_VERSION_LOC:
process_for_version_update(filename, regex_pattern, major, minor, patch)
###############################################################################
def process_for_version_update(filename, regex_pattern, major, minor, patch):
print("")
print(filename)
print(" %s" % regex_pattern)
print("")
with open(filename, 'r') as inf:
content = inf.read()
if r'\n' in regex_pattern: # this is a multiline pattern
mo = re.search(regex_pattern, content, re.M)
if not mo:
print("NO regex match, skipping")
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
return
updated_content = update_multiline_target(content, mo, major, minor, patch)
print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
else: # the pattern is for a single line
lines = content.split("\n")
hits = [(ix, line) for ix, line in enumerate(lines) if re.search(regex_pattern, line)]
if not hits:
print("NO regex match, skipping")
print("---------------------------------------------------")
return
hit_line = hits.pop(0)
updated_content = update_target_hitline(lines, hit_line, regex_pattern, major, minor, patch)
print("+++++++++++++++++++++++++++++++++++++++++++++++++++")
upd_filename = "%s.upd" % filename
with open(upd_filename, 'w') as updf:
updf.write(updated_content)
move(upd_filename, filename)
###############################################################################
def upversion(target, major, minor, patch):
if target.count('.'):
return ".".join([major, minor, patch])
sep_chars = ", "
if target.count(', '):
sep_chars = ", "
elif target.count(','):
sep_chars = ","
upped = sep_chars.join([major, minor, patch])
return upped
###############################################################################
def update_target_hitline(lines, hit_line, regex_pattern, major, minor, patch):
ix, hit = hit_line
print("target line:")
print(hit)
mo = re.search(regex_pattern, hit)
target = mo.groups()[0]
upped = upversion(target, major, minor, patch)
upped_line = hit.replace(target, upped)
print("\nupped line:\n%s" % upped_line)
lines[ix] = upped_line
updated_content = "\n".join(lines)
return updated_content
###############################################################################
def update_multiline_target(content, mo, major, minor, patch):
#dumpit(mo)
before = content[:mo.start()]
after = content[mo.end():]
block = mo.group()
print("target block:\n%s" % block)
target = mo.groups()[0]
print(target)
upped = upversion(target, major, minor, patch)
upped_block = block.replace(target, upped)
print("\nupped block:\n%s" % upped_block)
updated_content = before + upped_block + after
return updated_content
###############################################################################
def dumpit(mo):
"""
'string',
'start',
'end',
'pos',
'endpos',
'expand',
'group',
'groupdict',
'groups',
'lastgroup',
'lastindex',
're',
'regs',
'span',
"""
#guts = inspect.getmembers(mo)
#for attr_name, value in guts:
# if attr_name[:2] != '__':
# print("%s: %s" % (attr_name, value))
# print("")
print("===========================================================")
print("%s: %s" % ('start' , mo.start() ))
print("%s: %s" % ('end' , mo.end() ))
#print("%s: %s" % ('regs' , mo.regs) )
#print("%s: %s" % ('span' , mo.span() ))
print("%s:\n%s" % ('group' , mo.group() ))
span = mo.string[mo.start():mo.end()]
print("span?:\n%s" % span)
#start: <built-in method start of _sre.SRE_Match object at 0x104dc1b90>
#end: <built-in method end of _sre.SRE_Match object at 0x104dc1b90>
#
#regs: ((2186, 2222),)
#span: <built-in method span of _sre.SRE_Match object at 0x104dc1b90>
#
#group: <built-in method group of _sre.SRE_Match object at 0x104dc1b90>
#groups: <built-in method groups of _sre.SRE_Match object at 0x104dc1b90>
#groupdict: <built-in method groupdict of _sre.SRE_Match object at 0x104dc1b90>
###############################################################################
###############################################################################
if __name__ == "__main__":
main(sys.argv[1:])