[PATCH] Handle %define changes for autofetch
Martin Kolman
mkolman at redhat.com
Tue Aug 27 14:44:18 UTC 2013
If a package version variable specified with %define is changed,
autofetch all packages in Requires using the given version variable.
Signed-off-by: Martin Kolman <mkolman at redhat.com>
---
scripts/makeupdates | 87 +++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 71 insertions(+), 16 deletions(-)
diff --git a/scripts/makeupdates b/scripts/makeupdates
index 32643b9..b153dad 100755
--- a/scripts/makeupdates
+++ b/scripts/makeupdates
@@ -46,6 +46,12 @@ VERSION_EQUAL = "="
VERSION_MORE_OR_EQUAL = ">="
VERSION_LESS_OR_EQUAL = "<="
+VERSION_OP_MAP = {
+ "=": VERSION_EQUAL,
+ ">=": VERSION_MORE_OR_EQUAL,
+ "<=": VERSION_LESS_OR_EQUAL
+}
+
def getArchiveTag(configure, spec):
tag = ""
@@ -386,48 +392,96 @@ def createUpdatesImage(cwd, updates):
os.system("find . | cpio -c -o | gzip -9cv > %s/updates.img" % (cwd,))
sys.stdout.write("updates.img ready\n")
-def check_for_new_packages(tag, arch, added_rpms):
+def check_for_new_packages(tag, arch, added_rpms, specfile_path):
"""Download any new packages added to Requires and Defines
since the given tag, return list of RPM paths
"""
new_packages = {}
version_vars = {}
+ all_used_version_vars = {}
fedora_number = get_fedora_version()
+
+ Package = namedtuple("Package", "name version version_request req_tuple")
+
diff = doGitContentDiff(tag, ["anaconda.spec.in"])
new_requires = filter(lambda x: x.startswith("+Requires:"), diff)
new_defines = filter(lambda x: x.startswith("+%define"), diff)
+ with open(specfile_path, "rc") as f:
+ spec_content = f.readlines()
+ all_defines = filter(lambda x: x.startswith("%define"), spec_content)
+ all_requires = filter(lambda x: x.startswith("Requires:"), spec_content)
- # first parse defines, to get the version variables
-
- for define in new_defines:
+ # parse all defines, to get the version variables
+ for define in all_defines:
# second word & split the "ver" suffix
package = define.split()[1][:-3]
version = define.split()[2]
version_vars[package] = version
- # then parse requires and substitute version variables where needed
+ # parse all Requires and store lines referencing
+ # version variables
+ # ex.: Requires: langtable-data >= %{langtablever}
+ # will be stored as:
+ # langtable : [(langtable-data, VERSION_MORE_OR_EQUAL)]
+
+ for require in all_requires:
+ parts = require.split()
+ # we are interest only in Requires lines using
+ # version variables
+ if len(parts) >= 4 and parts[3].startswith('%'):
+ package_name = parts[1]
+ version_request = VERSION_OP_MAP.get(parts[2], None)
+ # drop the %{ prefix and ver} suffix
+ version_var = parts[3][2:-4]
+ # store (package_name, version_request) tuples for the given
+ # version variable
+
+ # single version variable might be used to set version of multiple
+ # package, see langtable for an example of such usage
+ if version_var in all_used_version_vars:
+ all_used_version_vars[version_var].append((package_name, version_request))
+ else:
+ all_used_version_vars[version_var] = [(package_name, version_request)]
- Package = namedtuple("Package", "name version version_request req_tuple")
+ # parse all new defines
+ for define in new_defines:
+ # second word & split the "ver" suffix
+ parts = define.split()
+ version_var = parts[1][:-3]
+ version = parts[2]
+ # if there are any packages in Requires using the version variable
+ # corresponding to the current %define, add a new package request
+ packages_using_this_define = all_used_version_vars.get(version_var, [])
+ # multiple requests might be using a single version variable
+ for package_name, version_request in packages_using_this_define:
+ if not version.count("-"):
+ version = "%s-1" % version
+ pkg_name = "%s-%s.fc%s.%s.rpm" % (package_name, version,
+ fedora_number, arch)
+ pkg_tuple = get_pkg_tuple(pkg_name)
+ req_tuple = get_req_tuple(pkg_tuple, version_request)
+ new_packages[package_name] = Package(package_name, version,
+ version_request, req_tuple)
+ # then parse requires and substitute version variables where needed
for req in new_requires:
parts = req.split()
if len(parts) < 2:
# must contain at least "+Requires:" and "some_package"
continue
package_name = parts[1]
+
+ # skip packages that were already added from new %defines
+ if package_name in new_packages:
+ continue
+
version_request = None
if len(parts) > 2:
# get the version request operator
version_operator = parts[2]
# at the moment only = (considered the default),
# >= and <= are supported
-
- if version_operator == ">=":
- version_request = VERSION_MORE_OR_EQUAL
- elif version_operator == "<=":
- version_request = VERSION_LESS_OR_EQUAL
- elif version_operator == "=":
- version_request = VERSION_EQUAL
+ version_request = VERSION_OP_MAP.get(version_operator, None)
version = parts.pop()
else:
version = ""
@@ -459,8 +513,9 @@ def check_for_new_packages(tag, arch, added_rpms):
new_packages[package_name] = Package(package_name, version,
version_request, req_tuple)
+ # report about new package requests
if new_packages:
- print("%d new packages found in Requires:" %
+ print("%d new packages found in Requires or updated %%defines for Requires:" %
len(new_packages))
for p in new_packages.values():
if p.version_request:
@@ -468,7 +523,7 @@ def check_for_new_packages(tag, arch, added_rpms):
else:
print(p.name)
else:
- print("no new Requires found")
+ print("no new Requires or updated %%defines for Requires found")
return []
# make sure the RPM cache folder exists
@@ -774,7 +829,7 @@ def main():
if args.fetch:
arch = args.fetch
- rpm_paths = check_for_new_packages(args.tag, arch, args.add_rpms)
+ rpm_paths = check_for_new_packages(args.tag, arch, args.add_rpms, spec)
args.add_rpms.extend(rpm_paths)
if args.add_rpms:
--
1.8.3.1
More information about the anaconda-patches
mailing list