source: soft/build_system/build_system/repsys/tags/V1_6_14/RepSys/rpmutil.py @ 1

Last change on this file since 1 was 1, checked in by fasma, 12 years ago

Initial Import from Mandriva's soft revision 224062 and package revision 45733

File size: 14.7 KB
Line 
1#!/usr/bin/python
2from RepSys import Error, config, RepSysTree
3from RepSys.svn import SVN
4from RepSys.rpm import SRPM
5from RepSys.log import specfile_svn2rpm
6from RepSys.util import execcmd
7import tempfile
8import shutil
9import glob
10import sys
11import os
12
13def get_spec(pkgdirurl, targetdir=".", submit=False):
14    svn = SVN(baseurl=pkgdirurl)
15    tmpdir = tempfile.mktemp()
16    try:
17        geturl = "/".join([pkgdirurl, "current", "SPECS"])
18        svn.export("'%s'" % geturl, tmpdir)
19        speclist = glob.glob(os.path.join(tmpdir, "*.spec"))
20        if not speclist:
21            raise Error, "no spec files found"
22        spec = speclist[0]
23        shutil.copy(spec, targetdir)
24    finally:
25        if os.path.isdir(tmpdir):
26            shutil.rmtree(tmpdir)
27
28def rpm_macros_defs(macros):
29    defs = ("--define \"%s %s\"" % macro for macro in macros)
30    args = " ".join(defs)
31    return args
32
33def get_srpm(pkgdirurl,
34             mode = "current",
35             targetdirs = None,
36             version = None,
37             release = None,
38             revision = None,
39             packager = "",
40             revname = 0,
41             svnlog = 0,
42             scripts = [], 
43             submit = False,
44             template = None,
45             macros = [],
46             verbose = 0):
47    svn = SVN(baseurl=pkgdirurl)
48    tmpdir = tempfile.mktemp()
49    topdir = "--define '_topdir %s'" % tmpdir
50    builddir = "--define '_builddir %s/%s'" % (tmpdir, "BUILD")
51    rpmdir = "--define '_rpmdir %s/%s'" % (tmpdir, "RPMS")
52    sourcedir = "--define '_sourcedir %s/%s'" % (tmpdir, "SOURCES")
53    specdir = "--define '_specdir %s/%s'" % (tmpdir, "SPECS")
54    srcrpmdir = "--define '_srcrpmdir %s/%s'" % (tmpdir, "SRPMS")
55    patchdir = "--define '_patchdir %s/%s'" % (tmpdir, "SOURCES")
56    try:
57        if mode == "version":
58            geturl = os.path.join(pkgdirurl, "versions",
59                                  version, release)
60        elif mode == "pristine":
61            geturl = os.path.join(pkgdirurl, "pristine")
62        elif mode == "current" or mode == "revision":
63            geturl = os.path.join(pkgdirurl, "current")
64        else:
65            raise Error, "unsupported get_srpm mode: %s" % mode
66        svn.export(geturl, tmpdir, rev=revision)
67        srpmsdir = os.path.join(tmpdir, "SRPMS")
68        os.mkdir(srpmsdir)
69        specsdir = os.path.join(tmpdir, "SPECS")
70        speclist = glob.glob(os.path.join(specsdir, "*.spec"))
71        if not speclist:
72            raise Error, "no spec files found"
73        spec = speclist[0]
74        if svnlog:
75            submit = not not revision
76            specfile_svn2rpm(pkgdirurl, spec, revision, submit=submit,
77                    template=template, macros=macros)
78        revisionreal = svn.revision(pkgdirurl)
79        for script in scripts:
80            status, output = execcmd(script, tmpdir, spec, str(revision),
81                                     noerror=1)
82            if status != 0:
83                raise Error, "script %s failed" % script
84        if packager:
85            packager = " --define 'packager %s'" % packager
86
87        defs = rpm_macros_defs(macros)
88        execcmd("rpm -bs --nodeps %s %s %s %s %s %s %s %s %s %s" %
89            (topdir, builddir, rpmdir, sourcedir, specdir, 
90             srcrpmdir, patchdir, packager, spec, defs))
91
92        if revision and revisionreal:
93            srpm = glob.glob(os.path.join(srpmsdir, "*.src.rpm"))[0]
94            srpminfo = SRPM(srpm)
95            release = srpminfo.release
96            srpmbase = os.path.basename(srpm)
97            os.rename(srpm, "%s/@%s:%s" % (srpmsdir, revisionreal, srpmbase))
98        srpm = glob.glob(os.path.join(srpmsdir, "*.src.rpm"))[0]
99        if not targetdirs:
100            targetdirs = (".",)
101        targetsrpms = []
102        for targetdir in targetdirs:
103            targetsrpm = os.path.join(os.path.realpath(targetdir), 
104                    os.path.basename(srpm))
105            targetsrpms.append(targetsrpm)
106            if verbose:
107                sys.stderr.write("Wrote: %s\n" %  targetsrpm)
108            execcmd("cp -f", srpm, targetdir)
109        os.unlink(srpm)
110        return targetsrpms
111    finally:
112        if os.path.isdir(tmpdir):
113            shutil.rmtree(tmpdir)
114
115def patch_spec(pkgdirurl, patchfile, log=""):
116    svn = SVN(baseurl=pkgdirurl)
117    tmpdir = tempfile.mktemp()
118    try:
119        geturl = "/".join([pkgdirurl, "current", "SPECS"])
120        svn.checkout(geturl, tmpdir)
121        speclist = glob.glob(os.path.join(tmpdir, "*.spec"))
122        if not speclist:
123            raise Error, "no spec files found"
124        spec = speclist[0]
125        status, output = execcmd("patch", spec, patchfile)
126        if status != 0:
127            raise Error, "can't apply patch:\n%s\n" % output
128        else:
129            svn.commit(tmpdir, log="")
130    finally:
131        if os.path.isdir(tmpdir):
132            shutil.rmtree(tmpdir)
133
134def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""):
135    srpm = SRPM(srpmfile)
136    if appendname:
137        pkgdirurl = "/".join([pkgdirurl, srpm.name])
138    svn = SVN(baseurl=pkgdirurl)
139    tmpdir = tempfile.mktemp()
140    try:
141        if srpm.epoch:
142            version = "%s:%s" % (srpm.epoch, srpm.version)
143        else:
144            version = srpm.version
145        versionurl = "/".join([pkgdirurl, "releases", version])
146        releaseurl = "/".join([versionurl, srpm.release])
147        ret = svn.mkdir(pkgdirurl, noerror=1, log="Created package directory")
148        if ret:
149            svn.checkout(pkgdirurl, tmpdir)
150            svn.mkdir(os.path.join(tmpdir, "releases"))
151            svn.mkdir(os.path.join(tmpdir, "releases", version))
152            svn.mkdir(os.path.join(tmpdir, "current"))
153            svn.mkdir(os.path.join(tmpdir, "current", "SPECS"))
154            svn.mkdir(os.path.join(tmpdir, "current", "SOURCES"))
155            #svn.commit(tmpdir,log="Created package structure.")
156            version_exists = 1
157            currentdir = os.path.join(tmpdir, "current")
158        else:
159            if svn.ls(releaseurl, noerror=1):
160                raise Error, "release already exists"
161            svn.checkout("/".join([pkgdirurl, "current"]), tmpdir)
162            svn.mkdir(versionurl, noerror=1,
163                      log="Created directory for version %s." % version)
164            currentdir = tmpdir
165         
166        specsdir = os.path.join(currentdir, "SPECS")
167        sourcesdir = os.path.join(currentdir, "SOURCES")
168
169        unpackdir = tempfile.mktemp()
170        os.mkdir(unpackdir)
171        try:
172            srpm.unpack(unpackdir)
173
174            uspecsdir = os.path.join(unpackdir, "SPECS")
175            usourcesdir = os.path.join(unpackdir, "SOURCES")
176           
177            uspecsentries = os.listdir(uspecsdir)
178            usourcesentries = os.listdir(usourcesdir)
179            specsentries = os.listdir(specsdir)
180            sourcesentries = os.listdir(sourcesdir)
181
182            # Remove old entries
183            for entry in [x for x in specsentries
184                             if x not in uspecsentries]:
185                if entry == ".svn":
186                    continue
187                entrypath = os.path.join(specsdir, entry)
188                os.unlink(entrypath)
189                svn.remove(entrypath)
190            for entry in [x for x in sourcesentries
191                             if x not in usourcesentries]:
192                if entry == ".svn":
193                    continue
194                entrypath = os.path.join(sourcesdir, entry)
195                os.unlink(entrypath)
196                svn.remove(entrypath)
197
198            # Copy all files
199            execcmd("cp -rf", uspecsdir, currentdir)
200            execcmd("cp -rf", usourcesdir, currentdir)
201           
202            # Add new entries
203            for entry in [x for x in uspecsentries
204                             if x not in specsentries]:
205                entrypath = os.path.join(specsdir, entry)
206                svn.add(entrypath)
207            for entry in [x for x in usourcesentries
208                             if x not in sourcesentries]:
209                entrypath = os.path.join(sourcesdir, entry)
210                svn.add(entrypath)
211        finally:
212            if os.path.isdir(unpackdir):
213                shutil.rmtree(unpackdir)
214
215        svn.commit(tmpdir, log=log)
216    finally:
217        if os.path.isdir(tmpdir):
218            shutil.rmtree(tmpdir)
219
220    # Do revision and pristine tag copies
221    pristineurl = os.path.join(pkgdirurl, "pristine")
222    svn.remove(pristineurl, noerror=1,
223               log="Removing previous pristine/ directory.")
224    currenturl = os.path.join(pkgdirurl, "current")
225    svn.copy(currenturl, pristineurl,
226             log="Copying release %s-%s to pristine/ directory." %
227                 (version, srpm.release))
228    svn.copy(currenturl, releaseurl,
229             log="Copying release %s-%s to releases/ directory." %
230                 (version, srpm.release))
231
232def create_package(pkgdirurl, log="", verbose=0):
233    svn = SVN(baseurl=pkgdirurl)
234    tmpdir = tempfile.mktemp()
235    try:
236        basename = RepSysTree.pkgname(pkgdirurl)
237        if verbose:
238            print "Creating package directory...",
239        sys.stdout.flush()
240        ret = svn.mkdir(pkgdirurl,
241                        log="Created package directory for '%s'." % basename)
242        if verbose:
243            print "done"
244            print "Checking it out...",
245        svn.checkout(pkgdirurl, tmpdir)
246        if verbose:
247            print "done"
248            print "Creating package structure...",
249        svn.mkdir(os.path.join(tmpdir, "current"))
250        svn.mkdir(os.path.join(tmpdir, "current", "SPECS"))
251        svn.mkdir(os.path.join(tmpdir, "current", "SOURCES"))
252        if verbose:
253            print "done"
254            print "Committing...",
255        svn.commit(tmpdir,
256                   log="Created package structure for '%s'." % basename)
257        print "done"
258    finally:
259        if os.path.isdir(tmpdir):
260            shutil.rmtree(tmpdir)
261
262
263def create_markrelease_log(version, release, revision):
264    log = """%%repsys markrelease
265version: %s
266release: %s
267revision: %s
268
269%s""" % (version, release, revision, 
270        ("Copying %s-%s to releases/ directory." % (version, release)))
271    return log
272
273def mark_release(pkgdirurl, version, release, revision):
274    svn = SVN(baseurl=pkgdirurl)
275    releasesurl = "/".join([pkgdirurl, "releases"])
276    versionurl = "/".join([releasesurl, version])
277    releaseurl = "/".join([versionurl, release])
278    if svn.ls(releaseurl, noerror=1):
279        raise Error, "release already exists"
280    svn.mkdir(releasesurl, noerror=1,
281              log="Created releases directory.")
282    svn.mkdir(versionurl, noerror=1,
283              log="Created directory for version %s." % version)
284    pristineurl = os.path.join(pkgdirurl, "pristine")
285    svn.remove(pristineurl, noerror=1,
286               log="Removing previous pristine/ directory.")
287    currenturl = os.path.join(pkgdirurl, "current")
288    svn.copy(currenturl, pristineurl,
289             log="Copying release %s-%s to pristine/ directory." %
290                 (version, release))
291    markreleaselog = create_markrelease_log(version, release, revision)
292    svn.copy(currenturl, releaseurl, rev=revision,
293             log=markreleaselog)
294
295def check_changed(pkgdirurl, all=0, show=0, verbose=0):
296    svn = SVN(baseurl=pkgdirurl)
297    if all:
298        baseurl = pkgdirurl
299        packages = []
300        if verbose:
301            print "Getting list of packages...",
302            sys.stdout.flush()
303        packages = [x[:-1] for x in svn.ls(baseurl)]
304        if verbose:
305            print "done"
306        if not packages:
307            raise Error, "couldn't get list of packages"
308    else:
309        baseurl, basename = os.path.split(pkgdirurl)
310        packages = [basename]
311    clean = []
312    changed = []
313    nopristine = []
314    nocurrent = []
315    for package in packages:
316        pkgdirurl = os.path.join(baseurl, package)
317        current = os.path.join(pkgdirurl, "current")
318        pristine = os.path.join(pkgdirurl, "pristine")
319        if verbose:
320            print "Checking package %s..." % package,
321            sys.stdout.flush()
322        if not svn.ls(current, noerror=1):
323            if verbose:
324                print "NO CURRENT"
325            nocurrent.append(package)
326        elif not svn.ls(pristine, noerror=1):
327            if verbose:
328                print "NO PRISTINE"
329            nopristine.append(package)
330        else:
331            diff = svn.diff(pristine, current)
332            if diff:
333                changed.append(package)
334                if verbose:
335                    print "CHANGED"
336                if show:
337                    print diff
338            else:
339                if verbose:
340                    print "clean"
341                clean.append(package)
342    if verbose:
343        if not packages:
344            print "No packages found!"
345        elif all:
346            print "Total clean packages: %s" % len(clean)
347            print "Total CHANGED packages: %d" % len(changed)
348            print "Total NO CURRENT packages: %s" % len(nocurrent)
349            print "Total NO PRISTINE packages: %s" % len(nopristine)
350    return {"clean": clean,
351            "changed": changed,
352            "nocurrent": nocurrent,
353            "nopristine": nopristine}
354
355def checkout(pkgdirurl, path=None, revision=None):
356    svn = SVN(baseurl=pkgdirurl)
357    current = os.path.join(pkgdirurl, "current")
358    if path is None:
359        _, path = os.path.split(pkgdirurl)
360    svn.checkout(current, path, rev=revision, show=1)
361
362def get_submit_info(path):
363    path = os.path.abspath(path)
364
365    # First, look for SPECS and SOURCES directories.
366    found = False
367    while path != "/":
368        if os.path.isdir(path):
369            specsdir = os.path.join(path, "SPECS")
370            sourcesdir = os.path.join(path, "SOURCES")
371            if os.path.isdir(specsdir) and os.path.isdir(sourcesdir):
372                found = True
373                break
374        path = os.path.dirname(path)
375    if not found:
376        raise Error, "SPECS and/or SOURCES directories not found"
377
378    # Then, check if this is really a subversion directory.
379    if not os.path.isdir(os.path.join(path, ".svn")):
380        raise Error, "subversion directory not found"
381   
382    svn = SVN(baseurl=pkgdirurl)
383
384
385    # Now, extract the package name.
386    for line in svn.info(path):
387        if line.startswith("URL: "):
388            url = line.split()[1]
389            toks = url.split("/")
390            if len(toks) < 2 or toks[-1] != "current":
391                raise Error, "unexpected URL received from 'svn info'"
392            name = toks[-2]
393            break
394    else:
395        raise Error, "URL tag not found in 'svn info' output"
396
397    # Finally, guess revision.
398    max = -1
399    files = []
400    files.extend(glob.glob("%s/*" % specsdir))
401    files.extend(glob.glob("%s/*" % sourcesdir))
402    for line in svn.info(" ".join(files)):
403        if line.startswith("Revision: "):
404            rev = int(line.split()[1])
405            if rev > max:
406                max = rev
407    if max == -1:
408        raise Error, "revision tag not found in 'svn info' output"
409   
410    return name, max
411
412# vim:et:ts=4:sw=4
Note: See TracBrowser for help on using the repository browser.