stable-rt-tools 1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stable_rt_tools/__init__.py +26 -0
- stable_rt_tools/about.py +51 -0
- stable_rt_tools/srt.py +80 -0
- stable_rt_tools/srt_announce.py +240 -0
- stable_rt_tools/srt_commit.py +116 -0
- stable_rt_tools/srt_create.py +95 -0
- stable_rt_tools/srt_git_filter.py +41 -0
- stable_rt_tools/srt_patches.py +174 -0
- stable_rt_tools/srt_prep.py +78 -0
- stable_rt_tools/srt_push.py +74 -0
- stable_rt_tools/srt_sign.py +76 -0
- stable_rt_tools/srt_tag.py +57 -0
- stable_rt_tools/srt_upload.py +82 -0
- stable_rt_tools/srt_util.py +253 -0
- stable_rt_tools/srt_util_context.py +98 -0
- stable_rt_tools/srt_util_tag.py +121 -0
- stable_rt_tools/tests/__init__.py +0 -0
- stable_rt_tools/tests/test_srt.py +768 -0
- stable_rt_tools/tests/test_srt_announce.py +67 -0
- stable_rt_tools/tests/test_srt_push.py +82 -0
- stable_rt_tools/tests/test_srt_util.py +135 -0
- stable_rt_tools/tests/test_srt_util_context.py +63 -0
- stable_rt_tools/tests/test_srt_util_tag.py +113 -0
- stable_rt_tools-1.4.dist-info/METADATA +37 -0
- stable_rt_tools-1.4.dist-info/RECORD +28 -0
- stable_rt_tools-1.4.dist-info/WHEEL +5 -0
- stable_rt_tools-1.4.dist-info/entry_points.txt +2 -0
- stable_rt_tools-1.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# srt - support out of tree patch workflows
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) Daniel Wagner <dwagner@suse.de>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be
|
|
15
|
+
# included in all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
"""
|
|
25
|
+
srt - support out of tree patch workflows
|
|
26
|
+
"""
|
stable_rt_tools/about.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# stable-rt-tools - support out of tree patch workflows
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) Daniel Wagner <dwagner@suse.de>
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
"""
|
|
23
|
+
Setup script for stable-rt-tools, a tool to support out of
|
|
24
|
+
tree patch workflows
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
'__version__',
|
|
29
|
+
'__title__',
|
|
30
|
+
'__summary__',
|
|
31
|
+
'__uri__',
|
|
32
|
+
'__doc_uri__',
|
|
33
|
+
'__author__',
|
|
34
|
+
'__email__',
|
|
35
|
+
'__license__',
|
|
36
|
+
'__copyright__',
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
__version__ = '1.4'
|
|
40
|
+
|
|
41
|
+
__title__ = 'stable-rt-tools'
|
|
42
|
+
__summary__ = 'Support out of tree patch workflows'
|
|
43
|
+
__uri__ = 'https://github.com/igaw/stable-rt-tools/' \
|
|
44
|
+
'releases/archive/{version}.tar.gz'.format(version=__version__)
|
|
45
|
+
__doc_uri__ = 'https://stable-rt-tools.readthedocs.io'
|
|
46
|
+
|
|
47
|
+
__author__ = "Daniel Wagner"
|
|
48
|
+
__email__ = 'dwagner@suse.de'
|
|
49
|
+
|
|
50
|
+
__license__ = 'MIT'
|
|
51
|
+
__copyright__ = 'Copyright (c) {} <{}>'.format(__author__, __email__)
|
stable_rt_tools/srt.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# srt - stable rt tooling
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) Siemens AG, 2018
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be
|
|
15
|
+
# included in all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE
|
|
24
|
+
|
|
25
|
+
import argparse
|
|
26
|
+
import logging
|
|
27
|
+
import sys
|
|
28
|
+
|
|
29
|
+
from stable_rt_tools import (srt_announce, srt_commit, srt_create, srt_push,
|
|
30
|
+
srt_sign, srt_tag, srt_upload, srt_patches,
|
|
31
|
+
srt_prep, about)
|
|
32
|
+
|
|
33
|
+
sub_cmd = {
|
|
34
|
+
'prep': srt_prep,
|
|
35
|
+
'commit': srt_commit,
|
|
36
|
+
'tag': srt_tag,
|
|
37
|
+
'create': srt_create,
|
|
38
|
+
'sign': srt_sign,
|
|
39
|
+
'upload': srt_upload,
|
|
40
|
+
'push': srt_push,
|
|
41
|
+
'announce': srt_announce,
|
|
42
|
+
'patches': srt_patches,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def srt_get_argparser():
|
|
47
|
+
parser = argparse.ArgumentParser(description='srt - stable -rt tool')
|
|
48
|
+
parser.add_argument('-d', '--debug',
|
|
49
|
+
action='store_true',
|
|
50
|
+
help='Enable debug logging')
|
|
51
|
+
parser.add_argument('-v', '--version',
|
|
52
|
+
action='store_true',
|
|
53
|
+
help='Show stable-rt-tools version')
|
|
54
|
+
|
|
55
|
+
subparser = parser.add_subparsers(help='sub command help', dest='cmd')
|
|
56
|
+
|
|
57
|
+
for _, cmd in sub_cmd.items():
|
|
58
|
+
cmd.add_argparser(subparser)
|
|
59
|
+
|
|
60
|
+
return parser
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def main():
|
|
64
|
+
parser = srt_get_argparser()
|
|
65
|
+
args = parser.parse_args(sys.argv[1:])
|
|
66
|
+
if args.version:
|
|
67
|
+
print('stable-rt-tools version {}'.format(about.__version__))
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
if args.debug:
|
|
71
|
+
logging.getLogger().setLevel(logging.DEBUG)
|
|
72
|
+
else:
|
|
73
|
+
logging.getLogger().setLevel(logging.INFO)
|
|
74
|
+
|
|
75
|
+
if args.cmd in sub_cmd:
|
|
76
|
+
sub_cmd[args.cmd].execute(args)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
if __name__ == "__main__":
|
|
80
|
+
main()
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# srt - stable rt tooling
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) Siemens AG, 2018
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be
|
|
15
|
+
# included in all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
from datetime import date, timedelta
|
|
28
|
+
from email.utils import make_msgid
|
|
29
|
+
from time import gmtime, strftime
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
import importlib.resources as pkg_resources
|
|
33
|
+
except ImportError:
|
|
34
|
+
import importlib_resources as pkg_resources
|
|
35
|
+
|
|
36
|
+
from stable_rt_tools.srt_util import (check_context, cmd, confirm, get_config,
|
|
37
|
+
get_gpg_fingerprint,
|
|
38
|
+
get_local_branch_name,
|
|
39
|
+
get_remote_branch_name)
|
|
40
|
+
from stable_rt_tools.srt_util_context import SrtContext
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def find_starting_ref(ctx):
|
|
44
|
+
# find starting point. first check for stable update only
|
|
45
|
+
ref = cmd(['git', 'log', '--pretty=format:%H', '--merges', '-n', '1'])
|
|
46
|
+
|
|
47
|
+
# if patches have been added, we find the old tag and should start there
|
|
48
|
+
# and not the last merge
|
|
49
|
+
commits = cmd(['git', 'log', '--simplify-by-decoration',
|
|
50
|
+
'--oneline', str(ref) + '..'])
|
|
51
|
+
if ' '.join(commits.split('\n')).find(str(ctx.old_short_tag)) != -1:
|
|
52
|
+
ref = str(ctx.old_tag)
|
|
53
|
+
|
|
54
|
+
return ref
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def create_rc_patches(config, ctx):
|
|
58
|
+
branch_name = get_local_branch_name()
|
|
59
|
+
cmd(['git', 'checkout', '-b', 'next-tmp'])
|
|
60
|
+
|
|
61
|
+
srt_env = os.environ.copy()
|
|
62
|
+
srt_env['SRT_REVIEW_TAG'] = str(ctx.new_tag)
|
|
63
|
+
srt_env['FILTER_BRANCH_SQUELCH_WARNING'] = str(1)
|
|
64
|
+
srt_path = os.path.dirname(os.path.realpath(__file__))
|
|
65
|
+
|
|
66
|
+
ref = find_starting_ref(ctx)
|
|
67
|
+
cmd(['git', 'filter-branch', '-f', '--msg-filter',
|
|
68
|
+
srt_path + '/srt_git_filter.py', str(ref) + '..'],
|
|
69
|
+
env=srt_env)
|
|
70
|
+
|
|
71
|
+
cmd(['git', 'format-patch', str(ref) + '..',
|
|
72
|
+
'-o', ctx.new_dir_mails, '--subject-prefix', 'PATCH RT',
|
|
73
|
+
'--cover-letter'])
|
|
74
|
+
|
|
75
|
+
cmd(['git', 'checkout', branch_name])
|
|
76
|
+
cmd(['git', 'branch', '-D', 'next-tmp'])
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def cover_letter_replacements(config, ctx):
|
|
80
|
+
r = {
|
|
81
|
+
"mail_to": config['MAIL_TO'],
|
|
82
|
+
"major": ctx.new_tag.major,
|
|
83
|
+
"minor": ctx.new_tag.minor,
|
|
84
|
+
"patch": ctx.new_tag.patch,
|
|
85
|
+
"new_version": ctx.new_short_tag,
|
|
86
|
+
"old_version": ctx.old_short_tag,
|
|
87
|
+
"prj_dir": config['PRJ_DIR'],
|
|
88
|
+
"message_id": make_msgid(),
|
|
89
|
+
"sender": config['SENDER'],
|
|
90
|
+
"name": config['NAME'],
|
|
91
|
+
"new_tag_rt": ctx.new_tag.rt,
|
|
92
|
+
"gpg_key_fingerprint": get_gpg_fingerprint(config),
|
|
93
|
+
}
|
|
94
|
+
if ctx.is_rc:
|
|
95
|
+
r["new_tag_rc"] = ctx.new_tag.rc
|
|
96
|
+
return r
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def write_rc_cover_letter(config, ctx):
|
|
100
|
+
with open(ctx.new_dir_mails + '/0000-cover-letter.patch', 'r') as f:
|
|
101
|
+
coverletter = f.read()
|
|
102
|
+
|
|
103
|
+
coverletter = coverletter.replace('*** SUBJECT HERE ***',
|
|
104
|
+
'Linux ' + str(ctx.new_tag))
|
|
105
|
+
|
|
106
|
+
rc_text = ''
|
|
107
|
+
with open(get_rc_templ_path(config), 'r') as f:
|
|
108
|
+
rc_text = f.read()
|
|
109
|
+
|
|
110
|
+
r = cover_letter_replacements(config, ctx)
|
|
111
|
+
|
|
112
|
+
today = date.today()
|
|
113
|
+
rc_date = today + timedelta(weeks=1)
|
|
114
|
+
r["release_date"] = rc_date
|
|
115
|
+
|
|
116
|
+
rc_text = rc_text.format(**r)
|
|
117
|
+
|
|
118
|
+
coverletter = coverletter.replace('*** BLURB HERE ***',
|
|
119
|
+
rc_text)
|
|
120
|
+
|
|
121
|
+
with open(ctx.new_dir_mails + '/0000-cover-letter.patch', 'w') as f:
|
|
122
|
+
f.write(coverletter)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def send_rc_patches(config, ctx, args):
|
|
126
|
+
gmd = ['git', 'send-email', '--confirm=never']
|
|
127
|
+
if args.suppress_cc:
|
|
128
|
+
gmd += ['--suppress-cc=all']
|
|
129
|
+
gmd += ['--to="{}"'.format(t) for t in config['MAIL_TO'].split(',')]
|
|
130
|
+
gmd += [ctx.new_dir_mails]
|
|
131
|
+
|
|
132
|
+
print('Dry run')
|
|
133
|
+
gmdd = gmd.copy()
|
|
134
|
+
gmdd.insert(2, '--dry-run')
|
|
135
|
+
print(cmd(gmdd, verbose=True))
|
|
136
|
+
if confirm('OK to send patches?'):
|
|
137
|
+
cmd(gmd)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def announce_rc(config, ctx, args):
|
|
141
|
+
create_rc_patches(config, ctx)
|
|
142
|
+
write_rc_cover_letter(config, ctx)
|
|
143
|
+
send_rc_patches(config, ctx, args)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def get_announce_tmpl_path(config):
|
|
147
|
+
if 'ANNOUNCE' in config:
|
|
148
|
+
return config['ANNOUNCE']
|
|
149
|
+
|
|
150
|
+
# Use importlib.resources.files for modern resource access
|
|
151
|
+
return str(
|
|
152
|
+
pkg_resources.files('stable_rt_tools').joinpath('announce-srt.txt')
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_rc_templ_path(config):
|
|
157
|
+
if 'RC_TEXT' in config:
|
|
158
|
+
return config['RC_TEXT']
|
|
159
|
+
|
|
160
|
+
return str(
|
|
161
|
+
pkg_resources.files('stable_rt_tools').joinpath('announce-srt-rc.txt')
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def announce(config, ctx, args):
|
|
166
|
+
from stable_rt_tools.srt_util import is_quilt_workflow
|
|
167
|
+
if ctx.is_rc:
|
|
168
|
+
announce_rc(config, ctx, args)
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
if is_quilt_workflow(config):
|
|
172
|
+
import subprocess
|
|
173
|
+
tag = str(ctx.new_tag) + '-patches'
|
|
174
|
+
try:
|
|
175
|
+
msg = subprocess.check_output([
|
|
176
|
+
'git', 'show', '-s', '--format=%B', tag
|
|
177
|
+
], encoding='utf-8').strip()
|
|
178
|
+
announce_start = msg.find('[ANNOUNCE]')
|
|
179
|
+
if announce_start != -1:
|
|
180
|
+
lines = msg[announce_start:].splitlines()
|
|
181
|
+
msg = '\n'.join(lines[1:]).lstrip('\n')
|
|
182
|
+
else:
|
|
183
|
+
pass
|
|
184
|
+
timestamp = strftime('%a, %d %b %Y %H:%M:%S -0000', gmtime())
|
|
185
|
+
sender = config.get('SENDER', '')
|
|
186
|
+
mail_to = config.get('MAIL_TO', '')
|
|
187
|
+
print(f"From: {sender}")
|
|
188
|
+
print(f"To: {mail_to}")
|
|
189
|
+
print(f"Subject: [ANNOUNCE] {ctx.new_tag}")
|
|
190
|
+
print(f"Date: {timestamp}\n")
|
|
191
|
+
print(msg)
|
|
192
|
+
except Exception as e:
|
|
193
|
+
print(f"Error extracting announcement from tag {tag}: {e}")
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
# rfc2822.html
|
|
197
|
+
# 3.3. Date and Time Specification
|
|
198
|
+
timestamp = strftime('%a, %d %b %Y %H:%M:%S -0000', gmtime())
|
|
199
|
+
|
|
200
|
+
stable_rt_text = ''
|
|
201
|
+
with open(get_announce_tmpl_path(config), 'r') as f:
|
|
202
|
+
stable_rt_text = f.read()
|
|
203
|
+
|
|
204
|
+
r = cover_letter_replacements(config, ctx)
|
|
205
|
+
|
|
206
|
+
r["date"] = timestamp
|
|
207
|
+
r["branch_name"] = get_remote_branch_name()
|
|
208
|
+
r["branch_head"] = cmd(['git', 'rev-parse', 'HEAD'])
|
|
209
|
+
|
|
210
|
+
print(stable_rt_text.format(**r))
|
|
211
|
+
|
|
212
|
+
ref = find_starting_ref(ctx)
|
|
213
|
+
print(cmd(['git', '--no-pager', 'shortlog', '{0}..{1}'.
|
|
214
|
+
format(ref, ctx.new_tag)]))
|
|
215
|
+
|
|
216
|
+
print('---')
|
|
217
|
+
|
|
218
|
+
print(cmd(['git', '--no-pager', 'diff', '--stat', '{0}..{1}'.
|
|
219
|
+
format(ref, ctx.new_tag)]))
|
|
220
|
+
|
|
221
|
+
print('---')
|
|
222
|
+
|
|
223
|
+
print(cmd(['git', '--no-pager', 'diff', '{0}..{1}'.
|
|
224
|
+
format(ref, ctx.new_tag)]))
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def add_argparser(parser):
|
|
228
|
+
prs = parser.add_parser('announce')
|
|
229
|
+
prs.add_argument('OLD_TAG', nargs='?')
|
|
230
|
+
prs.add_argument('NEW_TAG', nargs='?')
|
|
231
|
+
prs.add_argument('--suppress-cc', '-s', action="store_true", default=False,
|
|
232
|
+
help='Don''t auto-cc anyone (for testing)')
|
|
233
|
+
return prs
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def execute(args):
|
|
237
|
+
ctx = SrtContext(args)
|
|
238
|
+
check_context(ctx)
|
|
239
|
+
|
|
240
|
+
announce(get_config(), ctx, args)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# srt - stable rt tooling
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) Siemens AG, 2018
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be
|
|
15
|
+
# included in all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
import re
|
|
27
|
+
import shutil
|
|
28
|
+
import sys
|
|
29
|
+
import tempfile
|
|
30
|
+
|
|
31
|
+
from stable_rt_tools.srt_util import (cmd, confirm, get_config, get_gnupghome,
|
|
32
|
+
get_last_rt_tag, get_remote_branch_name,
|
|
33
|
+
is_dirty)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def localversion_set(filename, version):
|
|
37
|
+
with open(filename, 'w') as f:
|
|
38
|
+
f.write(version)
|
|
39
|
+
f.write('\n')
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def localversion_inc(filename):
|
|
43
|
+
with open(filename, 'r+') as f:
|
|
44
|
+
line = f.readline()
|
|
45
|
+
version = int(line[3:])
|
|
46
|
+
f.seek(0)
|
|
47
|
+
f.write('-rt{0}\n'.format(version+1))
|
|
48
|
+
f.truncate()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_kernel_version():
|
|
52
|
+
tmp = tempfile.mkdtemp()
|
|
53
|
+
cmd(['make', 'O=%s' % tmp, 'defconfig'])
|
|
54
|
+
line = cmd(['make', '-s', 'O=%s' % tmp, 'kernelrelease'])
|
|
55
|
+
shutil.rmtree(tmp)
|
|
56
|
+
return line.strip()[:-1]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def last_commit_was_release_commit():
|
|
60
|
+
p = re.compile(r'^.*Linux ([0-9\.]+[-a-z0-9]+)( REBASE)*')
|
|
61
|
+
lines = cmd(['git', 'log', '-1', '--pretty=%B'])
|
|
62
|
+
for msg in iter(lines.splitlines()):
|
|
63
|
+
m = p.match(msg)
|
|
64
|
+
if not m:
|
|
65
|
+
continue
|
|
66
|
+
return True
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def commit(config, rc):
|
|
71
|
+
if is_dirty():
|
|
72
|
+
print('repo is dirty -> abort', file=sys.stderr)
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
branch_name = get_remote_branch_name()
|
|
76
|
+
post_fix = branch_name.split('-')[-1]
|
|
77
|
+
branch_rebase = True if post_fix == 'rebase' else False
|
|
78
|
+
|
|
79
|
+
old_head = cmd(['git', 'rev-parse', 'HEAD'])
|
|
80
|
+
|
|
81
|
+
if branch_rebase:
|
|
82
|
+
rt = get_last_rt_tag(branch_name, '-rebase')
|
|
83
|
+
if last_commit_was_release_commit():
|
|
84
|
+
cmd(['git', 'reset', 'HEAD~'])
|
|
85
|
+
localversion_set(config['LOCALVERSION'], rt)
|
|
86
|
+
elif rc:
|
|
87
|
+
rt = get_last_rt_tag(branch_name, '-next')
|
|
88
|
+
rt = rt[3:]
|
|
89
|
+
rt = int(rt) + 1
|
|
90
|
+
localversion_set(config['LOCALVERSION'], '-rt{0}-rc{1}'.format(rt, rc))
|
|
91
|
+
else:
|
|
92
|
+
localversion_inc(config['LOCALVERSION'])
|
|
93
|
+
|
|
94
|
+
version = get_kernel_version()
|
|
95
|
+
msg = 'Linux {0}'.format(version)
|
|
96
|
+
if branch_rebase:
|
|
97
|
+
msg = msg + ' REBASE'
|
|
98
|
+
|
|
99
|
+
print('git commit -m {0}'.format(msg))
|
|
100
|
+
if confirm('OK to commit?'):
|
|
101
|
+
cmd(['git', 'add', config['LOCALVERSION']])
|
|
102
|
+
cmd(['git', 'commit', '-s', '-m', msg],
|
|
103
|
+
env={'GNUPGHOME': get_gnupghome(config)})
|
|
104
|
+
else:
|
|
105
|
+
cmd(['git', 'reset', '--hard', old_head])
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def add_argparser(parser):
|
|
109
|
+
prs = parser.add_parser('commit')
|
|
110
|
+
prs.add_argument('--release-candidate', '-r',
|
|
111
|
+
default=None, metavar='N', type=int)
|
|
112
|
+
return prs
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def execute(args):
|
|
116
|
+
commit(get_config(), args.release_candidate)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# srt - stable rt tooling
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) Siemens AG, 2018
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be
|
|
15
|
+
# included in all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
from logging import debug
|
|
28
|
+
from subprocess import PIPE, Popen
|
|
29
|
+
|
|
30
|
+
from stable_rt_tools.srt_util import check_context, cmd, get_config
|
|
31
|
+
from stable_rt_tools.srt_util_context import SrtContext
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def create_patch_file(old_tag, new_tag, filename):
|
|
35
|
+
with open(filename, 'w') as file:
|
|
36
|
+
c1 = ['git', 'diff', str(old_tag), str(new_tag)]
|
|
37
|
+
c2 = ['xz', '-9']
|
|
38
|
+
|
|
39
|
+
debug('run: ' + ' '.join(c1) + ' | ' + ' '.join(c2))
|
|
40
|
+
|
|
41
|
+
p1 = Popen(c1, stdout=PIPE)
|
|
42
|
+
p2 = Popen(c2, stdin=p1.stdout, stdout=file)
|
|
43
|
+
p1.stdout.close()
|
|
44
|
+
p2.wait()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def create_series(old_tag, new_tag, dirname):
|
|
48
|
+
cmd(['git', 'format-patch', '-q', '-o', dirname,
|
|
49
|
+
'{0}..{1}'.format(old_tag, new_tag)])
|
|
50
|
+
|
|
51
|
+
patches = [f for f in sorted(os.listdir(dirname))
|
|
52
|
+
if os.path.isfile(os.path.join(dirname, f))]
|
|
53
|
+
with open(dirname + '/series', 'w') as file:
|
|
54
|
+
for p in patches:
|
|
55
|
+
file.write('{0}\n'.format(p))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def create_tar_file(dirname, filename):
|
|
59
|
+
cmd(['tar', '-C', dirname, '-cJf', filename, 'patches/'])
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def create(config, ctx):
|
|
63
|
+
for d in [ctx.new_dir_patches, ctx.new_dir_series]:
|
|
64
|
+
if not os.path.exists(d):
|
|
65
|
+
os.makedirs(d)
|
|
66
|
+
|
|
67
|
+
if ctx.new_tag.is_rc:
|
|
68
|
+
create_patch_file(ctx.old_tag.base, str(
|
|
69
|
+
ctx.new_tag), ctx.new_fln_patch)
|
|
70
|
+
create_series(ctx.old_tag, ctx.new_tag, ctx.new_dir_series)
|
|
71
|
+
else:
|
|
72
|
+
create_patch_file(ctx.new_tag.base, str(
|
|
73
|
+
ctx.new_tag), ctx.new_fln_patch)
|
|
74
|
+
create_series(ctx.new_tag.base, ctx.new_tag.rebase, ctx.new_dir_series)
|
|
75
|
+
|
|
76
|
+
create_tar_file(ctx.new_dir_patches, ctx.new_fln_tar)
|
|
77
|
+
|
|
78
|
+
print('Created the following files in {0}'.format(ctx.new_dir_patches))
|
|
79
|
+
for f in ctx.get_files():
|
|
80
|
+
print('\t{0}'.format(f))
|
|
81
|
+
print('Review them')
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def add_argparser(parser):
|
|
85
|
+
prs = parser.add_parser('create')
|
|
86
|
+
prs.add_argument('OLD_TAG', nargs='?')
|
|
87
|
+
prs.add_argument('NEW_TAG', nargs='?')
|
|
88
|
+
return prs
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def execute(args):
|
|
92
|
+
ctx = SrtContext(args)
|
|
93
|
+
check_context(ctx)
|
|
94
|
+
|
|
95
|
+
create(get_config(), ctx)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# srt - stable rt tooling
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) Siemens AG, 2018
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be
|
|
15
|
+
# included in all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
import sys
|
|
28
|
+
|
|
29
|
+
review_tag = os.environ['SRT_REVIEW_TAG']
|
|
30
|
+
message = sys.stdin.readlines()
|
|
31
|
+
|
|
32
|
+
msg = """\
|
|
33
|
+
{} stable review patch.
|
|
34
|
+
If anyone has any objections, please let me know.
|
|
35
|
+
|
|
36
|
+
-----------
|
|
37
|
+
""".format(review_tag)
|
|
38
|
+
|
|
39
|
+
print(message[0])
|
|
40
|
+
print(msg)
|
|
41
|
+
print(''.join(message[1:]))
|