-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
ferrypicker | ||
=========== | ||
|
||
Apply patches from Fedora dist git to different components. | ||
|
||
This simple tool does 3 steps: | ||
|
||
1. download patch file from src.fedoraproject.org | ||
2. replaces package name with current dist-git work dir package name | ||
3. runs `git am --reject` on the product | ||
|
||
Usage: | ||
|
||
```shell | ||
[python36 (f32 %)]$ git switch -c f32-backport | ||
Switched to a new branch 'f32-backport' | ||
|
||
[python36 (f32-backport %)]$ ferrypick https://src.fedoraproject.org/rpms/python3.6/pull-request/2 | ||
Downloading https://src.fedoraproject.org/rpms/python3.6/pull-request/2.patch | ||
$ git am --reject /tmp/tmp7pa062j6.patch | ||
Applying: Fix python3-config --configdir | ||
Checking patch 00102-lib64.patch... | ||
.git/rebase-apply/patch:26: new blank line at EOF. | ||
+ | ||
Checking patch 00205-make-libpl-respect-lib64.patch... | ||
Checking patch python36.spec... | ||
error: while searching for: | ||
#global prerel ... | ||
%global upstream_version %{general_version}%{?prerel} | ||
Version: %{general_version}%{?prerel:~%{prerel}} | ||
Release: 4%{?dist} | ||
License: Python | ||
|
||
|
||
|
||
error: patch failed: python36.spec:17 | ||
error: while searching for: | ||
# ====================================================== | ||
|
||
%changelog | ||
* Wed May 06 2020 Miro Hrončok <[email protected]> - 3.6.10-4 | ||
- Rename from python36 to python3.6 | ||
|
||
|
||
error: patch failed: python36.spec:1535 | ||
Applied patch 00102-lib64.patch cleanly. | ||
Applied patch 00205-make-libpl-respect-lib64.patch cleanly. | ||
Applying patch python36.spec with 2 rejects... | ||
Rejected hunk #1. | ||
Hunk #2 applied cleanly. | ||
Hunk #3 applied cleanly. | ||
Rejected hunk #4. | ||
Patch failed at 0001 Fix python3-config --configdir | ||
hint: Use 'git am --show-current-patch=diff' to see the failed patch | ||
When you have resolved this problem, run "git am --continue". | ||
If you prefer to skip this patch, run "git am --skip" instead. | ||
To restore the original branch and stop patching, run "git am --abort". | ||
``` | ||
Enjoy. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import contextlib | ||
import os.path | ||
import re | ||
import shutil | ||
import subprocess | ||
import sys | ||
import tempfile | ||
import urllib.request | ||
|
||
COMMIT_RE = re.compile(r"^https://src\.fedoraproject\.org/\S+/([^/\s]+)/c/([0-9a-f]+)") | ||
PR_RE = re.compile(r"^https://src\.fedoraproject\.org/\S+/([^/\s]+)/pull-request/\d+") | ||
REPLACE_SUFFIXES = "spec", "rpmlintrc" | ||
|
||
|
||
def parse_link(link): | ||
""" | ||
For a given pagure link, return package name and the patch link. | ||
Raise ValueError if not recognized. | ||
""" | ||
for regex in COMMIT_RE, PR_RE: | ||
if match := regex.match(link): | ||
return match.group(1), match.group(0) + ".patch" | ||
raise ValueError("Unrecognized link") | ||
|
||
|
||
def rename(bytesline, original_name, current_name): | ||
""" | ||
On a given bytes line, naïvely replace original package name with current package name. | ||
Works on pkgname.spec and pkgname.rpmlintrc only (as defined in REPLACE_SUFFIXES). | ||
""" | ||
if original_name != current_name: | ||
for suffix in REPLACE_SUFFIXES: | ||
for prefix in "a", "b": # this is what git does | ||
original = f"{prefix}/{original_name}.{suffix}".encode("utf-8") | ||
current = f"{prefix}/{current_name}.{suffix}".encode("utf-8") | ||
bytesline = bytesline.replace(original, current) | ||
return bytesline | ||
|
||
|
||
@contextlib.contextmanager | ||
def patch(link, original_name, current_name): | ||
print(f"Downloading {link}") | ||
with tempfile.NamedTemporaryFile(suffix=".patch") as tmp_file: | ||
with urllib.request.urlopen(link) as response: | ||
for line in response: | ||
tmp_file.write(rename(line, original_name, current_name)) | ||
tmp_file.flush() | ||
yield tmp_file.name | ||
|
||
|
||
def stdout(cmd): | ||
return subprocess.check_output(cmd, shell=True, text=True).rstrip() | ||
|
||
|
||
def execute(cmd): | ||
return subprocess.run(cmd, shell=True, text=True) | ||
|
||
|
||
def main(): | ||
# TODO?: Add more sophisticated argument parsing | ||
if len(sys.argv) < 2: | ||
sys.exit(f"Usage: {sys.argv[0]} COMMIT_OR_PR_LINK [CURRENT_PKGNAME]") | ||
link = sys.argv[1] | ||
try: | ||
current_name = sys.argv[2] | ||
except IndexError: | ||
current_name = os.path.basename(stdout("git rev-parse --show-toplevel")) | ||
|
||
original_name, patch_link = parse_link(link) | ||
with patch(patch_link, original_name, current_name) as p: | ||
print(f"$ git am --reject {p}") | ||
execute(f"git am --reject {p}") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
From a0928446f85cfccf3c2fe26a2726502931b91f76 Mon Sep 17 00:00:00 2001 | ||
From: Tomas Orsava <[email protected]> | ||
Date: May 26 2020 17:16:15 +0000 | ||
Subject: rpmlint: Small fixes | ||
|
||
|
||
--- | ||
|
||
diff --git a/python3.8.rpmlintrc b/python3.8.rpmlintrc | ||
index 013f1e9..b97e76f 100644 | ||
--- a/python3.8.rpmlintrc | ||
+++ b/python3.8.rpmlintrc | ||
@@ -4,7 +4,7 @@ addFilter(r'crypto-policy-non-compliance-openssl') | ||
|
||
|
||
# TESTS: | ||
-addFilter(r'(zero-length|pem-certificate|uncompressed-zip) /usr/lib(64)?/python3.\d+/test') | ||
+addFilter(r'(zero-length|pem-certificate|uncompressed-zip) /usr/lib(64)?/python3\.\d+/test') | ||
|
||
|
||
# OTHER DELIBERATES: | ||
@@ -65,7 +65,7 @@ addFilter(r'^python3(\.\d+)?-debuginfo\.[^:]+: (E|W): useless-provides debuginfo | ||
addFilter(r'library-without-ldconfig-post') | ||
|
||
# debug package contains devel and non-devel files | ||
-addFilter(r'python3(\.\d+)?-debug.[^:]+: (E|W): (non-)?devel-file-in-(non-)?devel-package') | ||
+addFilter(r'python3(\.\d+)?-debug\.[^:]+: (E|W): (non-)?devel-file-in-(non-)?devel-package') | ||
|
||
# this goes to other subpackage, hence not actually dangling, the read error is bogus | ||
addFilter(r'dangling-relative-symlink /usr/lib(64)?/pkgconfig/python-3\.\d+dm?(-embed)?\.pc python-3\.\d+(-embed)?\.pc') | ||
@@ -80,8 +80,8 @@ addFilter(r'macro-in-comment %\{_pyconfig(32|64)_h\}') | ||
|
||
# Python modules don't need to be linked against libc | ||
# Since 3.8 they are no longer linked against libpython3.8.so.1.0 | ||
-addFilter(r'E: library-not-linked-against-libc /usr/lib(64)?/python3.\d+/lib-dynload/') | ||
-addFilter(r'E: shared-lib-without-dependency-information /usr/lib(64)?/python3.\d+/lib-dynload/') | ||
+addFilter(r'E: library-not-linked-against-libc /usr/lib(64)?/python3\.\d+/lib-dynload/') | ||
+addFilter(r'E: shared-lib-without-dependency-information /usr/lib(64)?/python3\.\d+/lib-dynload/') | ||
|
||
# SPELLING ERRORS | ||
addFilter(r'spelling-error .* en_US (bytecode|pyc|filename|tkinter|namespaces|pytest) ') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import pytest | ||
from pathlib import Path | ||
|
||
import ferrypick | ||
|
||
|
||
U = "https://src.fedoraproject.org" | ||
|
||
|
||
def test_parse_link_pr(): | ||
n, p = ferrypick.parse_link(f"{U}/rpms/python-rpm-macros/pull-request/62") | ||
assert p == f"{U}/rpms/python-rpm-macros/pull-request/62.patch" | ||
assert n == "python-rpm-macros" | ||
|
||
|
||
def test_parse_link_commit(): | ||
hash = "f54cef86717adf4f5374820c3d5314f75b340b8b" | ||
n, p = ferrypick.parse_link(f"{U}/rpms/python3.7/c/{hash}?branch=master") | ||
assert p == f"{U}/rpms/python3.7/c/{hash}.patch" | ||
assert n == "python3.7" | ||
|
||
|
||
def test_parse_link_commit_from_pr(): | ||
hash = "6697c4ae608728bce1025ef45af" | ||
n, p = ferrypick.parse_link(f"{U}/fork/ca/rpms/python3.7/c/{hash}?branch=rename") | ||
assert p == f"{U}/fork/ca/rpms/python3.7/c/{hash}.patch" | ||
assert n == "python3.7" | ||
|
||
|
||
def test_parse_link_bad(): | ||
with pytest.raises(ValueError): | ||
ferrypick.parse_link(f"{U}/fork/ca/rpms/python3.7/commits/rename") | ||
|
||
|
||
def test_rename_git_diff_spec(): | ||
line = b"diff --git a/python3.7.spec b/python3.7.spec" | ||
new = ferrypick.rename(line, "python3.7", "python37") | ||
assert new == b"diff --git a/python37.spec b/python37.spec" | ||
|
||
|
||
def test_rename_git_diff_rpmlintrc(): | ||
line = b"+++ b/python3.rpmlintrc" | ||
new = ferrypick.rename(line, "python3", "python3.9") | ||
assert new == b"+++ b/python3.9.rpmlintrc" | ||
|
||
|
||
def test_rename_git_diff_random_occurrence(): | ||
line = b" # remember to update the python3-docs package as well" | ||
new = ferrypick.rename(line, "python3-docs", "python-docs") | ||
assert new == line | ||
|
||
|
||
def test_patch_real(): | ||
link = f"{U}/rpms/python3.9/c/a0928446.patch" | ||
original_name = "python3.9" | ||
current_name = "python3.8" | ||
expected = Path(__file__).parent / "a0928446.patch" | ||
with ferrypick.patch(link, original_name, current_name) as patch: | ||
assert Path(patch).read_text() == expected.read_text() |