def check_changed(pkgdirurl, all=0, show=0, verbose=0): svn = SVN() if all: baseurl = pkgdirurl 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(pkgdirurl) packages = [basename] clean = [] changed = [] nopristine = [] nocurrent = [] for package in packages: pkgdirurl = os.path.join(baseurl, package) current = layout.checkout_url(pkgdirurl) pristine = layout.checkout_url(pkgdirurl, pristine=True) 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 mark_release(pkgdirurl, version, release, revision): svn = SVN() releasesurl = layout.checkout_url(pkgdirurl, releases=True) versionurl = "/".join([releasesurl, version]) releaseurl = "/".join([versionurl, release]) currenturl = layout.checkout_url(pkgdirurl) if svn.ls(releaseurl, noerror=1): raise 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 = layout.checkout_url(pkgdirurl, pristine=True) svn.remove(pristineurl, noerror=1, log="Removing previous pristine/ directory.") svn.copy(currenturl, pristineurl, log="Copying release %s-%s to pristine/ directory." % (version, release)) markreleaselog = create_markrelease_log(version, release, revision) svn.copy(currenturl, releaseurl, rev=revision, log=markreleaselog)
def checkout(pkgdirurl, path=None, revision=None, branch=None, distro=None, spec=False): o_pkgdirurl = pkgdirurl pkgdirurl = layout.package_url(o_pkgdirurl, distro=distro) append = None if spec: append = "SPECS" current = layout.checkout_url(pkgdirurl, branch=branch, append_path=append) if path is None: path = layout.package_name(pkgdirurl) mirror.info(current, write=True) svn = SVN() svn.checkout(current, path, rev=revision, show=1) binrepo.download_binaries(path)
def svn_log(pkgdirurl, verbose=False, limit=None, revision=None): mirror.info(pkgdirurl) url = checkout_url(pkgdirurl) svncmd = config.get("global", "svn-command", "svn") args = [svncmd, "log", url] if verbose: args.append("-v") if limit: args.append("-l") args.append(limit) if revision: args.append("-r") args.append(revision) if os.isatty(sys.stdin.fileno()): args.append("| less") rawcmd = " ".join(args) execcmd(rawcmd, show=True)
def get_spec(pkgdirurl, targetdir=".", submit=False): svn = SVN() tmpdir = tempfile.mktemp() try: geturl = layout.checkout_url(pkgdirurl, append_path="SPECS") mirror.info(geturl) svn.export("'%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) name = os.path.basename(spec) path = os.path.join(targetdir, name) print "Wrote %s" % (name) finally: if os.path.isdir(tmpdir): shutil.rmtree(tmpdir)
def patch_spec(pkgdirurl, patchfile, log=""): #FIXME use get_spec svn = SVN() tmpdir = tempfile.mktemp() try: geturl = layout.checkout_url(pkgdirurl, append_path="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 parse_options(): parser = OptionParser(help=HELP) parser.defaults["revision"] = None parser.add_option("-t", dest="target", default=None) parser.add_option("-l", action="callback", callback=list_targets) parser.add_option("-r", dest="revision", type="string", nargs=1) parser.add_option("-s", dest="submithost", type="string", nargs=1, default=None) parser.add_option("-i", dest="sid", type="string", nargs=1, default=None) parser.add_option("-a", dest="atonce", action="store_true", default=False) parser.add_option("--distro", dest="distro", type="string", default=None) parser.add_option("--define", action="append", default=[]) opts, args = parser.parse_args() if not args: name, url, rev = get_submit_info(".") args = ["%s@%s" % (url, str(rev))] print "Submitting %s at revision %s" % (name, rev) print "URL: %s" % url if opts.revision is not None: # backwards compatibility with the old -r usage if len(args) == 1: args[0] = args[0] + "@" + opts.revision else: raise Error, "can't use -r REV with more than one package name" del opts.revision if len(args) == 2: # prevent from using the old <name> <rev> syntax try: rev = int(args[1]) except ValueError: # ok, it is a package name, let it pass pass else: raise Error, "the format <name> <revision> is deprecated, "\ "use <name>@<revision> instead" # expand group aliases expanded = [] for nameurl in args: expanded.extend(expand_group(nameurl)) if expanded != args: print "Submitting: %s" % " ".join(expanded) args = expanded # generate URLs for package names: opts.urls = [mirror.strip_username( layout.package_url(nameurl, distro=opts.distro, mirrored=False)) for nameurl in args] # find the revision if not specified: newurls = [] for url in opts.urls: if not "@" in url: print "Fetching revision..." courl = layout.checkout_url(url) log = SVN().log(courl, limit=1) if not log: raise Error, "can't find a revision for %s" % courl ci = log[0] print "URL:", url print "Commit:", print "%d | %s" % (ci.revision, ci.author), if ci.lines: line = " ".join(ci.lines).strip() if len(line) > 57: line = line[:57] + "..." print "| %s" % line, print url = url + "@" + str(ci.revision) newurls.append(url) opts.urls[:] = newurls # choose a target if not specified: if opts.target is None and opts.distro is None: target = layout.distro_branch(opts.urls[0]) or DEFAULT_TARGET print "Implicit target: %s" % target opts.target = target del opts.distro return opts
def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None, macros=[], exported=None): concat = config.get("log", "concat", "").split() revoffset = get_revision_offset() svn = SVN() pkgreleasesurl = layout.checkout_url(pkgdirurl, releases=True) pkgcurrenturl = layout.checkout_url(pkgdirurl) releaseslog = svn.log(pkgreleasesurl, noerror=1) currentlog = svn.log(pkgcurrenturl, limit=size, start=rev, end=revoffset) # sort releases by copyfrom-revision, so that markreleases for same # revisions won't look empty releasesdata = [] if releaseslog: for relentry in releaseslog[::-1]: try: (version, release, relrevision) = \ parse_markrelease_log(relentry) except InvalidEntryError: continue releasesdata.append((relrevision, -relentry.revision, relentry, version, release)) releasesdata.sort() # collect valid releases using the versions provided by the changes and # the packages prevrevision = 0 releases = [] for (relrevision, dummy, relentry, version, release) in releasesdata: if prevrevision == relrevision: # ignore older markrelease of the same revision, since they # will have no history continue entries = [entry for entry in currentlog if relrevision >= entry.revision and (prevrevision < entry.revision)] if not entries: #XXX probably a forced release, without commits in current/, # check if this is the right behavior sys.stderr.write("warning: skipping (possible) release " "%s-%s@%s, no commits since previous markrelease (r%r)\n" % (version, release, relrevision, prevrevision)) continue release = make_release(author=relentry.author, revision=relentry.revision, date=relentry.date, lines=relentry.lines, entries=entries, version=version, release=release) releases.append(release) prevrevision = relrevision # look for commits that have been not submitted (released) yet # this is done by getting all log entries newer (greater revision no.) # than releasesdata[-1] (in the case it exists) if releasesdata: latest_revision = releasesdata[-1][0] # the latest copied rev else: latest_revision = 0 notsubmitted = [entry for entry in currentlog if entry.revision > latest_revision] if notsubmitted: # if they are not submitted yet, what we have to do is to add # a release/version number from getrelease() version, release = getrelease(pkgdirurl, macros=macros, exported=exported) toprelease = make_release(entries=notsubmitted, released=False, version=version, release=release) releases.append(toprelease) data = dump_file(releases[::-1], currentlog=currentlog, template=template) return data
def get_srpm(pkgdirurl, mode = "current", targetdirs = None, version = None, release = None, revision = None, packager = "", revname = 0, svnlog = 0, scripts = [], submit = False, template = None, macros = [], verbose = 0, strict = False): svn = SVN() tmpdir = tempfile.mktemp() topdir = "--define '_topdir %s'" % tmpdir builddir = "--define '_builddir %s/%s'" % (tmpdir, "BUILD") rpmdir = "--define '_rpmdir %s/%s'" % (tmpdir, "RPMS") sourcedir = "--define '_sourcedir %s/%s'" % (tmpdir, "SOURCES") specdir = "--define '_specdir %s/%s'" % (tmpdir, "SPECS") srcrpmdir = "--define '_srcrpmdir %s/%s'" % (tmpdir, "SRPMS") patchdir = "--define '_patchdir %s/%s'" % (tmpdir, "SOURCES") try: if mode == "version": geturl = layout.checkout_url(pkgdirurl, version=version, release=release) elif mode == "pristine": geturl = layout.checkout_url(pkgdirurl, pristine=True) elif mode == "current" or mode == "revision": #FIXME we should handle revisions specified using @REV geturl = layout.checkout_url(pkgdirurl) else: raise Error, "unsupported get_srpm mode: %s" % mode strict = strict or config.getbool("submit", "strict-revision", False) if strict and not rev_touched_url(geturl, revision): #FIXME would be nice to have the revision number even when # revision is None raise Error, "the revision %s does not change anything "\ "inside %s" % (revision or "HEAD", geturl) mirror.info(geturl) svn.export(geturl, tmpdir, rev=revision) binrepo.download_binaries(tmpdir) srpmsdir = os.path.join(tmpdir, "SRPMS") os.mkdir(srpmsdir) specsdir = os.path.join(tmpdir, "SPECS") speclist = glob.glob(os.path.join(specsdir, "*.spec")) if config.getbool("srpm", "run-prep", False): makefile = os.path.join(tmpdir, "Makefile") if os.path.exists(makefile): execcmd("make", "-C", tmpdir, "srpm-prep") if not speclist: raise Error, "no spec files found" spec = speclist[0] if svnlog: submit = not not revision log.specfile_svn2rpm(pkgdirurl, spec, revision, submit=submit, template=template, macros=macros, exported=tmpdir) for script in scripts: #FIXME revision can be "None" 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 defs = rpm_macros_defs(macros) sourcecmd = config.get("helper", "rpmbuild", "rpmbuild") execcmd("%s -bs --nodeps %s %s %s %s %s %s %s %s %s %s" % (sourcecmd, topdir, builddir, rpmdir, sourcedir, specdir, srcrpmdir, patchdir, packager, spec, defs)) # copy the generated SRPMs to their target locations targetsrpms = [] urlrev = None if revname: urlrev = revision or layout.get_url_revision(geturl) if not targetdirs: targetdirs = (".",) srpms = glob.glob(os.path.join(srpmsdir, "*.src.rpm")) if not srpms: # something fishy happened raise Error, "no SRPMS were found at %s" % srpmsdir for srpm in srpms: name = os.path.basename(srpm) if revname: name = "@%s:%s" % (urlrev, name) for targetdir in targetdirs: newpath = os.path.join(targetdir, name) targetsrpms.append(newpath) if os.path.exists(newpath): # should we warn? os.unlink(newpath) shutil.copy(srpm, newpath) if verbose: sys.stderr.write("Wrote: %s\n" % newpath) return targetsrpms finally: if os.path.isdir(tmpdir): shutil.rmtree(tmpdir)
def put_srpm(srpmfile, markrelease=False, striplog=True, branch=None, baseurl=None, baseold=None, logmsg=None, rename=True): svn = SVN() srpm = SRPM(srpmfile) tmpdir = tempfile.mktemp() if baseurl: pkgurl = mirror._joinurl(baseurl, srpm.name) else: pkgurl = layout.package_url(srpm.name, distro=branch, mirrored=False) print "Importing package to %s" % pkgurl try: if srpm.epoch: version = "%s:%s" % (srpm.epoch, srpm.version) else: version = srpm.version versionurl = "/".join([pkgurl, "releases", version]) releaseurl = "/".join([versionurl, srpm.release]) currenturl = "/".join([pkgurl, "current"]) currentdir = os.path.join(tmpdir, "current") ret = svn.mkdir(pkgurl, noerror=1, log="Created package directory") if ret or not svn.ls(currenturl, noerror=1): svn.checkout(pkgurl, tmpdir) svn.mkdir(os.path.join(tmpdir, "releases")) svn.mkdir(currentdir) svn.mkdir(os.path.join(currentdir, "SPECS")) svn.mkdir(os.path.join(currentdir, "SOURCES")) #svn.commit(tmpdir,log="Created package structure.") version_exists = 1 else: raise Error, "package already exists or error creating package directory" 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) if binrepo.is_binary(entrypath): continue svn.add(entrypath) finally: if os.path.isdir(unpackdir): shutil.rmtree(unpackdir) specs = glob.glob(os.path.join(specsdir, "*.spec")) if not specs: raise Error, "no spec file found on %s" % specsdir if len(specs) > 1: raise Error, "more than one spec file found on %s" % specsdir specpath = specs[0] if rename: specfile = os.path.basename(specpath) specname = specfile[:-len(".spec")] if specname != srpm.name: newname = srpm.name + ".spec" newpath = os.path.join(specsdir, newname) sys.stderr.write("warning: renaming spec file to '%s' " "(use -n to disable it)\n" % (newname)) os.rename(specpath, newpath) try: svn.remove(specpath) except Error: # file not tracked svn.revert(specpath) svn.add(newpath) specpath = newpath if striplog: specpath = specpath fspec = open(specpath) spec, chlog = log.split_spec_changelog(fspec) fspec.close() fspec = open(specpath, "w") fspec.writelines(spec) fspec.close() chlog.seek(0, os.SEEK_END) if chlog.tell() != 0: chlog.seek(0) #FIXME move it to layout.py oldurl = baseold or config.get("log", "oldurl") if oldurl == '.' or oldurl.startswith('./'): pkgoldurl = os.path.join(pkgurl, oldurl) else: pkgoldurl = mirror._joinurl(oldurl, srpm.name) svn.mkdir(pkgoldurl, noerror=1, log="created old log directory for %s" % srpm.name) logtmp = tempfile.mktemp() try: svn.checkout(pkgoldurl, logtmp) miscpath = os.path.join(logtmp, "log") fmisc = open(miscpath, "w+") fmisc.writelines(chlog) fmisc.close() svn.add(miscpath) svn.commit(logtmp, log="imported old log for %s" % srpm.name) finally: if os.path.isdir(logtmp): shutil.rmtree(logtmp) binrepo.import_binaries(currentdir, srpm.name) svn.commit(tmpdir, log=logmsg or ("imported package %s" % srpm.name)) finally: if os.path.isdir(tmpdir): shutil.rmtree(tmpdir) # Do revision and pristine tag copies pristineurl = layout.checkout_url(pkgurl, pristine=True) svn.remove(pristineurl, noerror=1, log="Removing previous pristine/ directory.") currenturl = layout.checkout_url(pkgurl) svn.copy(currenturl, pristineurl, log="Copying release %s-%s to pristine/ directory." % (version, srpm.release)) if markrelease: svn.copy(currenturl, releaseurl, log="Copying release %s-%s to releases/ directory." % (version, srpm.release))