import glob import os import re import rpm import sys ts = rpm.TransactionSet() packages = [] for arg in sys.argv[1:]: packages += glob.glob(arg) erlang_provides = {} erlang_requires = {} package_names = [] package_headers = {} ## ## Custom tweaks begins here ## # These packages should be marked as noarch package_noarch = [ "emacs-erlang", "emacs-erlang-el", "erlang-doc"] # These are additional Requires which cannot be picked up automatically (yet). # TODO these should be added automatically package_additional_requires = { "emacs-erlang": ["emacs-common-erlang = %{version}-%{release}", "emacs(bin) >= %{_emacs_version}" ], "emacs-erlang-el": ["emacs-erlang = %{version}-%{release}"], "erlang-dialyzer": ["graphviz"], "erlang-erl_interface": ["%{name}-erts%{?_isa} = %{version}-%{release}"], # This library (lksctp-tools) is dlopened so it can't be picked # up automatically by the RPM dependency checker "erlang-erts": ["lksctp-tools"], "erlang-gs": ["tk"], # Stores files/links in /usr/share/java so has to depend on jpackage-utils "erlang-ic": ["jpackage-utils"], # Stores files/links in /usr/share/java so has to depend on jpackage-utils "erlang-jinterface": ["%{name}-erts%{?_isa} = %{version}-%{release}", "jpackage-utils"], "erlang-wx": ["mesa-libGL", "mesa-libGLU"], } package_additional_buildrequires = { "emacs-erlang": ["emacs", "emacs-el"], "erlang-crypto": ["openssl-devel"], "erlang-diameter": ["ed"], # BEWARE. No fop for EPEL5, and only for x86/x86_64 in EPEL6, # so we cannot regenerate docs here. (Un)Fortunately we dropped # support for EPEL6 and older versions. # FIXME add bootstrap condition first. "erlang-doc": ["fop", "libxslt"], "erlang-erts": ["lksctp-tools-devel", "m4", "ncurses-devel", "zlib-devel"], "erlang-gs": ["tcl-devel", "tk-devel"], # in EPEL6 on arches different from %{ix86} x86_64 we have to # use java-devel-gcj, so technically this requirement makes it # impossible to build Java support there. (Un)Fortunately we # already dropped full support for EPEL6 and older versions. "erlang-ic": ["java-devel"], "erlang-jinterface": ["java-devel"], "erlang-odbc": ["unixODBC-devel"], } package_additional_obsoletes = { "erlang-erts": [ "erlang-appmon", "erlang-docbuilder", "erlang-inviso", "erlang-pman", "erlang-toolbar", "erlang-tv"], } ## ## Custom tweaks ends here ## # To match 'erlang(asn1ct_eval_ext:transform_to_EXTERNAL1994/1)' prog = re.compile("^erlang(.*:.*/\d+)") rpmmask = re.compile(".*\.rpm") # iterate over all rpms for package in sorted([p for p in packages if rpmmask.match(p)]): # A tricky part. We are processing packages, rebuilt with # %{__erlang_provides_requires}. Otherwise we won't get information # about imports/exports (until we learn how to parse Erlang BEAM file # headers with Python. fd = os.open(package, os.O_RDONLY) h = ts.hdrFromFdno(fd) os.close(fd) rpm_name = h[rpm.RPMTAG_NAME] # Let's calculate provides # We'll create dictionary to speedup future use # FIXME duplicate provides local_provides = [p for p in h[rpm.RPMTAG_PROVIDENAME] if prog.match(p)] erlang_provides.update({k: rpm_name for k in local_provides}) # Let's calculate requires erlang_requires.update({rpm_name: [r for r in h[rpm.RPMTAG_REQUIRENAME] if prog.match(r) and not r in local_provides]}) package_headers.update({rpm_name: h}) package_names.append(rpm_name) namemask = re.compile("^erlang-[a-zA-Z0-9_]*$") print "### BEGIN OF AUTOGENERATED LIST ###" print "" for name in package_names: h = package_headers[name] if name == "erlang-doc": # Additional ifdef just for this sub-package (see below) print "%if %{with doc}" if namemask.match(name): print "%%package %s" % name.replace("erlang-", "") else: print "%%package -n %s" % name print "Summary: %s" % h[rpm.RPMTAG_SUMMARY] print "Group: %s" % h[rpm.RPMTAG_GROUP] rawdeps = [erlang_provides.get(r, "Error: missing requires: %s" % r) for r in erlang_requires[name]] deps = set() dependency_add = deps.add [x for x in rawdeps if not (x in deps or dependency_add(x))] # Additional BuildRequires (if any): for br in package_additional_buildrequires.get(name, []): print "BuildRequires: %s" % br # Add basic autogenerated Requires: for r in sorted(deps): #Requires: %{name}-stdlib%{?_isa} = %{version}-%{release} print "Requires: %s%%{?_isa} = %%{version}-%%{release}" % r.replace("erlang-", "%{name}-") # Add custom additional Requires (if any): for r in package_additional_requires.get(name, []): print "Requires: %s" % r # Add custom additional Obsoletes (if any): for os in package_additional_obsoletes.get(name, []): print "Obsoletes: %s" % os if name in package_noarch: print "BuildArch: noarch" print "" if namemask.match(name): print "%%description %s" % name.replace("erlang-", "") else: print "%%description -n %s" % name print "%s" % h[rpm.RPMTAG_DESCRIPTION] if name == "erlang-doc": # Additional ifdef just for this sub-package (see above) print "%endif" print "" print "### END OF AUTOGENERATED LIST ###"