| |
@@ -336,22 +336,79 @@
|
| |
return encoding == "binary"
|
| |
|
| |
|
| |
- def spec_file_processed_by_rpmautospec(file_name, dir_path=None):
|
| |
+ def _replace_lines(lines, startline, endline, replacement_lines=None, strip_endline=False):
|
| |
+ replacement_lines = replacement_lines or []
|
| |
+ try:
|
| |
+ start = lines.index(startline)
|
| |
+ end = lines.index(endline, start)
|
| |
+ except ValueError:
|
| |
+ # if both are missing, nothing to do, all good
|
| |
+ # if only one of them is present, we better not touch it
|
| |
+ return lines, False
|
| |
+ else:
|
| |
+ # rpmautospec adds an empty line after the end
|
| |
+ # we want to remove it, but only if it is actually empty
|
| |
+ if strip_endline and lines[end+1] == "\n":
|
| |
+ end += 1
|
| |
+ lines = lines[:start] + replacement_lines + lines[end+1:]
|
| |
+ return lines, True
|
| |
+
|
| |
+
|
| |
+ def spec_file_undo_rpmautospec(file_name, dir_path=None):
|
| |
+ """
|
| |
+ Given a path to specfile, undo changes generated by rpmautospec.
|
| |
+ Iff there is something to undo, the specfile will be overwritten.
|
| |
+
|
| |
+ Namely:
|
| |
+
|
| |
+ 1. Removes everything between the following lines:
|
| |
+ ## START: Set by rpmautospec
|
| |
+ ## END: Set by rpmautospec
|
| |
+ 2. Replaces everything between the following lines with %autochangelog:
|
| |
+ ## START: Generated by rpmautospec
|
| |
+ ## END: Generated by rpmautospec
|
| |
+
|
| |
+ Both of the steps only happen once. If the specfile contains multiple such sections,
|
| |
+ only the first one is removed/replaced.
|
| |
+
|
| |
+ The saved spec file is not guaranteed to be bit-by-bit identical with the original
|
| |
+ spec file used as an input to rpmautospec.
|
| |
+ However, subsequent repeated conversions there and back should be quite stable.
|
| |
+
|
| |
+ The return value says whether the specfile was overwritten.
|
| |
+ """
|
| |
file_path = os.path.join(dir_path or "", file_name)
|
| |
|
| |
try:
|
| |
- contents = open(file_path).readlines()
|
| |
+ with open(file_path) as f:
|
| |
+ contents = f.readlines()
|
| |
except Exception:
|
| |
- # if we can't read it, let's assume the answer is "no".
|
| |
+ # if we can't read it, let's do nothing
|
| |
return False
|
| |
|
| |
- # Check for the %autorelease header prepended to the file
|
| |
- if any('START: Set by rpmautospec' in line for line in contents[:10]):
|
| |
+ # remove the generated macro section near the beginning of the specfile
|
| |
+ contents, was_removed = _replace_lines(
|
| |
+ contents,
|
| |
+ '## START: Set by rpmautospec\n',
|
| |
+ '## END: Set by rpmautospec\n',
|
| |
+ strip_endline=True)
|
| |
+
|
| |
+ # replace the generated changelog with %autochangelog
|
| |
+ # note that this does not generally produce content identical to the original
|
| |
+ # e.g. the macro could have been conditionalized or in curly brackets
|
| |
+ # most importantly, the %changelog section might have been omitted entirely
|
| |
+ # however, this should be Good Enough for most of us
|
| |
+ contents, was_replaced = _replace_lines(
|
| |
+ contents,
|
| |
+ '## START: Generated by rpmautospec\n',
|
| |
+ '## END: Generated by rpmautospec\n',
|
| |
+ ['%autochangelog\n'])
|
| |
+
|
| |
+ # finally, replace the spec if needed
|
| |
+ # if we cannot write it, better blow up
|
| |
+ if was_removed or was_replaced:
|
| |
+ with open(file_path, 'w') as f:
|
| |
+ f.writelines(contents)
|
| |
return True
|
| |
|
| |
- # It seems that currently there's no mechanism to detect
|
| |
- # %autochangelog processing. But most packages would use both
|
| |
- # %autochangelog and %autorelease together, so we should catch
|
| |
- # most cases by checking for %autorelease only.
|
| |
- # https://pagure.io/fedora-infra/rpmautospec/issue/269
|
| |
return False
|
| |
Fixes https://pagure.io/fedpkg/issue/527
Depends-on: https://pagure.io/fedora-infra/rpmautospec/pull-request/312
This is a proof of concept, I haven't touched the tests at all. Will do that if this has a chance of being accepted.