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