diff options
Diffstat (limited to 'RepSys/rpmutil.py')
-rw-r--r-- | RepSys/rpmutil.py | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py new file mode 100644 index 0000000..3df9818 --- /dev/null +++ b/RepSys/rpmutil.py @@ -0,0 +1,369 @@ +#!/usr/bin/python +from RepSys import Error, config +from RepSys.svn import SVN +from RepSys.rpm import SRPM +from RepSys.log import specfile_svn2rpm +from RepSys.util import execcmd +import tempfile +import shutil +import glob +import sys +import os + +def get_spec(pkgdirurl, targetdir="."): + svn = SVN() + tmpdir = tempfile.mktemp() + try: + geturl = "/".join([pkgdirurl, "current", "SPECS"]) + svn.checkout("'%s'" % geturl, tmpdir) + speclist = glob.glob(os.path.join(tmpdir, "*.spec")) + if not speclist: + raise Error, "no spec files found" + spec = speclist[0] + shutil.copy(spec, targetdir) + finally: + if os.path.isdir(tmpdir): + shutil.rmtree(tmpdir) + +def get_srpm(pkgdirurl, + mode = "current", + targetdirs = None, + version = None, + release = None, + revision = None, + packager = "", + revname = 0, + svnlog = 0, + scripts = []): + svn = SVN() + tmpdir = tempfile.mktemp() + try: + if mode == "version": + geturl = os.path.join(pkgdirurl, "versions", + version, release) + elif mode == "pristine": + geturl = os.path.join(pkgdirurl, "pristine") + elif mode == "current" or mode == "revision": + geturl = os.path.join(pkgdirurl, "current") + else: + raise Error, "unsupported get_srpm mode: %s" % mode + svn.checkout(geturl, tmpdir, rev=revision) + srpmsdir = os.path.join(tmpdir, "SRPMS") + os.mkdir(srpmsdir) + specsdir = os.path.join(tmpdir, "SPECS") + speclist = glob.glob(os.path.join(specsdir, "*.spec")) + if not speclist: + raise Error, "no spec files found" + spec = speclist[0] + if svnlog: + specfile_svn2rpm(pkgdirurl, spec, revision) + revision = svn.revision(tmpdir) + for script in scripts: + status, output = execcmd(script, tmpdir, spec, str(revision), + noerror=1) + if status != 0: + raise Error, "script %s failed" % script + if packager: + packager = " --define 'packager %s'" % packager + execcmd("rpm -bs --nodeps --define '_topdir %s'%s %s" % + (tmpdir, packager, spec)) + if revname: + srpm = glob.glob(os.path.join(srpmsdir, "*.src.rpm"))[0] + srpmbase = os.path.basename(srpm) + os.rename(srpm, "%s/@%i:%s" % (srpmsdir, revision, srpmbase)) + srpm = glob.glob(os.path.join(srpmsdir, "*.src.rpm"))[0] + if not targetdirs: + targetdirs = (".",) + for targetdir in targetdirs: + execcmd("cp -f", srpm, targetdir) + os.unlink(srpm) + finally: + if os.path.isdir(tmpdir): + shutil.rmtree(tmpdir) + +def patch_spec(pkgdirurl, patchfile, log=""): + svn = SVN() + tmpdir = tempfile.mktemp() + try: + geturl = "/".join([pkgdirurl, "current", "SPECS"]) + svn.checkout(geturl, tmpdir) + speclist = glob.glob(os.path.join(tmpdir, "*.spec")) + if not speclist: + raise Error, "no spec files found" + spec = speclist[0] + status, output = execcmd("patch", spec, patchfile) + if status != 0: + raise Error, "can't apply patch:\n%s\n" % output + else: + svn.commit(tmpdir, log="") + finally: + if os.path.isdir(tmpdir): + shutil.rmtree(tmpdir) + +def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""): + srpm = SRPM(srpmfile) + if appendname: + pkgdirurl = "/".join([pkgdirurl, srpm.name]) + svn = SVN() + tmpdir = tempfile.mktemp() + try: + if srpm.epoch: + version = "%s:%s" % (srpm.epoch, srpm.version) + else: + version = srpm.version + versionurl = "/".join([pkgdirurl, "releases", version]) + releaseurl = "/".join([versionurl, srpm.release]) + ret = svn.mkdir(pkgdirurl, noerror=1, log="Created package directory") + if ret: + svn.checkout(pkgdirurl, tmpdir) + svn.mkdir(os.path.join(tmpdir, "releases")) + svn.mkdir(os.path.join(tmpdir, "releases", version)) + svn.mkdir(os.path.join(tmpdir, "current")) + svn.mkdir(os.path.join(tmpdir, "current", "SPECS")) + svn.mkdir(os.path.join(tmpdir, "current", "SOURCES")) + #svn.commit(tmpdir,log="Created package structure.") + version_exists = 1 + currentdir = os.path.join(tmpdir, "current") + else: + if svn.ls(releaseurl, noerror=1): + raise Error, "release already exists" + svn.checkout("/".join([pkgdirurl, "current"]), tmpdir) + svn.mkdir(versionurl, noerror=1, + log="Created directory for version %s." % version) + currentdir = tmpdir + + specsdir = os.path.join(currentdir, "SPECS") + sourcesdir = os.path.join(currentdir, "SOURCES") + + unpackdir = tempfile.mktemp() + os.mkdir(unpackdir) + try: + srpm.unpack(unpackdir) + + uspecsdir = os.path.join(unpackdir, "SPECS") + usourcesdir = os.path.join(unpackdir, "SOURCES") + + uspecsentries = os.listdir(uspecsdir) + usourcesentries = os.listdir(usourcesdir) + specsentries = os.listdir(specsdir) + sourcesentries = os.listdir(sourcesdir) + + # Remove old entries + for entry in [x for x in specsentries + if x not in uspecsentries]: + if entry == ".svn": + continue + entrypath = os.path.join(specsdir, entry) + os.unlink(entrypath) + svn.remove(entrypath) + for entry in [x for x in sourcesentries + if x not in usourcesentries]: + if entry == ".svn": + continue + entrypath = os.path.join(sourcesdir, entry) + os.unlink(entrypath) + svn.remove(entrypath) + + # Copy all files + execcmd("cp -rf", uspecsdir, currentdir) + execcmd("cp -rf", usourcesdir, currentdir) + + # Add new entries + for entry in [x for x in uspecsentries + if x not in specsentries]: + entrypath = os.path.join(specsdir, entry) + svn.add(entrypath) + for entry in [x for x in usourcesentries + if x not in sourcesentries]: + entrypath = os.path.join(sourcesdir, entry) + svn.add(entrypath) + finally: + if os.path.isdir(unpackdir): + shutil.rmtree(unpackdir) + + svn.commit(tmpdir, log=log) + finally: + if os.path.isdir(tmpdir): + shutil.rmtree(tmpdir) + + # Do revision and pristine tag copies + pristineurl = os.path.join(pkgdirurl, "pristine") + svn.remove(pristineurl, noerror=1, + log="Removing previous pristine/ directory.") + currenturl = os.path.join(pkgdirurl, "current") + svn.copy(currenturl, pristineurl, + log="Copying release %s-%s to pristine/ directory." % + (version, srpm.release)) + svn.copy(currenturl, releaseurl, + log="Copying release %s-%s to releases/ directory." % + (version, srpm.release)) + +def create_package(pkgdirurl, log="", verbose=0): + svn = SVN() + tmpdir = tempfile.mktemp() + try: + basename = os.path.basename(pkgdirurl) + if verbose: + print "Creating package directory...", + sys.stdout.flush() + ret = svn.mkdir(pkgdirurl, + log="Created package directory for '%s'." % basename) + if verbose: + print "done" + print "Checking it out...", + svn.checkout(pkgdirurl, tmpdir) + if verbose: + print "done" + print "Creating package structure...", + svn.mkdir(os.path.join(tmpdir, "current")) + svn.mkdir(os.path.join(tmpdir, "current", "SPECS")) + svn.mkdir(os.path.join(tmpdir, "current", "SOURCES")) + if verbose: + print "done" + print "Committing...", + svn.commit(tmpdir, + log="Created package structure for '%s'." % basename) + print "done" + finally: + if os.path.isdir(tmpdir): + shutil.rmtree(tmpdir) + +def mark_release(pkgdirurl, version, release, revision): + svn = SVN() + releasesurl = "/".join([pkgdirurl, "releases"]) + versionurl = "/".join([releasesurl, version]) + releaseurl = "/".join([versionurl, release]) + if svn.ls(releaseurl, noerror=1): + raise cncrep.Error, "release already exists" + svn.mkdir(releasesurl, noerror=1, + log="Created releases directory.") + svn.mkdir(versionurl, noerror=1, + log="Created directory for version %s." % version) + pristineurl = os.path.join(pkgdirurl, "pristine") + svn.remove(pristineurl, noerror=1, + log="Removing previous pristine/ directory.") + currenturl = os.path.join(pkgdirurl, "current") + svn.copy(currenturl, pristineurl, + log="Copying release %s-%s to pristine/ directory." % + (version, release)) + svn.copy(currenturl, releaseurl, rev=revision, + log="Copying release %s-%s to releases/ directory." % + (version, release)) + +def check_changed(url, all=0, show=0, verbose=0): + svn = SVN() + if all: + baseurl = url + packages = [] + if verbose: + print "Getting list of packages...", + sys.stdout.flush() + packages = [x[:-1] for x in svn.ls(baseurl)] + if verbose: + print "done" + if not packages: + raise Error, "couldn't get list of packages" + else: + baseurl, basename = os.path.split(url) + packages = [basename] + clean = [] + changed = [] + nopristine = [] + nocurrent = [] + for package in packages: + pkgdirurl = os.path.join(baseurl, package) + current = os.path.join(pkgdirurl, "current") + pristine = os.path.join(pkgdirurl, "pristine") + if verbose: + print "Checking package %s..." % package, + sys.stdout.flush() + if not svn.ls(current, noerror=1): + if verbose: + print "NO CURRENT" + nocurrent.append(package) + elif not svn.ls(pristine, noerror=1): + if verbose: + print "NO PRISTINE" + nopristine.append(package) + else: + diff = svn.diff(pristine, current) + if diff: + changed.append(package) + if verbose: + print "CHANGED" + if show: + print diff + else: + if verbose: + print "clean" + clean.append(package) + if verbose: + if not packages: + print "No packages found!" + elif all: + print "Total clean packages: %s" % len(clean) + print "Total CHANGED packages: %d" % len(changed) + print "Total NO CURRENT packages: %s" % len(nocurrent) + print "Total NO PRISTINE packages: %s" % len(nopristine) + return {"clean": clean, + "changed": changed, + "nocurrent": nocurrent, + "nopristine": nopristine} + +def checkout(url, path=None, revision=None): + svn = SVN() + current = os.path.join(url, "current") + if path is None: + _, path = os.path.split(url) + svn.checkout(current, path, rev=revision, show=1) + +def get_submit_info(path): + path = os.path.abspath(path) + + # First, look for SPECS and SOURCES directories. + found = False + while path != "/": + if os.path.isdir(path): + specsdir = os.path.join(path, "SPECS") + sourcesdir = os.path.join(path, "SOURCES") + if os.path.isdir(specsdir) and os.path.isdir(sourcesdir): + found = True + break + path = os.path.dirname(path) + if not found: + raise Error, "SPECS and/or SOURCES directories not found" + + # Then, check if this is really a subversion directory. + if not os.path.isdir(os.path.join(path, ".svn")): + raise Error, "subversion directory not found" + + svn = SVN() + + # Now, extract the package name. + for line in svn.info(path): + if line.startswith("URL: "): + url = line.split()[1] + toks = url.split("/") + if len(toks) < 2 or toks[-1] != "current": + raise Error, "unexpected URL received from 'svn info'" + name = toks[-2] + break + else: + raise Error, "URL tag not found in 'svn info' output" + + # Finally, guess revision. + max = -1 + files = [] + files.extend(glob.glob("%s/*" % specsdir)) + files.extend(glob.glob("%s/*" % sourcesdir)) + for line in svn.info(" ".join(files)): + if line.startswith("Revision: "): + rev = int(line.split()[1]) + if rev > max: + max = rev + if max == -1: + raise Error, "revision tag not found in 'svn info' output" + + return name, max + +# vim:et:ts=4:sw=4 |