-- cgit v1.2.1 From 3c632697bd604933d3284acdc79eb3178ddd77ef Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 27 Sep 2006 13:45:38 +0000 Subject: merge 1.6.2b changes --- CHANGES | 6 ++++++ Makefile | 1 + RepSys/commands/submit.py | 6 +++++- RepSys/rpmutil.py | 4 ++++ create-srpm | 22 ++++++++++++++++++---- repsys.spec | 11 +++++++---- 6 files changed, 41 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index aa9e004..b7df556 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +* 1.6.2b +- make submit pass --define options to create-srpm script +- print error message when create-srpm fails +- make get_srpm return the srpms list +- add upload-srpm support in create-srpm + * 1.6.2a - moved revision-offset to [log] section and added a comment diff --git a/Makefile b/Makefile index 46ddead..1131888 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ RELEASE:=$(shell rpm -q --qf %{RELEASE} --specfile $(PACKAGE).spec) TAG := $(shell echo "V$(VERSION)_$(RELEASE)" | tr -- '-.' '__') FILES = ChangeLog Makefile MANIFEST.in PKG-INFO create-srpm getsrpm-mdk rebrand-mdk \ + {default,revno}.chlog \ repsys repsys.conf repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py # rules to build a test rpm diff --git a/RepSys/commands/submit.py b/RepSys/commands/submit.py index 6e9eb0f..380391a 100644 --- a/RepSys/commands/submit.py +++ b/RepSys/commands/submit.py @@ -39,6 +39,7 @@ def parse_options(): parser.add_option("-t", dest="target", default="Cooker") parser.add_option("-l", dest="list", action="store_true") parser.add_option("-r", dest="revision", type="string", nargs=1) + parser.add_option("--define", action="append") opts, args = parser.parse_args() if not args: name, rev = get_submit_info(".") @@ -63,7 +64,7 @@ def parse_options(): raise Error, "provide -l or a revision number" return opts -def submit(pkgdirurl, revision, target, list=0): +def submit(pkgdirurl, revision, target, list=0, define=[]): #if not NINZ: # raise Error, "you must have NINZ installed to use this command" type, rest = urllib.splittype(pkgdirurl) @@ -113,10 +114,13 @@ def submit(pkgdirurl, revision, target, list=0): createsrpm = get_helper("create-srpm") command = "ssh %s %s '%s' -r %s -t %s" % ( host, createsrpm, pkgdirurl, revision, target) + if define: + command += " " + " ".join([ "--define " + x for x in define ]) status, output = execcmd(command) if status == 0: print "Package submitted!" else: + sys.stderr.write(output) sys.exit(status) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 83d0051..9c0018a 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -90,9 +90,13 @@ def get_srpm(pkgdirurl, srpm = glob.glob(os.path.join(srpmsdir, "*.src.rpm"))[0] if not targetdirs: targetdirs = (".",) + targetsrpms = [] for targetdir in targetdirs: + targetsrpm = os.path.join(os.path.realpath(targetdir), os.path.basename(srpm)) + targetsrpms.append(targetsrpm) execcmd("cp -f", srpm, targetdir) os.unlink(srpm) + return targetsrpms finally: if os.path.isdir(tmpdir): shutil.rmtree(tmpdir) diff --git a/create-srpm b/create-srpm index 000afd2..ee98ccd 100755 --- a/create-srpm +++ b/create-srpm @@ -3,7 +3,7 @@ from RepSys import Error, config from RepSys.rpmutil import get_srpm from RepSys.cgiutil import get_targets -from RepSys.util import mapurl +from RepSys.util import mapurl, execcmd, get_helper import sys import os import pwd @@ -16,7 +16,7 @@ class CmdIface: return config.get("users", author) def submit_package(self, packageurl, packagerev, targetname, - dontmapurl_=0): + dontmapurl_=0, define=[]): pw = pwd.getpwuid(os.getuid()) username = pw[0] packager = config.get("users", username) or pw[4] @@ -46,13 +46,26 @@ class CmdIface: newurl = packageurl if not dontmapurl_: newurl = mapurl(packageurl) - get_srpm(newurl, + targetsrpms = get_srpm(newurl, revision=packagerev, targetdirs=target.target, packager=packager, revname=1, svnlog=1, scripts=target.scripts) + + uploadsrpm = config.get("helper", "upload-srpm", None) + if uploadsrpm: + upload_command = [ uploadsrpm ] + if define: + for x in define: + upload_command.append("--define") + upload_command.append(x) + upload_command.append(targetname) + upload_command.append(targetsrpms[0]) + status, output = execcmd(" ".join(upload_command)) + if status != 0: + raise CmdError, "Failed to upload %s:\n%s" % (targetsrpms[0], output) return 1 def submit_targets(self): @@ -69,6 +82,7 @@ def parse_options(): parser.add_option("-M", "--nomapping", action="store_true", dest="urlmap", default=False, help="disable url mapping") + parser.add_option("--define", action="append") opts, args = parser.parse_args() if not args: parser.error("you must supply a package url") @@ -78,7 +92,7 @@ def parse_options(): def main(): iface = CmdIface() opts, args = parse_options() - iface.submit_package(args[0], opts.revision, opts.target, opts.urlmap) + iface.submit_package(args[0], opts.revision, opts.target, opts.urlmap, opts.define) if __name__ == "__main__": diff --git a/repsys.spec b/repsys.spec index 6942f0b..e32d536 100644 --- a/repsys.spec +++ b/repsys.spec @@ -1,9 +1,9 @@ Name: repsys -Version: 1.6.2a -Release: 1mdk +Version: 1.6.2b +Release: %mkrel 1 Summary: Tools for Mandriva Linux repository access and management Group: Development/Other -Source: %{name}-%{repsys_version}.tar.bz2 +Source: %{name}-%{version}.tar.bz2 License: GPL URL: http://qa.mandriva.com/twiki/bin/view/Main/RepositorySystem Prefix: %{_prefix} @@ -18,7 +18,7 @@ Requires: python-cheetah Tools for Mandriva Linux repository access and management. %prep -%setup -q -n %{name}-%{repsys_version} +%setup -q %build python setup.py build @@ -44,6 +44,9 @@ rm -rf %{buildroot} %{_bindir}/getsrpm-mdk %{_datadir}/repsys/rebrand-mdk %{_datadir}/repsys/create-srpm +%{_datadir}/repsys/default.chlog +%{_datadir}/repsys/revno.chlog +%{py_sitedir}/RepSys # MAKE THE CHANGES IN CVS: NO PATCH OR SOURCE ALLOWED -- cgit v1.2.1 From e8aa9562d2805f7ca918a34388088efd7de04bde Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 27 Sep 2006 13:47:21 +0000 Subject: fix spacing --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1131888..72a553f 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ RELEASE:=$(shell rpm -q --qf %{RELEASE} --specfile $(PACKAGE).spec) TAG := $(shell echo "V$(VERSION)_$(RELEASE)" | tr -- '-.' '__') FILES = ChangeLog Makefile MANIFEST.in PKG-INFO create-srpm getsrpm-mdk rebrand-mdk \ - {default,revno}.chlog \ + {default,revno}.chlog \ repsys repsys.conf repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py # rules to build a test rpm -- cgit v1.2.1 From cc7a16b494f94683e7c5dc44f9ad38aed9b5aa3f Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 27 Sep 2006 13:48:37 +0000 Subject: 1.6.4 --- repsys | 2 +- repsys.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/repsys b/repsys index 958e7bd..44592c0 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.3a" +VERSION="1.6.4" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] diff --git a/repsys.spec b/repsys.spec index e32d536..06aec23 100644 --- a/repsys.spec +++ b/repsys.spec @@ -1,5 +1,5 @@ Name: repsys -Version: 1.6.2b +Version: 1.6.4 Release: %mkrel 1 Summary: Tools for Mandriva Linux repository access and management Group: Development/Other -- cgit v1.2.1 From 8e97dc246c1b0d09fac1c3d1813bdf4ee7b38d73 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 27 Sep 2006 13:51:27 +0000 Subject: add oldfashion.chlog in dist --- Makefile | 2 +- repsys.spec | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 72a553f..ed38a15 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ RELEASE:=$(shell rpm -q --qf %{RELEASE} --specfile $(PACKAGE).spec) TAG := $(shell echo "V$(VERSION)_$(RELEASE)" | tr -- '-.' '__') FILES = ChangeLog Makefile MANIFEST.in PKG-INFO create-srpm getsrpm-mdk rebrand-mdk \ - {default,revno}.chlog \ + {default,oldfashion,revno}.chlog \ repsys repsys.conf repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py # rules to build a test rpm diff --git a/repsys.spec b/repsys.spec index 06aec23..7b50d97 100644 --- a/repsys.spec +++ b/repsys.spec @@ -46,6 +46,7 @@ rm -rf %{buildroot} %{_datadir}/repsys/create-srpm %{_datadir}/repsys/default.chlog %{_datadir}/repsys/revno.chlog +%{_datadir}/repsys/oldfashion.chlog %{py_sitedir}/RepSys # MAKE THE CHANGES IN CVS: NO PATCH OR SOURCE ALLOWED -- cgit v1.2.1 From 9581f2057ad7f6fb6fbb2f372b28a088a258d60a Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Tue, 17 Oct 2006 13:27:25 +0000 Subject: - added Warly's patch to make log.py cope with packages which have no markrelease --- RepSys/log.py | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 0c49d12..feca06a 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -266,17 +266,18 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): # for the emergency bug fixer: the [].sort() is done using the # decorate-sort-undecorate pattern releases_data = [] - for relentry in releaseslog[::-1]: - try: - revinfo = parse_repsys_entry(relentry) - except InvalidEntryError: - continue - try: - release_number = int(revinfo["revision"]) - except (KeyError, ValueError): - raise Error, "Error parsing data from log entry from r%s" % \ - relentry.revision - releases_data.append((release_number, relentry, revinfo)) + if releaseslog: + for relentry in releaseslog[::-1]: + try: + revinfo = parse_repsys_entry(relentry) + except InvalidEntryError: + continue + try: + release_number = int(revinfo["revision"]) + except (KeyError, ValueError): + raise Error, "Error parsing data from log entry from r%s" % \ + relentry.revision + releases_data.append((release_number, relentry, revinfo)) releases_data.sort() for release_number, relentry, revinfo in releases_data: @@ -311,16 +312,17 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): # look for commits that have been not submited (released) yet # this is done by getting all log entries newer (revision larger) # than releaseslog[0] - latest_revision = releaseslog[0].revision - 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) - toprelease = make_release(entries=notsubmitted, released=False, - version=version, release=release) - releases.append(toprelease) + if releaseslog: + latest_revision = releaseslog[0].revision + 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) + toprelease = make_release(entries=notsubmitted, released=False, + version=version, release=release) + releases.append(toprelease) data = dump_file(releases[::-1], template=template) return data -- cgit v1.2.1 From 18c1b7be09a9a0f8e45ef940f3d657e49ebf58b1 Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Tue, 17 Oct 2006 13:29:35 +0000 Subject: - updated reference specfile --- repsys.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/repsys.spec b/repsys.spec index 7b50d97..d9786c0 100644 --- a/repsys.spec +++ b/repsys.spec @@ -1,5 +1,5 @@ Name: repsys -Version: 1.6.4 +Version: 1.6.5 Release: %mkrel 1 Summary: Tools for Mandriva Linux repository access and management Group: Development/Other @@ -52,6 +52,9 @@ rm -rf %{buildroot} # MAKE THE CHANGES IN CVS: NO PATCH OR SOURCE ALLOWED %changelog +* Tue Oct 17 2006 Andreas Hasenack 1.6.5-1mdk +- 1.6.5 + * Thu Feb 02 2006 Andreas Hasenack 1.6.0-1mdk - version 1.6.0, see CVS changelog -- cgit v1.2.1 From 9c22d93dcb61b96402e94a6396605de3a456247d Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Tue, 17 Oct 2006 13:32:30 +0000 Subject: - added upload-srpm to the sample repsys.conf file --- repsys.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/repsys.conf b/repsys.conf index 244189c..a720130 100644 --- a/repsys.conf +++ b/repsys.conf @@ -15,6 +15,7 @@ path = /usr/share/repsys/default.chlog [helper] create-srpm = /usr/share/repsys/create-srpm +upload-srpm = /usr/local/bin/youri.devel [users] andreas = Andreas Hasenack -- cgit v1.2.1 From 99a0f968aa6f0b0f5d21bf649c91d40067530b63 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 18 Oct 2006 14:12:12 +0000 Subject: use get_helper --- create-srpm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create-srpm b/create-srpm index ee98ccd..67f6f15 100755 --- a/create-srpm +++ b/create-srpm @@ -54,7 +54,7 @@ class CmdIface: svnlog=1, scripts=target.scripts) - uploadsrpm = config.get("helper", "upload-srpm", None) + uploadsrpm = get_helper("upload-srpm") if uploadsrpm: upload_command = [ uploadsrpm ] if define: -- cgit v1.2.1 From 28577e8c743a934806ebf8725fb9166eb0a7ec72 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 18 Oct 2006 14:50:44 +0000 Subject: use a different "submit " section per target in configuration file --- RepSys/cgiutil.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/RepSys/cgiutil.py b/RepSys/cgiutil.py index ebb65c9..6dda91e 100644 --- a/RepSys/cgiutil.py +++ b/RepSys/cgiutil.py @@ -2,6 +2,7 @@ from RepSys import Error, config from RepSys.svn import SVN import time +import re class CgiError(Error): pass @@ -19,24 +20,22 @@ def get_targets(): if not TARGETS: target = SubmitTarget() targetoptions = {} - for option, value in config.walk("submit"): - if targetoptions.has_key(option): - TARGETS.append(target) + submit_re = re.compile("^submit\s+(.+)$") + for section in config.sections(): + m = submit_re.match(section) + if m: target = SubmitTarget() - targetoptions = {} - targetoptions[option] = 1 - if option == "name": - target.name = value - elif option == "target": - target.target = value.split() - elif option == "allowed": - target.allowed = value.split() - elif option == "scripts": - target.scripts = value.split() - else: - raise Error, "unknown [submit] option %s" % option - if targetoptions: - TARGETS.append(target) + target.name = m.group(1) + for option, value in config.walk(section): + if option == "target": + target.target = value.split() + elif option == "allowed": + target.allowed = value.split() + elif option == "scripts": + target.scripts = value.split() + else: + raise Error, "unknown [%s] option %s" % (section, option) + TARGETS.append(target) return TARGETS # vim:et:ts=4:sw=4 -- cgit v1.2.1 From 4fa14621f56a2e73cde623723064fd229f5dd77a Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 18 Oct 2006 14:56:11 +0000 Subject: update repsys.conf for new submit syntax --- repsys.conf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/repsys.conf b/repsys.conf index a720130..cf4dd77 100644 --- a/repsys.conf +++ b/repsys.conf @@ -27,8 +27,7 @@ helio = Helio Chissini de Castro lmontel = Laurent Montel oden = Oden Eriksson -[submit] -name = Cooker +[submit Cooker] target = /export/home/repsys allowed = svn+ssh://svn.mandriva.com/svn/mdv/cooker scripts = /usr/share/repsys/rebrand-mdk -- cgit v1.2.1 From 1967a4afaa9b44e4d1c91cec2c6dc67f5d3df624 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 18 Oct 2006 14:56:54 +0000 Subject: 1.6.6 --- repsys | 2 +- repsys.spec | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/repsys b/repsys index 44592c0..192b99b 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.4" +VERSION="1.6.6" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] diff --git a/repsys.spec b/repsys.spec index d9786c0..28a0ff8 100644 --- a/repsys.spec +++ b/repsys.spec @@ -52,6 +52,9 @@ rm -rf %{buildroot} # MAKE THE CHANGES IN CVS: NO PATCH OR SOURCE ALLOWED %changelog +* Wed Oct 18 2006 Olivier Blin 1.6.5-1mdv2007.1 +- use a different "submit " section per target in configuration file + * Tue Oct 17 2006 Andreas Hasenack 1.6.5-1mdk - 1.6.5 -- cgit v1.2.1 From 9182803453b5d062878f2cb888d81117b856c583 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 18 Oct 2006 14:58:53 +0000 Subject: I really meant 1.6.6 --- repsys.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repsys.spec b/repsys.spec index 28a0ff8..900cc20 100644 --- a/repsys.spec +++ b/repsys.spec @@ -1,5 +1,5 @@ Name: repsys -Version: 1.6.5 +Version: 1.6.6 Release: %mkrel 1 Summary: Tools for Mandriva Linux repository access and management Group: Development/Other @@ -52,7 +52,7 @@ rm -rf %{buildroot} # MAKE THE CHANGES IN CVS: NO PATCH OR SOURCE ALLOWED %changelog -* Wed Oct 18 2006 Olivier Blin 1.6.5-1mdv2007.1 +* Wed Oct 18 2006 Olivier Blin 1.6.6-1mdv2007.1 - use a different "submit " section per target in configuration file * Tue Oct 17 2006 Andreas Hasenack 1.6.5-1mdk -- cgit v1.2.1 From f4e84db35fec26c19b15bc163c139d183e7151a6 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 18 Oct 2006 17:32:37 +0000 Subject: - removed unnecessary parsing of the log entries --- RepSys/log.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index feca06a..ea5c798 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -281,11 +281,6 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): releases_data.sort() for release_number, relentry, revinfo in releases_data: - try: - revinfo = parse_repsys_entry(relentry) - except InvalidEntryError: - continue - try: release_revision = int(revinfo["revision"]) except (ValueError, KeyError): -- cgit v1.2.1 From 873ecb640b59a97b4d2ec1b00c2d2413f28d9475 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Thu, 19 Oct 2006 12:10:16 +0000 Subject: make get_srpm display the extracted .src.rpm (path + filename) (initially from pixel, frontport from V1_5_X) --- RepSys/rpmutil.py | 1 + 1 file changed, 1 insertion(+) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 9c0018a..e35639d 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -94,6 +94,7 @@ def get_srpm(pkgdirurl, for targetdir in targetdirs: targetsrpm = os.path.join(os.path.realpath(targetdir), os.path.basename(srpm)) targetsrpms.append(targetsrpm) + sys.stderr.write("Wrote: %s\n" % targetsrpm) execcmd("cp -f", srpm, targetdir) os.unlink(srpm) return targetsrpms -- cgit v1.2.1 From 0b137c7f5d5141717297e8e063b820f35de64eca Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 19 Oct 2006 16:42:41 +0000 Subject: - fixed bug introducted in r65890, in which it was ignoring unreleased revisions when the package had no releases. --- RepSys/log.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index ea5c798..931ba5d 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -306,18 +306,20 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): # look for commits that have been not submited (released) yet # this is done by getting all log entries newer (revision larger) - # than releaseslog[0] + # than releaseslog[0] (in the case it exists) if releaseslog: latest_revision = releaseslog[0].revision - 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) - toprelease = make_release(entries=notsubmitted, released=False, - version=version, release=release) - releases.append(toprelease) + 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) + toprelease = make_release(entries=notsubmitted, released=False, + version=version, release=release) + releases.append(toprelease) data = dump_file(releases[::-1], template=template) return data -- cgit v1.2.1 From f3561ea58ec845e932d4cbfe68fa4497aad1c10b Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Thu, 19 Oct 2006 16:45:27 +0000 Subject: updated default urls --- repsys.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repsys.conf b/repsys.conf index cf4dd77..b823ac3 100644 --- a/repsys.conf +++ b/repsys.conf @@ -1,10 +1,10 @@ [global] verbose = no -default_parent = svn+ssh://svn.mandriva.com/svn/mdv/cooker +default_parent = svn+ssh://svn.mandriva.com/svn/packages/cooker url-map = svn\+ssh://svn\.mandriva\.com/(.*) file:///\1 [log] -oldurl = svn+ssh://svn.mandriva.com/svn/mdv/misc +oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc # controls up to which revision the rpm changelog # will be constructed (default zero, i.e., oldest # commit) -- cgit v1.2.1 From a53a4246dc50e7d676ef65f0250088ba1f0ce078 Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Thu, 19 Oct 2006 17:41:29 +0000 Subject: updated default urls (missed one entry) --- repsys.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys.conf b/repsys.conf index b823ac3..783a2e0 100644 --- a/repsys.conf +++ b/repsys.conf @@ -29,5 +29,5 @@ oden = Oden Eriksson [submit Cooker] target = /export/home/repsys -allowed = svn+ssh://svn.mandriva.com/svn/mdv/cooker +allowed = svn+ssh://svn.mandriva.com/svn/packages/cooker scripts = /usr/share/repsys/rebrand-mdk -- cgit v1.2.1 From f1059f752f5dc34bc08a1bbd7a2731105a02cc8d Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 19 Oct 2006 21:32:34 +0000 Subject: - added another format for the changelog data, so that it can be used by templates for changelogs compatible with repsys 1.5 --- RepSys/log.py | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 931ba5d..dde2ad0 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -161,10 +161,38 @@ def group_releases_by_author(releases): release.revision = first.revisions[0].revision return releases - + + +def group_revisions_by_author(currentlog): + revisions = [] + last_author = None + for entry in currentlog: + revision = _Revision() + revision.lines = format_lines(entry.lines) + revision.raw_date = entry.date + revision.date = parse_raw_date(entry.date) + revision.revision = entry.revision + if entry.author == last_author: + revisions[-1].revisions.append(revision) + else: + author = _Author() + author.name, author.email = get_author_name(entry.author) + author.revisions = [revision] + revisions.append(author) + last_author = entry.author + return revisions + emailpat = re.compile("(?P.*?)\s*<(?P.*?)>") +def get_author_name(author): + found = emailpat.match(config.get("users", author, author)) + name = ((found and found.group("name")) or author) + email = ((found and found.group("email")) or author) + return name, email + +def parse_raw_date(rawdate): + return time.strftime("%a %b %d %Y", rawdate) def make_release(author=None, revision=None, date=None, lines=None, entries=[], released=True, version=None, release=None): @@ -176,27 +204,23 @@ def make_release(author=None, revision=None, date=None, lines=None, rel.revision = revision rel.version = version rel.release = release - rel.date = (date and time.strftime("%a %b %d %Y", date)) or None + rel.date = (date and parse_raw_date(date)) or None rel.lines = lines rel.released = released for entry in entries: revision = _Revision() revision.revision = entry.revision revision.lines = format_lines(entry.lines) - revision.date = time.strftime("%a %b %d %Y", entry.date) + revision.date = parse_raw_date(entry.date) revision.raw_date = entry.date revision.author = entry.author - found = emailpat.match(config.get("users", entry.author, entry.author)) - revision.author_name = ((found and found.group("name")) or - entry.author) - revision.author_email = ((found and found.group("email")) or - entry.author) + (revision.author_name, revision.author_email) = \ + get_author_name(entry.author) rel.revisions.append(revision) return rel -def dump_file(releases, template=None): - +def dump_file(releases, currentlog=None, template=None): templpath = template or config.get("template", "path", None) params = {} if templpath is None or not os.path.exists(templpath): @@ -206,8 +230,10 @@ def dump_file(releases, template=None): else: params["file"] = templpath releases_author = group_releases_by_author(releases) + revisions_author = group_revisions_by_author(currentlog) params["searchList"] = [{"releases_by_author" : releases_author, - "releases" : releases}] + "releases" : releases, + "revisions_by_author": revisions_author}] t = Template(**params) return repr(t) @@ -321,7 +347,7 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): version=version, release=release) releases.append(toprelease) - data = dump_file(releases[::-1], template=template) + data = dump_file(releases[::-1], currentlog=currentlog, template=template) return data -- cgit v1.2.1 From 5b7a9a57193f550a4fed126f485adc36540e527c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 19 Oct 2006 21:35:09 +0000 Subject: - added another changelog template, it copies the changelog format from repsys 1.5 --- compatv15.chlog | 13 +++++++++++++ setup.py | 1 + 2 files changed, 14 insertions(+) create mode 100644 compatv15.chlog diff --git a/compatv15.chlog b/compatv15.chlog new file mode 100644 index 0000000..3373a19 --- /dev/null +++ b/compatv15.chlog @@ -0,0 +1,13 @@ +## Sample Changelog template +## +#import time +#for $author in $revisions_by_author +* $author.revisions[0].date $author.name <$author.email> ++ ${time.strftime("%Y-%m-%d %H:%M:%S", author.revisions[0].raw_date)} ($author.revisions[0].revision) + #for $rev in $author.revisions + #for $line in $rev.lines +$line + #end for + #end for + +#end for diff --git a/setup.py b/setup.py index 86ffd94..272ec84 100755 --- a/setup.py +++ b/setup.py @@ -25,6 +25,7 @@ setup(name="repsys", ["default.chlog", "revno.chlog", "oldfashion.chlog", + "compatv15.chlog", "create-srpm", "rebrand-mdk"]), ("/etc/", ["repsys.conf"])] -- cgit v1.2.1 From dad24be156b4bce751224cda8609bb0229c00c39 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 20 Oct 2006 15:47:57 +0000 Subject: - SVN.log now contains information about the changed paths --- RepSys/svn.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/RepSys/svn.py b/RepSys/svn.py index e83b072..bc565b0 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -11,6 +11,7 @@ class SVNLogEntry: self.revision = revision self.author = author self.date = date + self.changed = [] self.lines = [] def __cmp__(self, other): @@ -248,7 +249,7 @@ class SVN: return None def log(self, url, start=None, end=0, limit=None, **kwargs): - cmd = ["log", url] + cmd = ["log", "-v", url] if start is not None or end != 0: if start is not None and type(start) is not type(0): try: @@ -273,17 +274,32 @@ class SVN: return None revheader = re.compile("^r(?P[0-9]+) \| (?P[^\|]+) \| (?P[^\|]+) \| (?P[0-9]+) (?:line|lines)$") + changedpat = re.compile(r"^\s+(?P[^\s]+) (?P[^\s]+)(?: \([^\s]+ (?P[^:]+)(?:\:(?P[0-9]+))?\))?$") logseparator = "-"*72 linesleft = 0 entry = None log = [] - emptyline = 0 + appendchanged = 0 + changedheader = 0 for line in output.splitlines(): - if emptyline: - emptyline = 0 - continue line = line.rstrip() - if linesleft == 0: + if not line: + appendchanged = 0 + if changedheader: + appendchanged = 1 + changedheader = 0 + elif appendchanged: + m = changedpat.match(line) + if m: + changed = m.groupdict().copy() + from_rev = changed.get("from_rev") + if from_rev is not None: + try: + changed["from_rev"] = int(from_rev) + except (ValueError, TypeError): + raise Error, "invalid revision number in svn log" + entry.changed.append(changed) + elif linesleft == 0: if line != logseparator: m = revheader.match(line) if m: @@ -294,7 +310,7 @@ class SVN: entry = SVNLogEntry(int(m.group("revision")), m.group("author"), timetuple) log.append(entry) - emptyline = 1 + changedheader = 1 else: entry.lines.append(line) linesleft -= 1 -- cgit v1.2.1 From f36eb3974bb8b0eafe71aee733a27d5c5836e457 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 20 Oct 2006 21:55:31 +0000 Subject: - changed repsys to use copy-from svn metadata to generate log messages --- RepSys/log.py | 85 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index dde2ad0..2f058fc 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -274,6 +274,27 @@ def get_revision_offset(): "file(s).") return revoffset or 0 +oldmsgpat = re.compile( + r"Copying release (?P[^\s]+) to (?P[^\s]+) directory\.") + +def parse_markrelease_log(relentry): + if not ((relentry.lines and oldmsgpat.match(relentry.lines[0]) \ + or parse_repsys_entry(relentry))): + raise InvalidEntryError + from_rev = None + path = None + for changed in relentry.changed: + if changed["action"] == "A" and changed["from_rev"]: + from_rev = changed["from_rev"] + path = changed["path"] + break + else: + raise InvalidEntryError + # get the version and release from the names in the path, do not relay + # on log messages + version, release = path.rsplit(os.path.sep, 3)[-2:] + return version, release, from_rev + def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): concat = config.get("log", "concat", "").split() @@ -284,52 +305,46 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): releaseslog = svn.log(pkgreleasesurl, noerror=1) currentlog = svn.log(pkgcurrenturl, limit=size, start=rev, end=revoffset) - lastauthor = None - previous_revision = 0 - currelease = None - releases = [] - # for the emergency bug fixer: the [].sort() is done using the - # decorate-sort-undecorate pattern - releases_data = [] - if releaseslog: - for relentry in releaseslog[::-1]: - try: - revinfo = parse_repsys_entry(relentry) - except InvalidEntryError: - continue - try: - release_number = int(revinfo["revision"]) - except (KeyError, ValueError): - raise Error, "Error parsing data from log entry from r%s" % \ - relentry.revision - releases_data.append((release_number, relentry, revinfo)) - releases_data.sort() - - for release_number, relentry, revinfo in releases_data: + # sort releases by copyfrom-revision, so that markreleases for same + # revisions won't be look empty + releasesdata = [] + for relentry in releaseslog[::-1]: try: - release_revision = int(revinfo["revision"]) - except (ValueError, KeyError): - raise Error, "Error parsing data from log entry from r%s" % \ - relentry.revision - - # get entries newer than 'previous' and older than 'relentry' + (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 history + continue entries = [entry for entry in currentlog - if release_revision >= entry.revision and - (previous_revision < entry.revision)] + 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 and if some release is - # not being lost. + # 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=revinfo["version"], release=revinfo["release"]) + version=version, release=release) releases.append(release) - previous_revision = release_revision - + prevrevision = relrevision + # look for commits that have been not submited (released) yet # this is done by getting all log entries newer (revision larger) # than releaseslog[0] (in the case it exists) -- cgit v1.2.1 From 47253e1456e038e9d155655f767cf05b608f69d6 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 20 Oct 2006 21:58:28 +0000 Subject: - fixed small bug in the svn log parser in which it was getting more lines than the entry had. --- RepSys/svn.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/RepSys/svn.py b/RepSys/svn.py index bc565b0..1483a02 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -283,12 +283,13 @@ class SVN: changedheader = 0 for line in output.splitlines(): line = line.rstrip() - if not line: - appendchanged = 0 if changedheader: appendchanged = 1 changedheader = 0 elif appendchanged: + if not line: + appendchanged = 0 + continue m = changedpat.match(line) if m: changed = m.groupdict().copy() -- cgit v1.2.1 From 19b75603da4fb275fee76ae9eb765ab6ba16f463 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 20 Oct 2006 22:04:08 +0000 Subject: - fixed regression from the bug of package without releases/ --- RepSys/log.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 2f058fc..62a290d 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -309,14 +309,15 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): # sort releases by copyfrom-revision, so that markreleases for same # revisions won't be look empty releasesdata = [] - 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() + 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 -- cgit v1.2.1 From e6afb8fdb59e4d2754cfc9db8cc3834d6e6411dc Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 20 Oct 2006 22:07:11 +0000 Subject: - changed version to 1.6.7 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 192b99b..c19bfbc 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.6" +VERSION="1.6.7" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 29fb68e4a59dd18bb84e2bed46949f245f9b0327 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 23 Oct 2006 13:32:21 +0000 Subject: - fixed the problem of trailling slashes in package urls --- RepSys/__init__.py | 19 +++++++++++++++++++ RepSys/log.py | 6 +++--- RepSys/rpmutil.py | 4 ++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/RepSys/__init__.py b/RepSys/__init__.py index c371e7a..c394746 100644 --- a/RepSys/__init__.py +++ b/RepSys/__init__.py @@ -1,9 +1,28 @@ #!/usr/bin/python +import re +import os import ConfigParser + config = ConfigParser.Config() del ConfigParser class Error(Exception): pass +class RepSysTree: + """ + This class just hold methods that abstract all the not-so-explicit + rules about the directory structure of a repsys repository. + """ + def fixpath(cls, url): + return re.sub("/+$", "", url) + fixpath = classmethod(fixpath) + + def pkgname(cls, pkgdirurl): + # we must remove trailling slashes in the package path because + # os.path.basename could return "" from URLs ending with "/" + fixedurl = cls.fixpath(pkgdirurl) + return os.path.basename(fixedurl) + pkgname = classmethod(pkgname) + # vim:et:ts=4:sw=4 diff --git a/RepSys/log.py b/RepSys/log.py index 62a290d..cf913f8 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -1,5 +1,5 @@ #!/usr/bin/python -from RepSys import Error, config +from RepSys import Error, config, RepSysTree from RepSys.svn import SVN from RepSys.util import execcmd @@ -52,7 +52,7 @@ def getrelease(pkgdirurl, rev=None): svn = SVN(baseurl=pkgdirurl) tmpdir = tempfile.mktemp() try: - pkgname = os.path.basename(pkgdirurl) + pkgname = RepSysTree.pkgname(pkgdirurl) pkgcurrenturl = os.path.join(pkgdirurl, "current") specurl = os.path.join(pkgcurrenturl, "SPECS") if svn.ls(specurl, noerror=1): @@ -394,7 +394,7 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, svn = SVN(baseurl=pkgdirurl) tmpdir = tempfile.mktemp() try: - pkgname = os.path.basename(pkgdirurl) + pkgname = RepSysTree.pkgname(pkgdirurl) pkgoldurl = os.path.join(oldurl, pkgname) if svn.ls(pkgoldurl, noerror=1): svn.export(pkgoldurl, tmpdir, rev=rev) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index e35639d..ac54046 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -1,5 +1,5 @@ #!/usr/bin/python -from RepSys import Error, config +from RepSys import Error, config, RepSysTree from RepSys.svn import SVN from RepSys.rpm import SRPM from RepSys.log import specfile_svn2rpm @@ -223,7 +223,7 @@ def create_package(pkgdirurl, log="", verbose=0): svn = SVN(baseurl=pkgdirurl) tmpdir = tempfile.mktemp() try: - basename = os.path.basename(pkgdirurl) + basename = RepSysTree.pkgname(pkgdirurl) if verbose: print "Creating package directory...", sys.stdout.flush() -- cgit v1.2.1 From 18fbc3bebe823b3d1b79e042dda4521782dec44d Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 31 Oct 2006 13:52:10 +0000 Subject: - added small lstrip to handle log messages beginning with spaces --- RepSys/log.py | 1 + 1 file changed, 1 insertion(+) diff --git a/RepSys/log.py b/RepSys/log.py index cf913f8..5c29876 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -104,6 +104,7 @@ def format_lines(lines): entrylines = [] perexpr = re.compile(r"([^%])%([^%])") for line in lines: + line = line.lstrip() if line: line = perexpr.sub("\\1%%\\2", line) if first: -- cgit v1.2.1 From 3e7445ccaac74a97c2e32f4cb07eff1cb9829c36 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 31 Oct 2006 14:19:08 +0000 Subject: - commented out "Status: not releases" from default template --- default.chlog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.chlog b/default.chlog index 4b767cf..00b4784 100644 --- a/default.chlog +++ b/default.chlog @@ -4,7 +4,7 @@ * $rel.date $rel.author_name <$rel.author_email> $rel.version-$rel.release + Revision: $rel.revision #if not $rel.released -+ Status: not released +##+ Status: not released #end if #for $rev in $rel.release_revisions #for $line in $rev.lines -- cgit v1.2.1 From cc310ea0eda3a0b6e80a16c3e812617ea165b170 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 1 Nov 2006 03:53:00 +0000 Subject: - make create-srpm handle exceptions intended to be handled, so that we don't receive the ugly traceback when upload-srpm fails --- create-srpm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/create-srpm b/create-srpm index 67f6f15..b8004a2 100755 --- a/create-srpm +++ b/create-srpm @@ -63,7 +63,8 @@ class CmdIface: upload_command.append(x) upload_command.append(targetname) upload_command.append(targetsrpms[0]) - status, output = execcmd(" ".join(upload_command)) + status, output = execcmd(" ".join(upload_command), + noerror=1) if status != 0: raise CmdError, "Failed to upload %s:\n%s" % (targetsrpms[0], output) return 1 @@ -92,7 +93,11 @@ def parse_options(): def main(): iface = CmdIface() opts, args = parse_options() - iface.submit_package(args[0], opts.revision, opts.target, opts.urlmap, opts.define) + try: + iface.submit_package(args[0], opts.revision, opts.target, opts.urlmap, opts.define) + except Error, e: + sys.stderr.write("error: %s\n" % str(e)) + sys.exit(1) if __name__ == "__main__": -- cgit v1.2.1 From 1493d3f9467e818ce0b7131d74b1f4258f8bb221 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Sun, 12 Nov 2006 11:25:43 +0000 Subject: always unlink the src.rpm after running the upload command --- create-srpm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/create-srpm b/create-srpm index b8004a2..fc235bf 100755 --- a/create-srpm +++ b/create-srpm @@ -65,8 +65,9 @@ class CmdIface: upload_command.append(targetsrpms[0]) status, output = execcmd(" ".join(upload_command), noerror=1) + os.unlink(targetsrpms[0]) if status != 0: - raise CmdError, "Failed to upload %s:\n%s" % (targetsrpms[0], output) + raise CmdError, "Failed to upload %s:\n%s" % (packageurl, output) return 1 def submit_targets(self): -- cgit v1.2.1 From c812b801c2f07af369babc6d52056d3604b7292b Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Sun, 12 Nov 2006 13:24:18 +0000 Subject: add compatv15.chlog in dist --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ed38a15..e1aa91b 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ RELEASE:=$(shell rpm -q --qf %{RELEASE} --specfile $(PACKAGE).spec) TAG := $(shell echo "V$(VERSION)_$(RELEASE)" | tr -- '-.' '__') FILES = ChangeLog Makefile MANIFEST.in PKG-INFO create-srpm getsrpm-mdk rebrand-mdk \ - {default,oldfashion,revno}.chlog \ + {compatv15,default,oldfashion,revno}.chlog \ repsys repsys.conf repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py # rules to build a test rpm -- cgit v1.2.1 From c0c7e58a098064358280d637ef328ed7a859a096 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Sun, 12 Nov 2006 13:24:26 +0000 Subject: bump release --- repsys.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys.spec b/repsys.spec index 900cc20..1f6f189 100644 --- a/repsys.spec +++ b/repsys.spec @@ -1,5 +1,5 @@ Name: repsys -Version: 1.6.6 +Version: 1.6.8 Release: %mkrel 1 Summary: Tools for Mandriva Linux repository access and management Group: Development/Other -- cgit v1.2.1 From 7405ba4000a438fd49873100dfefaef53d0ea68e Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 13 Nov 2006 03:10:46 +0000 Subject: Removed duplicated code to find the author name in make_releases. --- RepSys/log.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 5c29876..25c54de 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -199,9 +199,7 @@ def make_release(author=None, revision=None, date=None, lines=None, entries=[], released=True, version=None, release=None): rel = _Release() rel.author = author - found = emailpat.match(config.get("users", author, author or "")) - rel.author_name = (found and found.group("name")) or author - rel.author_email = (found and found.group("email")) or author + rel.author_name, rel.author_email = get_author_name(author) rel.revision = revision rel.version = version rel.release = release -- cgit v1.2.1 From fe33b467fea63fae1a8436803f7d34575fbf105d Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Mon, 13 Nov 2006 16:35:48 +0000 Subject: add compatv15.chlog so that "make localrpm" works (even if this spec file is not used for the final package) --- repsys.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/repsys.spec b/repsys.spec index 1f6f189..eaf1434 100644 --- a/repsys.spec +++ b/repsys.spec @@ -44,6 +44,7 @@ rm -rf %{buildroot} %{_bindir}/getsrpm-mdk %{_datadir}/repsys/rebrand-mdk %{_datadir}/repsys/create-srpm +%{_datadir}/repsys/compatv15.chlog %{_datadir}/repsys/default.chlog %{_datadir}/repsys/revno.chlog %{_datadir}/repsys/oldfashion.chlog -- cgit v1.2.1 From ff0c060f077628368f121800bd7da63330879061 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Mon, 13 Nov 2006 16:36:22 +0000 Subject: make get_srpm() verbose only when called from the getsrpm command --- RepSys/commands/getsrpm.py | 1 + RepSys/rpmutil.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/RepSys/commands/getsrpm.py b/RepSys/commands/getsrpm.py index a212b52..d76aca7 100644 --- a/RepSys/commands/getsrpm.py +++ b/RepSys/commands/getsrpm.py @@ -74,6 +74,7 @@ def parse_options(): if len(args) != 1: raise Error, "invalid arguments" opts.pkgdirurl = default_parent(args[0]) + opts.verbose = 1 return opts def main(): diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index ac54046..ed62901 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -36,7 +36,8 @@ def get_srpm(pkgdirurl, svnlog = 0, scripts = [], submit = False, - template = None): + template = None, + verbose = 0): svn = SVN(baseurl=pkgdirurl) tmpdir = tempfile.mktemp() topdir = "--define '_topdir %s'" % tmpdir @@ -94,7 +95,8 @@ def get_srpm(pkgdirurl, for targetdir in targetdirs: targetsrpm = os.path.join(os.path.realpath(targetdir), os.path.basename(srpm)) targetsrpms.append(targetsrpm) - sys.stderr.write("Wrote: %s\n" % targetsrpm) + if verbose: + sys.stderr.write("Wrote: %s\n" % targetsrpm) execcmd("cp -f", srpm, targetdir) os.unlink(srpm) return targetsrpms -- cgit v1.2.1 From d132547bf943cbeabc56edb71eb089033e8e5721 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Mon, 13 Nov 2006 16:36:43 +0000 Subject: 1.6.9 --- repsys.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys.spec b/repsys.spec index eaf1434..91353e1 100644 --- a/repsys.spec +++ b/repsys.spec @@ -1,5 +1,5 @@ Name: repsys -Version: 1.6.8 +Version: 1.6.9 Release: %mkrel 1 Summary: Tools for Mandriva Linux repository access and management Group: Development/Other -- cgit v1.2.1 From a5ae5fc7033a0d13d999713620a2816b5aa3bc21 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 13 Nov 2006 20:20:17 +0000 Subject: Fixed undeclared name "pkgdirurl" in "co" subcommand. Replaced url by pkgdirurl, as in the rest of the code. --- RepSys/commands/co.py | 2 +- RepSys/rpmutil.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RepSys/commands/co.py b/RepSys/commands/co.py index 0c9d2dc..f2b4d64 100644 --- a/RepSys/commands/co.py +++ b/RepSys/commands/co.py @@ -23,7 +23,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) not in (1, 2): raise Error, "invalid arguments" - opts.url = default_parent(args[0]) + opts.pkgdirurl = default_parent(args[0]) if len(args) == 2: opts.path = args[1] else: diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index ed62901..0302089 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -344,11 +344,11 @@ def check_changed(url, all=0, show=0, verbose=0): "nocurrent": nocurrent, "nopristine": nopristine} -def checkout(url, path=None, revision=None): +def checkout(pkgdirurl, path=None, revision=None): svn = SVN(baseurl=pkgdirurl) - current = os.path.join(url, "current") + current = os.path.join(pkgdirurl, "current") if path is None: - _, path = os.path.split(url) + _, path = os.path.split(pkgdirurl) svn.checkout(current, path, rev=revision, show=1) def get_submit_info(path): -- cgit v1.2.1 From 0c62e6d9a17ca45c1709ca17d0005ecfb640fe99 Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Tue, 14 Nov 2006 20:58:00 +0000 Subject: - silence stderr when querying for version-release of a .src.rpm package --- RepSys/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RepSys/log.py b/RepSys/log.py index 25c54de..d1e2a59 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -61,7 +61,7 @@ def getrelease(pkgdirurl, rev=None): if found: specpath = found[0] command = (("rpm -q --qf '%%{VERSION}-%%{RELEASE}\n' " - "--specfile %s") % specpath) + "--specfile %s 2>/dev/null") % specpath) status, output = execcmd(command) if status != 0: raise Error, "Error in command %s: %s" % (command, output) -- cgit v1.2.1 From 14c125b310d2aa3392d2382755beff4871adaee5 Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Tue, 28 Nov 2006 15:49:54 +0000 Subject: - fix current version number --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index c19bfbc..10e8b89 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.7" +VERSION="1.6.9" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From a7c361fa2cc9546d95583ffd3d60fe78381f44f2 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 30 Nov 2006 13:07:14 +0000 Subject: Fixed wrong variable name on "changed". --- RepSys/commands/changed.py | 2 +- RepSys/rpmutil.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RepSys/commands/changed.py b/RepSys/commands/changed.py index c99f3ae..d3094a8 100644 --- a/RepSys/commands/changed.py +++ b/RepSys/commands/changed.py @@ -25,7 +25,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) != 1: raise Error, "invalid arguments" - opts.url = default_parent(args[0]) + opts.pkgdirurl = default_parent(args[0]) opts.verbose = 1 # Unconfigurable return opts diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 0302089..4ae007d 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -284,10 +284,10 @@ def mark_release(pkgdirurl, version, release, revision): svn.copy(currenturl, releaseurl, rev=revision, log=markreleaselog) -def check_changed(url, all=0, show=0, verbose=0): +def check_changed(pkgdirurl, all=0, show=0, verbose=0): svn = SVN(baseurl=pkgdirurl) if all: - baseurl = url + baseurl = pkgdirurl packages = [] if verbose: print "Getting list of packages...", @@ -298,7 +298,7 @@ def check_changed(url, all=0, show=0, verbose=0): if not packages: raise Error, "couldn't get list of packages" else: - baseurl, basename = os.path.split(url) + baseurl, basename = os.path.split(pkgdirurl) packages = [basename] clean = [] changed = [] -- cgit v1.2.1 From d376426856a092a44635c6616ba72c8d1a2e3444 Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Thu, 30 Nov 2006 21:53:14 +0000 Subject: - use svn export instead of checkout, saves 50% disk space --- RepSys/log.py | 3 ++- RepSys/rpmutil.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index d1e2a59..152abb0 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -199,7 +199,8 @@ def make_release(author=None, revision=None, date=None, lines=None, entries=[], released=True, version=None, release=None): rel = _Release() rel.author = author - rel.author_name, rel.author_email = get_author_name(author) + if author: + rel.author_name, rel.author_email = get_author_name(author) rel.revision = revision rel.version = version rel.release = release diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 4ae007d..872dc99 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -57,7 +57,7 @@ def get_srpm(pkgdirurl, geturl = os.path.join(pkgdirurl, "current") else: raise Error, "unsupported get_srpm mode: %s" % mode - svn.checkout(geturl, tmpdir, rev=revision) + svn.export(geturl, tmpdir, rev=revision) srpmsdir = os.path.join(tmpdir, "SRPMS") os.mkdir(srpmsdir) specsdir = os.path.join(tmpdir, "SPECS") @@ -69,7 +69,7 @@ def get_srpm(pkgdirurl, submit = not not revision specfile_svn2rpm(pkgdirurl, spec, revision, submit=submit, template=template) - revisionreal = svn.revision(tmpdir) + revisionreal = svn.revision(pkgdirurl) for script in scripts: status, output = execcmd(script, tmpdir, spec, str(revision), noerror=1) -- cgit v1.2.1 From d2588e5434995b5502bfff3cc34e9f78e43d859f Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Fri, 1 Dec 2006 13:10:03 +0000 Subject: - bump version --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 10e8b89..79bacf6 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.9" +VERSION="1.6.10" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 3362fd42e4cc57d2f4241252ca6b3ef1b1e98596 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 4 Dec 2006 15:27:17 +0000 Subject: Added option "tempdir" to the [submit] section. --- RepSys/__init__.py | 2 ++ repsys.conf | 3 +++ 2 files changed, 5 insertions(+) diff --git a/RepSys/__init__.py b/RepSys/__init__.py index c394746..94697d1 100644 --- a/RepSys/__init__.py +++ b/RepSys/__init__.py @@ -1,10 +1,12 @@ #!/usr/bin/python import re import os +import tempfile import ConfigParser config = ConfigParser.Config() +tempfile.tempdir = config.get("submit", "tempdir", None) or None # when "" del ConfigParser class Error(Exception): pass diff --git a/repsys.conf b/repsys.conf index 783a2e0..72b10c3 100644 --- a/repsys.conf +++ b/repsys.conf @@ -27,6 +27,9 @@ helio = Helio Chissini de Castro lmontel = Laurent Montel oden = Oden Eriksson +[submit] +tempdir = + [submit Cooker] target = /export/home/repsys allowed = svn+ssh://svn.mandriva.com/svn/packages/cooker -- cgit v1.2.1 From 441cccabe7fd255810aabc77fdd636fb3905906b Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 4 Dec 2006 19:58:45 +0000 Subject: Moved the option "tempdir" from [submit] to [global], since it changes the behavior of all subcommands. --- RepSys/__init__.py | 2 +- repsys.conf | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/RepSys/__init__.py b/RepSys/__init__.py index 94697d1..b303065 100644 --- a/RepSys/__init__.py +++ b/RepSys/__init__.py @@ -6,7 +6,7 @@ import tempfile import ConfigParser config = ConfigParser.Config() -tempfile.tempdir = config.get("submit", "tempdir", None) or None # when "" +tempfile.tempdir = config.get("global", "tempdir", None) or None # when "" del ConfigParser class Error(Exception): pass diff --git a/repsys.conf b/repsys.conf index 72b10c3..cec6fa6 100644 --- a/repsys.conf +++ b/repsys.conf @@ -2,6 +2,7 @@ verbose = no default_parent = svn+ssh://svn.mandriva.com/svn/packages/cooker url-map = svn\+ssh://svn\.mandriva\.com/(.*) file:///\1 +#tempdir = /tmp [log] oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc @@ -27,9 +28,6 @@ helio = Helio Chissini de Castro lmontel = Laurent Montel oden = Oden Eriksson -[submit] -tempdir = - [submit Cooker] target = /export/home/repsys allowed = svn+ssh://svn.mandriva.com/svn/packages/cooker -- cgit v1.2.1 From 5c5b3e1f3304f55aa3467dae63d8cbdcdec59163 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Fri, 15 Dec 2006 12:36:10 +0000 Subject: use Cooker as default submit target --- repsys.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/repsys.conf b/repsys.conf index cec6fa6..1430fb6 100644 --- a/repsys.conf +++ b/repsys.conf @@ -28,6 +28,9 @@ helio = Helio Chissini de Castro lmontel = Laurent Montel oden = Oden Eriksson +[submit] +default = Cooker + [submit Cooker] target = /export/home/repsys allowed = svn+ssh://svn.mandriva.com/svn/packages/cooker -- cgit v1.2.1 From 275cab2de13197085229b0478ecebb1859036092 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 2 Jan 2007 15:23:10 +0000 Subject: Make source lines fit in 80 columns --- RepSys/log.py | 3 ++- RepSys/rpmutil.py | 3 ++- RepSys/svn.py | 3 ++- RepSys/util.py | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 152abb0..b2e9321 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -316,7 +316,8 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): parse_markrelease_log(relentry) except InvalidEntryError: continue - releasesdata.append((relrevision, -relentry.revision, relentry, version, release)) + releasesdata.append((relrevision, -relentry.revision, relentry, + version, release)) releasesdata.sort() # collect valid releases using the versions provided by the changes and diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 872dc99..8cc6244 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -93,7 +93,8 @@ def get_srpm(pkgdirurl, targetdirs = (".",) targetsrpms = [] for targetdir in targetdirs: - targetsrpm = os.path.join(os.path.realpath(targetdir), os.path.basename(srpm)) + targetsrpm = os.path.join(os.path.realpath(targetdir), + os.path.basename(srpm)) targetsrpms.append(targetsrpm) if verbose: sys.stderr.write("Wrote: %s\n" % targetsrpm) diff --git a/RepSys/svn.py b/RepSys/svn.py index 1483a02..4e073dc 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -205,7 +205,8 @@ class SVN: return [x.split() for x in output.split()] return None - def merge(self, url1, url2=None, rev1=None, rev2=None, path=None, **kwargs): + def merge(self, url1, url2=None, rev1=None, rev2=None, path=None, + **kwargs): cmd = ["merge"] if rev1 and rev2 and not url2: cmd.append("-r") diff --git a/RepSys/util.py b/RepSys/util.py index 8c66199..83f2ebe 100644 --- a/RepSys/util.py +++ b/RepSys/util.py @@ -29,7 +29,8 @@ def execcmd(*cmd, **kwargs): status = os.system(cmdstr) output = "" else: - status, output = commands_getstatusoutput("LANG=C LANGUAGE=C LC_ALL=C "+cmdstr) + status, output = commands_getstatusoutput( + "LANG=C LANGUAGE=C LC_ALL=C "+cmdstr) if status != 0 and not kwargs.get("noerror"): raise Error, "command failed: %s\n%s\n" % (cmdstr, output) if config.getbool("global", "verbose", 0): -- cgit v1.2.1 From 9a98086f0224ea644e0dc2d8e2a42bcf40c2d6df Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 2 Jan 2007 15:24:55 +0000 Subject: Really minor comment fixes --- RepSys/log.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index b2e9321..2934907 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -307,7 +307,7 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): end=revoffset) # sort releases by copyfrom-revision, so that markreleases for same - # revisions won't be look empty + # revisions won't look empty releasesdata = [] if releaseslog: for relentry in releaseslog[::-1]: @@ -327,7 +327,7 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): for (relrevision, dummy, relentry, version, release) in releasesdata: if prevrevision == relrevision: # ignore older markrelease of the same revision, since they - # will have history + # will have no history continue entries = [entry for entry in currentlog if relrevision >= entry.revision and -- cgit v1.2.1 From c2361c74e06a0fe7e84b534a74f868cf19f90f5a Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 2 Jan 2007 16:30:45 +0000 Subject: Commit messages containing SILENT (or whatever is in repsys.conf) won't appear in the changelog. --- RepSys/log.py | 9 +++++++++ repsys.conf | 2 ++ 2 files changed, 11 insertions(+) diff --git a/RepSys/log.py b/RepSys/log.py index 2934907..064b585 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -195,6 +195,13 @@ def get_author_name(author): def parse_raw_date(rawdate): return time.strftime("%a %b %d %Y", rawdate) +def ignore_log_entry(entry): + ignstr = config.get("log", "ignore-string", "SILENT") + for line in entry.lines: + if ignstr in line: + return True + return False + def make_release(author=None, revision=None, date=None, lines=None, entries=[], released=True, version=None, release=None): rel = _Release() @@ -208,6 +215,8 @@ def make_release(author=None, revision=None, date=None, lines=None, rel.lines = lines rel.released = released for entry in entries: + if ignore_log_entry(entry): + continue revision = _Revision() revision.revision = entry.revision revision.lines = format_lines(entry.lines) diff --git a/repsys.conf b/repsys.conf index 1430fb6..e87b119 100644 --- a/repsys.conf +++ b/repsys.conf @@ -10,6 +10,8 @@ oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc # will be constructed (default zero, i.e., oldest # commit) revision-offset = 0 +# commits containing this string won't be shown in the changelog: +ignore-string = SILENT [template] path = /usr/share/repsys/default.chlog -- cgit v1.2.1 From ae858677cdae9a7fa093fda779661d3d26b6b4c6 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 2 Jan 2007 19:30:29 +0000 Subject: Changed the behavior of the SILENT option to be line-oriented. Lines in the commit messages containing SILENT at any place will be ignored. Commit messages containing SILENT at the beginning of the first line will make all lines to be ignored. --- RepSys/log.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 064b585..f3f2bab 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -195,12 +195,16 @@ def get_author_name(author): def parse_raw_date(rawdate): return time.strftime("%a %b %d %Y", rawdate) -def ignore_log_entry(entry): +def filter_log_lines(lines): + # lines in commit messages containing SILENT at any position will be + # skipped; commits with their log messages beggining with SILENT in the + # first positionj of the first line will be completely ignored. ignstr = config.get("log", "ignore-string", "SILENT") - for line in entry.lines: - if ignstr in line: - return True - return False + if len(lines) and lines[0].startswith(ignstr): + return None + filtered = [line for line in lines if ignstr not in line] + return filtered + def make_release(author=None, revision=None, date=None, lines=None, entries=[], released=True, version=None, release=None): @@ -215,11 +219,12 @@ def make_release(author=None, revision=None, date=None, lines=None, rel.lines = lines rel.released = released for entry in entries: - if ignore_log_entry(entry): + lines = filter_log_lines(entry.lines) + if lines is None: continue revision = _Revision() revision.revision = entry.revision - revision.lines = format_lines(entry.lines) + revision.lines = format_lines(lines) revision.date = parse_raw_date(entry.date) revision.raw_date = entry.date revision.author = entry.author -- cgit v1.2.1 From 592b9d0877ebe26f81a6a51fdde729a71a85cd00 Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Wed, 3 Jan 2007 12:25:12 +0000 Subject: - 1.6.11 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 79bacf6..bcd951c 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.10" +VERSION="1.6.11" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 9e4787788d045c125a1981015e0b2056ee9eed61 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 3 Jan 2007 13:19:48 +0000 Subject: Fixed old module use that does not exist now --- RepSys/rpmutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 8cc6244..968470c 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -269,7 +269,7 @@ def mark_release(pkgdirurl, version, release, revision): versionurl = "/".join([releasesurl, version]) releaseurl = "/".join([versionurl, release]) if svn.ls(releaseurl, noerror=1): - raise cncrep.Error, "release already exists" + raise Error, "release already exists" svn.mkdir(releasesurl, noerror=1, log="Created releases directory.") svn.mkdir(versionurl, noerror=1, -- cgit v1.2.1 From e95b85e5666db657c4e7d1b252dca0a0ffe6090a Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 3 Jan 2007 13:49:45 +0000 Subject: Make the changelog show the revision number from ignored commits that are newer than the not ignored ones. Releases containing only SILENT commit messages will be shown, but without log lines (probably the changelog template should handle this case). --- RepSys/log.py | 6 ++---- repsys.conf | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index f3f2bab..2651d19 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -198,10 +198,10 @@ def parse_raw_date(rawdate): def filter_log_lines(lines): # lines in commit messages containing SILENT at any position will be # skipped; commits with their log messages beggining with SILENT in the - # first positionj of the first line will be completely ignored. + # first positionj of the first line will have all lines ignored. ignstr = config.get("log", "ignore-string", "SILENT") if len(lines) and lines[0].startswith(ignstr): - return None + return [] filtered = [line for line in lines if ignstr not in line] return filtered @@ -220,8 +220,6 @@ def make_release(author=None, revision=None, date=None, lines=None, rel.released = released for entry in entries: lines = filter_log_lines(entry.lines) - if lines is None: - continue revision = _Revision() revision.revision = entry.revision revision.lines = format_lines(lines) diff --git a/repsys.conf b/repsys.conf index e87b119..f74d866 100644 --- a/repsys.conf +++ b/repsys.conf @@ -10,7 +10,7 @@ oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc # will be constructed (default zero, i.e., oldest # commit) revision-offset = 0 -# commits containing this string won't be shown in the changelog: +# commit lines containing this string won't be shown in the changelog: ignore-string = SILENT [template] -- cgit v1.2.1 From c03d8448d9ec52b6c0c22743b487e1c02519bdbc Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Wed, 3 Jan 2007 15:41:09 +0000 Subject: - 1.6.12 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index bcd951c..a335895 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.11" +VERSION="1.6.12" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 8a6a78b1e7de47da015c666dd44b29fa86a105a7 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 16 Jan 2007 18:50:46 +0000 Subject: Added the option "host" to the submit section. It allows to submit to one host the package placed in another subversion host. The option "-s" in the command-line also can do it. --- RepSys/commands/submit.py | 87 +++++++++++++++++------------------------------ repsys.conf | 1 + 2 files changed, 33 insertions(+), 55 deletions(-) diff --git a/RepSys/commands/submit.py b/RepSys/commands/submit.py index 380391a..5c95526 100644 --- a/RepSys/commands/submit.py +++ b/RepSys/commands/submit.py @@ -18,12 +18,18 @@ import xmlrpclib HELP = """\ Usage: repsys submit [OPTIONS] [URL [REVISION]] +Submits the package from URL to the submit host. + Options: -t TARGET Submit given package URL to given target -l Just list available targets -r REV Provides a revision number (when not providing as an argument) + -s The host in which the package URL will be submitted + (defaults to the host in the URL) -h Show this message + --define Defines one variable to be used by the submit scripts + in the submit host Examples: repsys submit @@ -39,6 +45,8 @@ def parse_options(): parser.add_option("-t", dest="target", default="Cooker") parser.add_option("-l", dest="list", action="store_true") 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("--define", action="append") opts, args = parser.parse_args() if not args: @@ -64,64 +72,33 @@ def parse_options(): raise Error, "provide -l or a revision number" return opts -def submit(pkgdirurl, revision, target, list=0, define=[]): +def submit(pkgdirurl, revision, target, list=0, define=[], submithost=None): #if not NINZ: # raise Error, "you must have NINZ installed to use this command" - type, rest = urllib.splittype(pkgdirurl) - host, path = urllib.splithost(rest) - user, host = urllib.splituser(host) - host, port = urllib.splitport(host) - if type != "https" and type != "svn+ssh": - raise Error, "you must use https:// or svn+ssh:// urls" - if user: - user, passwd = urllib.splitpasswd(user) - if passwd: - raise Error, "do not use a password in your command line" - if type == "https": - user, passwd = get_auth(username=user) - #soap = NINZ.client.Binding(host=host, - # url="https://%s/scripts/cnc/soap" % host, - # ssl=1, - # auth=(NINZ.client.AUTH.httpbasic, - # user, passwd)) - if port: - port = ":"+port - else: - port = "" - iface = xmlrpclib.ServerProxy("https://%s:%s@%s%s/scripts/cnc/xmlrpc" - % (user, passwd, host, port)) - try: - if list: - targets = iface.submit_targets() - if not targets: - raise Error, "no targets available" - sys.stdout.writelines(['"%s"\n' % x for x in targets]) - else: - iface.submit_package(pkgdirurl, revision, target) - print "Package submitted!" - #except NINZ.client.SoapError, e: - except xmlrpclib.ProtocolError, e: - raise Error, "remote error: "+str(e.errmsg) - except xmlrpclib.Fault, e: - raise Error, "remote error: "+str(e.faultString) - except xmlrpclib.Error, e: - raise Error, "remote error: "+str(e) + if submithost is None: + submithost = config.get("submit", "host") + if submithost is None: + # extract the submit host from the svn host + type, rest = urllib.splittype(pkgdirurl) + host, path = urllib.splithost(rest) + user, host = urllib.splituser(host) + submithost, port = urllib.splitport(host) + del type, user, port, path, rest + # runs a create-srpm in the server through ssh, which will make a + # copy of the rpm in the export directory + if list: + raise Error, "unable to list targets from svn+ssh:// URLs" + createsrpm = get_helper("create-srpm") + command = "ssh %s %s '%s' -r %s -t %s" % ( + submithost, createsrpm, pkgdirurl, revision, target) + if define: + command += " " + " ".join([ "--define " + x for x in define ]) + status, output = execcmd(command) + if status == 0: + print "Package submitted!" else: - # runs a create-srpm in the server through ssh, which will make a - # copy of the rpm in the export directory - if list: - raise Error, "unable to list targets from svn+ssh:// URLs" - createsrpm = get_helper("create-srpm") - command = "ssh %s %s '%s' -r %s -t %s" % ( - host, createsrpm, pkgdirurl, revision, target) - if define: - command += " " + " ".join([ "--define " + x for x in define ]) - status, output = execcmd(command) - if status == 0: - print "Package submitted!" - else: - sys.stderr.write(output) - sys.exit(status) + sys.stderr.write(output) + sys.exit(status) def main(): diff --git a/repsys.conf b/repsys.conf index f74d866..af71609 100644 --- a/repsys.conf +++ b/repsys.conf @@ -31,6 +31,7 @@ lmontel = Laurent Montel oden = Oden Eriksson [submit] +host = kenobi.mandriva.com default = Cooker [submit Cooker] -- cgit v1.2.1 From 6378ccbba271beea89195ee838a8d9f4979833fe Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Tue, 16 Jan 2007 20:16:36 +0000 Subject: - 1.6.13 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index a335895..988e42e 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.12" +VERSION="1.6.13" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 25545a7a3702c0b624b802b795d631534977979b Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 24 Jan 2007 15:26:48 +0000 Subject: Added "repsys.macros" configuration file. It will contain macros overriding the local system ones. The reason for it is to make changelogs generated in kenobi (2007.0) having the cooker release number (in the case 2007.1). --- Makefile | 2 +- RepSys/log.py | 25 ++++++++++++++++++++++++- repsys.conf | 2 ++ repsys.macros | 6 ++++++ setup.py | 2 +- 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 repsys.macros diff --git a/Makefile b/Makefile index e1aa91b..f55bbfe 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TAG := $(shell echo "V$(VERSION)_$(RELEASE)" | tr -- '-.' '__') FILES = ChangeLog Makefile MANIFEST.in PKG-INFO create-srpm getsrpm-mdk rebrand-mdk \ {compatv15,default,oldfashion,revno}.chlog \ - repsys repsys.conf repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py + repsys repsys.conf repsys.macros repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py # rules to build a test rpm diff --git a/RepSys/log.py b/RepSys/log.py index 2651d19..6d7bde0 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -60,8 +60,12 @@ def getrelease(pkgdirurl, rev=None): found = glob.glob(os.path.join(tmpdir, "*.spec")) if found: specpath = found[0] + fmt = "--define \"%s %s\"" + macros = (fmt % macro for macro in parse_macros()) + options = " ".join(macros) command = (("rpm -q --qf '%%{VERSION}-%%{RELEASE}\n' " - "--specfile %s 2>/dev/null") % specpath) + "--specfile %s %s 2>/dev/null") % + (specpath, options)) status, output = execcmd(command) if status != 0: raise Error, "Error in command %s: %s" % (command, output) @@ -77,6 +81,25 @@ def getrelease(pkgdirurl, rev=None): shutil.rmtree(tmpdir) +def parse_macros(): + path = config.get("log", "macros-file", None) + if not path: + # if the user did not declated where is the file, ignore it + return + if not os.path.isfile(path): + # complain when declared and not found + sys.stderr.write("warning: could not open macros file: %s\n" % + path) + return + for line in open(path): + line = line.strip() + if line.startswith("#") or not line: + continue + name, value = line.split(None, 1) + # trying to have the same format from rpm macros files + name = name[1:] + yield (name, value) + class _Revision: lines = [] date = None diff --git a/repsys.conf b/repsys.conf index af71609..8eeea05 100644 --- a/repsys.conf +++ b/repsys.conf @@ -12,6 +12,8 @@ oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc revision-offset = 0 # commit lines containing this string won't be shown in the changelog: ignore-string = SILENT +# see repsys.macros: +#macros-file = /etc/repsys.macros [template] path = /usr/share/repsys/default.chlog diff --git a/repsys.macros b/repsys.macros new file mode 100644 index 0000000..83caa21 --- /dev/null +++ b/repsys.macros @@ -0,0 +1,6 @@ +# Use this file to override the macros from the machine where repsys is +# being run. It is used when retrieving version-release to be used in the +# changelog of a package not released yet. + +#%mandriva_release 2007.1 +#%distsuffix mdv diff --git a/setup.py b/setup.py index 272ec84..701f8d6 100755 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ setup(name="repsys", "compatv15.chlog", "create-srpm", "rebrand-mdk"]), - ("/etc/", ["repsys.conf"])] + ("/etc/", ["repsys.conf", "repsys.macros"])] ) # vim:ts=4:sw=4:et -- cgit v1.2.1 From d4d9914ec004a9ad1b767bc177d45af6694080be Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 29 Jan 2007 16:44:02 +0000 Subject: Make ConfigParser forward args to allow the use of "raw" option. It will enable us to choose which sections should not allow ConfigParser's references. --- RepSys/ConfigParser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RepSys/ConfigParser.py b/RepSys/ConfigParser.py index 0f219b9..c10b3a7 100644 --- a/RepSys/ConfigParser.py +++ b/RepSys/ConfigParser.py @@ -373,8 +373,8 @@ class Config: def set(self, section, option, value): return self._config.set(section, option, value) - def walk(self, section): - return self._config.walk(section) + def walk(self, section, *args, **kwargs): + return self._config.walk(section, *args, **kwargs) def get(self, section, option, default=None): try: -- cgit v1.2.1 From a493be252f25b57767023930d4ed927b37816e71 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 29 Jan 2007 18:14:56 +0000 Subject: Removed bogus macros files and added [macros ..] sections to repsys.conf. These sections are referenced by the "rpm-macros" option in [submit ..] sections and contain the RPM macros to be used with the target of the package being generated. These macros are defined using --define option of rpm. --- Makefile | 2 +- RepSys/cgiutil.py | 24 ++++++++++++++++++------ RepSys/log.py | 36 ++++++++---------------------------- RepSys/rpmutil.py | 13 ++++++++++--- create-srpm | 3 ++- repsys.conf | 18 ++++++++++++++++++ repsys.macros | 6 ------ setup.py | 2 +- 8 files changed, 58 insertions(+), 46 deletions(-) delete mode 100644 repsys.macros diff --git a/Makefile b/Makefile index f55bbfe..e1aa91b 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ TAG := $(shell echo "V$(VERSION)_$(RELEASE)" | tr -- '-.' '__') FILES = ChangeLog Makefile MANIFEST.in PKG-INFO create-srpm getsrpm-mdk rebrand-mdk \ {compatv15,default,oldfashion,revno}.chlog \ - repsys repsys.conf repsys.macros repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py + repsys repsys.conf repsys.spec setup.cfg setup.py RepSys/*.py RepSys/{cgi,commands}/*.py # rules to build a test rpm diff --git a/RepSys/cgiutil.py b/RepSys/cgiutil.py index 6dda91e..35c5efb 100644 --- a/RepSys/cgiutil.py +++ b/RepSys/cgiutil.py @@ -1,6 +1,7 @@ #!/usr/bin/python from RepSys import Error, config from RepSys.svn import SVN +from RepSys.ConfigParser import NoSectionError import time import re @@ -10,11 +11,23 @@ class SubmitTarget: def __init__(self): self.name = "" self.target = "" + self.macros = [] self.allowed = [] self.scripts = [] TARGETS = [] +def parse_macrosref(refs, config): + macros = [] + for name in refs: + secname = "macros %s" % name + try: + macros.extend(config.walk(secname, raw=True)) + except NoSectionError: + raise Error, "missing macros section " \ + "%r in configuration" % secname + return macros + def get_targets(): global TARGETS if not TARGETS: @@ -27,12 +40,11 @@ def get_targets(): target = SubmitTarget() target.name = m.group(1) for option, value in config.walk(section): - if option == "target": - target.target = value.split() - elif option == "allowed": - target.allowed = value.split() - elif option == "scripts": - target.scripts = value.split() + if option in ("target", "allowed", "scripts"): + setattr(target, option, value.split()) + elif option == "rpm-macros": + refs = value.split() + target.macros = parse_macrosref(refs, config) else: raise Error, "unknown [%s] option %s" % (section, option) TARGETS.append(target) diff --git a/RepSys/log.py b/RepSys/log.py index 6d7bde0..3645fdd 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -42,13 +42,14 @@ default_template = """ #end for """ -def getrelease(pkgdirurl, rev=None): +def getrelease(pkgdirurl, rev=None, macros=[]): """Tries to obtain the version-release of the package for a yet-not-markrelease revision of the package. Is here where things should be changed if "automatic release increasing" will be used. """ + from RepSys.rpmutil import rpm_macros_defs svn = SVN(baseurl=pkgdirurl) tmpdir = tempfile.mktemp() try: @@ -60,9 +61,7 @@ def getrelease(pkgdirurl, rev=None): found = glob.glob(os.path.join(tmpdir, "*.spec")) if found: specpath = found[0] - fmt = "--define \"%s %s\"" - macros = (fmt % macro for macro in parse_macros()) - options = " ".join(macros) + options = rpm_macros_defs(macros) command = (("rpm -q --qf '%%{VERSION}-%%{RELEASE}\n' " "--specfile %s %s 2>/dev/null") % (specpath, options)) @@ -80,26 +79,6 @@ def getrelease(pkgdirurl, rev=None): if os.path.isdir(tmpdir): shutil.rmtree(tmpdir) - -def parse_macros(): - path = config.get("log", "macros-file", None) - if not path: - # if the user did not declated where is the file, ignore it - return - if not os.path.isfile(path): - # complain when declared and not found - sys.stderr.write("warning: could not open macros file: %s\n" % - path) - return - for line in open(path): - line = line.strip() - if line.startswith("#") or not line: - continue - name, value = line.split(None, 1) - # trying to have the same format from rpm macros files - name = name[1:] - yield (name, value) - class _Revision: lines = [] date = None @@ -331,7 +310,8 @@ def parse_markrelease_log(relentry): return version, release, from_rev -def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): +def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, + template=None, macros=[]): concat = config.get("log", "concat", "").split() revoffset = get_revision_offset() svn = SVN(baseurl=pkgdirurl) @@ -394,7 +374,7 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): 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) + version, release = getrelease(pkgdirurl, macros=macros) toprelease = make_release(entries=notsubmitted, released=False, version=version, release=release) releases.append(toprelease) @@ -405,7 +385,7 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None): def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, - submit=False, template=None): + submit=False, template=None, macros=[]): newlines = [] found = 0 @@ -422,7 +402,7 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, # Create new changelog newlines.append("\n\n%changelog\n") newlines.append(svn2rpm(pkgdirurl, rev=rev, size=size, submit=submit, - template=template)) + template=template, macros=macros)) # Merge old changelog, if available oldurl = config.get("log", "oldurl") diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 968470c..367fd45 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -25,6 +25,11 @@ def get_spec(pkgdirurl, targetdir=".", submit=False): if os.path.isdir(tmpdir): shutil.rmtree(tmpdir) +def rpm_macros_defs(macros): + defs = ("--define \"%s %s\"" % macro for macro in macros) + args = " ".join(defs) + return args + def get_srpm(pkgdirurl, mode = "current", targetdirs = None, @@ -37,6 +42,7 @@ def get_srpm(pkgdirurl, scripts = [], submit = False, template = None, + macros = [], verbose = 0): svn = SVN(baseurl=pkgdirurl) tmpdir = tempfile.mktemp() @@ -68,7 +74,7 @@ def get_srpm(pkgdirurl, if svnlog: submit = not not revision specfile_svn2rpm(pkgdirurl, spec, revision, submit=submit, - template=template) + template=template, macros=macros) revisionreal = svn.revision(pkgdirurl) for script in scripts: status, output = execcmd(script, tmpdir, spec, str(revision), @@ -78,9 +84,10 @@ def get_srpm(pkgdirurl, if packager: packager = " --define 'packager %s'" % packager - execcmd("rpm -bs --nodeps %s %s %s %s %s %s %s %s %s" % + defs = rpm_macros_defs(macros) + execcmd("rpm -bs --nodeps %s %s %s %s %s %s %s %s %s %s" % (topdir, builddir, rpmdir, sourcedir, specdir, - srcrpmdir, patchdir, packager, spec)) + srcrpmdir, patchdir, packager, spec, defs)) if revision and revisionreal: srpm = glob.glob(os.path.join(srpmsdir, "*.src.rpm"))[0] diff --git a/create-srpm b/create-srpm index fc235bf..5223d45 100755 --- a/create-srpm +++ b/create-srpm @@ -52,7 +52,8 @@ class CmdIface: packager=packager, revname=1, svnlog=1, - scripts=target.scripts) + scripts=target.scripts, + macros=target.macros) uploadsrpm = get_helper("upload-srpm") if uploadsrpm: diff --git a/repsys.conf b/repsys.conf index 8eeea05..dce1fe3 100644 --- a/repsys.conf +++ b/repsys.conf @@ -40,3 +40,21 @@ default = Cooker target = /export/home/repsys allowed = svn+ssh://svn.mandriva.com/svn/packages/cooker scripts = /usr/share/repsys/rebrand-mdk +## +## rpm-macros refers to the sections containing the macros used for this +## target. The values will be used to build the rpmbuild command line. For +## example: +## +## [macros cooker] +## a = b +## c = %a +## +## will render in the command line: --define "a b" --define "c %a". +## +#rpm-macros = global cooker + +#[macros global] +#distsuffix = mdv + +#[macros cooker] +#mandriva_release = 2007.1 diff --git a/repsys.macros b/repsys.macros deleted file mode 100644 index 83caa21..0000000 --- a/repsys.macros +++ /dev/null @@ -1,6 +0,0 @@ -# Use this file to override the macros from the machine where repsys is -# being run. It is used when retrieving version-release to be used in the -# changelog of a package not released yet. - -#%mandriva_release 2007.1 -#%distsuffix mdv diff --git a/setup.py b/setup.py index 701f8d6..272ec84 100755 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ setup(name="repsys", "compatv15.chlog", "create-srpm", "rebrand-mdk"]), - ("/etc/", ["repsys.conf", "repsys.macros"])] + ("/etc/", ["repsys.conf"])] ) # vim:ts=4:sw=4:et -- cgit v1.2.1 From f2d171495ab3387cb95256accd5db304f8db0f86 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 30 Jan 2007 15:10:12 +0000 Subject: Removed stripping of log messages in order to not destroy topic structure from log messages. --- RepSys/log.py | 1 - 1 file changed, 1 deletion(-) diff --git a/RepSys/log.py b/RepSys/log.py index 3645fdd..535287d 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -106,7 +106,6 @@ def format_lines(lines): entrylines = [] perexpr = re.compile(r"([^%])%([^%])") for line in lines: - line = line.lstrip() if line: line = perexpr.sub("\\1%%\\2", line) if first: -- cgit v1.2.1 From dfbe875f5fed1fdd017eba2d460c53b8b7cd2658 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 30 Jan 2007 20:56:26 +0000 Subject: Hide authors with only SILENTed changesets. --- RepSys/log.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RepSys/log.py b/RepSys/log.py index 535287d..d6d13e3 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -94,7 +94,9 @@ class _Revision: class _Release(_Revision): version = None release = None - revisions = None + revisions = [] + release_revisions = [] + authors = [] def __init__(self, **kwargs): self.revisions = [] @@ -135,8 +137,13 @@ def group_releases_by_author(releases): for release in releases: authors = {} for revision in release.revisions: + if not revision.lines: + continue authors.setdefault(revision.author, []).append(revision) + if not authors: + continue + # all the mess below is to sort by author and by revision number decorated = [] for authorname, revs in authors.iteritems(): -- cgit v1.2.1 From a06743d412196834e963a340f542422ed8d9a6cd Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 31 Jan 2007 12:56:03 +0000 Subject: - 1.6.14 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 988e42e..c0c9b1b 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.13" +VERSION="1.6.14" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From eecfb31ec9d42d37c71ecbe92c5a51bee156dc11 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 28 Feb 2007 14:31:52 +0000 Subject: Added changelogs and scripts to manifest template. --- MANIFEST.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 9311d09..03bd9ea 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,4 @@ recursive-include RepSys *.py -include repsys repsys.conf MANIFEST.in +include repsys repsys.conf MANIFEST.in +include *.chlog +include rebrand-mdk create-srpm getsrpm-mdk -- cgit v1.2.1 From 215990c8e99fd698d3231aae2bd67ac914a21065 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 14 Mar 2007 22:15:00 +0000 Subject: Make create-srpm check if the temporary package still exists before trying to remove it. --- create-srpm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/create-srpm b/create-srpm index 5223d45..83a4153 100755 --- a/create-srpm +++ b/create-srpm @@ -66,7 +66,8 @@ class CmdIface: upload_command.append(targetsrpms[0]) status, output = execcmd(" ".join(upload_command), noerror=1) - os.unlink(targetsrpms[0]) + if os.path.isfile(targetsrpms[0]): + os.unlink(targetsrpms[0]) if status != 0: raise CmdError, "Failed to upload %s:\n%s" % (packageurl, output) return 1 -- cgit v1.2.1 From fa714df32fc64fecdf766bdc9ba801ddc07ce536 Mon Sep 17 00:00:00 2001 From: Gustavo De Nardin Date: Thu, 15 Mar 2007 13:30:59 +0000 Subject: warn about strange situation, when working around it, to possibly help eventual future debugging --- create-srpm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/create-srpm b/create-srpm index 83a4153..820c81f 100755 --- a/create-srpm +++ b/create-srpm @@ -68,6 +68,8 @@ class CmdIface: noerror=1) if os.path.isfile(targetsrpms[0]): os.unlink(targetsrpms[0]) + else: + sys.stderr.write("warning: upload ok; temp file '%s' removed unexpectedly\n" % (targetsrpms[0])) if status != 0: raise CmdError, "Failed to upload %s:\n%s" % (packageurl, output) return 1 -- cgit v1.2.1 From b98cc32e7546d0cb90ce6df763a9515045750924 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 15 Mar 2007 18:40:24 +0000 Subject: Make releases with only SILENTed messages will result in a warning, not to be skipped. --- RepSys/log.py | 9 ++++----- default.chlog | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index d6d13e3..85d502f 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -97,6 +97,7 @@ class _Release(_Revision): revisions = [] release_revisions = [] authors = [] + visible = False def __init__(self, **kwargs): self.revisions = [] @@ -137,13 +138,8 @@ def group_releases_by_author(releases): for release in releases: authors = {} for revision in release.revisions: - if not revision.lines: - continue authors.setdefault(revision.author, []).append(revision) - if not authors: - continue - # all the mess below is to sort by author and by revision number decorated = [] for authorname, revs in authors.iteritems(): @@ -226,8 +222,11 @@ def make_release(author=None, revision=None, date=None, lines=None, rel.date = (date and parse_raw_date(date)) or None rel.lines = lines rel.released = released + rel.visible = False for entry in entries: lines = filter_log_lines(entry.lines) + if lines: + rel.visible = True revision = _Revision() revision.revision = entry.revision revision.lines = format_lines(lines) diff --git a/default.chlog b/default.chlog index 00b4784..ab5f97b 100644 --- a/default.chlog +++ b/default.chlog @@ -5,6 +5,9 @@ + Revision: $rel.revision #if not $rel.released ##+ Status: not released + #end if + #if not $rel.visible ++ EMPTYLOG: Man is the only animal that blushes -- or needs to. -- Mark Twain #end if #for $rev in $rel.release_revisions #for $line in $rev.lines -- cgit v1.2.1 From c2842fc2cf36e5cc132a431e8449af25b2675584 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 16 Mar 2007 15:53:26 +0000 Subject: 1.6.15 --- CHANGES | 6 ++++++ PKG-INFO | 2 +- repsys | 2 +- repsys.spec | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index b7df556..8fa4e03 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +* 1.6.15 +- empty changelog entries are now shown, with a EMPTYLOG tag to allow + rpmlint warn the developer about it +- check (and warn) if a temporary package has already been removed before + trying to remove it + * 1.6.2b - make submit pass --define options to create-srpm script - print error message when create-srpm fails diff --git a/PKG-INFO b/PKG-INFO index 5b2e07c..03e6f74 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: repsys -Version: 1.6.0 +Version: 1.6.15 Summary: Tools for Mandriva Linux repository access and management Home-page: http://qa.mandriva.com/twiki/bin/view/Main/RepositorySystem Author: Gustavo Niemeyer diff --git a/repsys b/repsys index c0c9b1b..3ac7f81 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.14" +VERSION="1.6.15" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] diff --git a/repsys.spec b/repsys.spec index 91353e1..81e251a 100644 --- a/repsys.spec +++ b/repsys.spec @@ -1,5 +1,5 @@ Name: repsys -Version: 1.6.9 +Version: 1.6.15 Release: %mkrel 1 Summary: Tools for Mandriva Linux repository access and management Group: Development/Other -- cgit v1.2.1 From 8c403d422268c1ef1ddfd481e5835c9c071478da Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 24 Apr 2007 18:15:43 +0000 Subject: Aways use HEAD for changelogs placed in misc/, since they can contain fixes. Also they are always intended to represent one change *BEFORE* the package import. --- RepSys/log.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RepSys/log.py b/RepSys/log.py index 85d502f..c4e2769 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -418,7 +418,9 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, pkgname = RepSysTree.pkgname(pkgdirurl) pkgoldurl = os.path.join(oldurl, pkgname) if svn.ls(pkgoldurl, noerror=1): - svn.export(pkgoldurl, tmpdir, rev=rev) + # we're using HEAD here because fixes in misc/ (oldurl) may + # be newer than packages' last changed revision. + svn.export(pkgoldurl, tmpdir) logfile = os.path.join(tmpdir, "log") if os.path.isfile(logfile): file = open(logfile) -- cgit v1.2.1 From 5cf994844b3510ec0d79f6dbc0fc1109d9412673 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 24 Apr 2007 18:16:41 +0000 Subject: Escape even the old changelogs that are inside misc/. These old changelogs contain bogus macros entries because the output of rpm -qp --changelog (or the equivalent) doesn't print the changelogs escaped. --- RepSys/log.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index c4e2769..24dca3c 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -103,6 +103,11 @@ class _Release(_Revision): self.revisions = [] _Revision.__init__(self, **kwargs) +unescaped_macro_pat = re.compile(r"([^%])%([^%])") + +def escape_macros(text): + escaped = unescaped_macro_pat.sub("\\1%%\\2", text) + return escaped def format_lines(lines): first = 1 @@ -110,7 +115,7 @@ def format_lines(lines): perexpr = re.compile(r"([^%])%([^%])") for line in lines: if line: - line = perexpr.sub("\\1%%\\2", line) + line = escape_macros(line) if first: first = 0 line = line.lstrip() @@ -425,7 +430,9 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, if os.path.isfile(logfile): file = open(logfile) newlines.append("\n") - newlines.append(file.read()) + log = file.read() + log = escape_macros(log) + newlines.append(log) file.close() finally: if os.path.isdir(tmpdir): -- cgit v1.2.1 From 87079b89cd471cb0c8f8415a0e3444c65596fbe3 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 17:25:10 +0000 Subject: Make the default template to ignore authors with empty changesets. --- default.chlog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/default.chlog b/default.chlog index ab5f97b..c127d4b 100644 --- a/default.chlog +++ b/default.chlog @@ -16,6 +16,13 @@ $line #end for #for $author in $rel.authors + #if $author.revisions and not $author.revisions[0].lines + #continue + #end if + ##alternatively, one could use: + ###if $author.email == "root" + ## #continue + ###end if + $author.name <$author.email> #for $rev in $author.revisions #for $line in $rev.lines -- cgit v1.2.1 From 61014d8ba27b0bb25d83c62c0da2404073c362b5 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 17:26:28 +0000 Subject: Implemented __repr__ for the classes _Release and _Revision in order to ease debugging. --- RepSys/log.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/RepSys/log.py b/RepSys/log.py index 24dca3c..b03e23d 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -90,6 +90,12 @@ class _Revision: def __init__(self, **kwargs): self.__dict__.update(kwargs) + def __repr__(self): + lines = repr(self.lines)[:30] + "...]" + line = "<_Revision %d author=%r date=%r lines=%s>" % \ + (self.revision, self.author, self.date, lines) + return line + class _Release(_Revision): version = None @@ -103,6 +109,11 @@ class _Release(_Revision): self.revisions = [] _Revision.__init__(self, **kwargs) + def __repr__(self): + line = "<_Release v=%s r=%s revs=%r>" % \ + (self.version, self.release, self.revisions) + return line + unescaped_macro_pat = re.compile(r"([^%])%([^%])") def escape_macros(text): -- cgit v1.2.1 From 8a62bcc2b2df3c6b8008c91083966ebc470f11ff Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 17:27:28 +0000 Subject: Added "putsrpm" to the list of subcommands in the --help message --- repsys | 1 + 1 file changed, 1 insertion(+) diff --git a/repsys b/repsys index 3ac7f81..bddbf71 100755 --- a/repsys +++ b/repsys @@ -18,6 +18,7 @@ Useful commands: rpmlog changed authoremail + putsrpm Run "repsys COMMAND --help" for more information. -- cgit v1.2.1 From 91700a68924f4b2e97a18f2c3787bd885c36640c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 17:28:55 +0000 Subject: Fixed regressions introduced in changelog generation while fixing the problem of package just imported. --- RepSys/log.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index b03e23d..f298e6f 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -151,8 +151,10 @@ class _Author: def group_releases_by_author(releases): allauthors = [] + grouped = [] for release in releases: authors = {} + latest = None for revision in release.revisions: authors.setdefault(revision.author, []).append(revision) @@ -165,7 +167,19 @@ def group_releases_by_author(releases): revdeco = [(r.revision, r) for r in revs] revdeco.sort(reverse=1) author.revisions = [t[1] for t in revdeco] - decorated.append((max(revdeco)[0], author)) + revlatest = author.revisions[0] + # keep the latest revision even for silented authors (below) + if latest is None or revlatest.revision > latest.revision: + latest = revlatest + count = sum(len(rev.lines) for rev in author.revisions) + if count == 0: + # skipping author with only silented lines + continue + decorated.append((revdeco[0][0], author)) + + if not decorated: + # skipping release with only authors with silented lines + continue decorated.sort(reverse=1) release.authors = [t[1] for t in decorated] @@ -176,12 +190,17 @@ def group_releases_by_author(releases): first, release.authors = release.authors[0], release.authors[1:] release.author_name = first.name release.author_email = first.email - release.date = first.revisions[0].date - release.raw_date = first.revisions[0].raw_date release.release_revisions = first.revisions - release.revision = first.revisions[0].revision - return releases + #release.date = first.revisions[0].date + release.date = latest.date + release.raw_date = latest.raw_date + #release.revision = first.revisions[0].revision + release.revision = latest.revision + + grouped.append(release) + + return grouped def group_revisions_by_author(currentlog): -- cgit v1.2.1 From 0b5ebe2e1b3becfd57c15dc3d585ffcd22b47076 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 17:39:28 +0000 Subject: Merged work on plugins support, including the possibility to wrap configuration sections. --- RepSys/ConfigParser.py | 43 +++++++++++++++++++++++++++++++++++++++---- RepSys/plugins/__init__.py | 27 +++++++++++++++++++++++++++ RepSys/plugins/sample.py.txt | 14 ++++++++++++++ repsys | 21 ++++++++++++++++++++- 4 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 RepSys/plugins/__init__.py create mode 100644 RepSys/plugins/sample.py.txt diff --git a/RepSys/ConfigParser.py b/RepSys/ConfigParser.py index c10b3a7..d995a57 100644 --- a/RepSys/ConfigParser.py +++ b/RepSys/ConfigParser.py @@ -348,6 +348,7 @@ import os class Config: def __init__(self): self._config = ConfigParser() + self._wrapped = {} conffiles = [] conffiles.append("/etc/repsys.conf") repsys_conf = os.environ.get("REPSYS_CONF") @@ -358,6 +359,14 @@ class Config: if os.path.isfile(file): self._config.read(file) + def wrap(self, section, handler, option=None): + """Set one wrapper for a given section + + The wrapper must be a function + f(section, option=None, default=None, walk=False). + """ + self._wrapped[section] = handler + def sections(self): try: return self._config.sections() @@ -373,10 +382,18 @@ class Config: def set(self, section, option, value): return self._config.set(section, option, value) - def walk(self, section, *args, **kwargs): - return self._config.walk(section, *args, **kwargs) - - def get(self, section, option, default=None): + def walk(self, section, option=None, raw=0, vars=None): + handler = self._wrapped.get(section) + if handler: + return handler(section, option, walk=True) + return self._config.walk(section, option, raw, vars) + + def get(self, section, option, default=None, wrap=True): + if wrap: + handler = self._wrapped.get(section) + if handler: + handler = self._wrapped.get(section) + return handler(section, option, default) try: return self._config.get(section, option) except Error: @@ -395,4 +412,22 @@ class Config: return states[ret.lower()] return default +def test(): + config = Config() + def handler(section, option=None, default=None, walk=False): + d = {"fulano": "ciclano", + "foolano": "ceeclano"} + if walk: + return d.items() + elif option in d: + return d[option] + else: + return config.get(section, option, default, wrap=False) + config.wrap("users", handler=handler) + print config.get("users", "fulano") # found in wrapper + print config.get("users", "andreas") # found in repsys.conf + print config.walk("users") + +if __name__ == "__main__": + test() # vim:ts=4:sw=4:et diff --git a/RepSys/plugins/__init__.py b/RepSys/plugins/__init__.py new file mode 100644 index 0000000..8bf4521 --- /dev/null +++ b/RepSys/plugins/__init__.py @@ -0,0 +1,27 @@ +import os + +loaded = {} + +def load(): + # based on smart's plugin system + pluginsdir = os.path.dirname(__file__) + for entry in os.listdir(pluginsdir): + if entry != "__init__.py" and entry.endswith(".py"): + name = entry[:-3] + loaded[name] = __import__("RepSys.plugins."+name, + fromlist=[name]) + elif os.path.isdir(entry): + initfile = os.path.join(entry, "__init__.py") + if os.path.isfile(initfile): + loaded[entry] = __import__("RepSys.plugins."+entry, + fromlist=[entry]) + +def list(): + return loaded.keys() + +def help(name): + from RepSys import Error + try: + return loaded[name].__doc__ + except KeyError: + raise Error, "plugin %s not found" % name diff --git a/RepSys/plugins/sample.py.txt b/RepSys/plugins/sample.py.txt new file mode 100644 index 0000000..9877f3c --- /dev/null +++ b/RepSys/plugins/sample.py.txt @@ -0,0 +1,14 @@ +# Sample repsys plugin. In order to test it, rename to sample.py +# vim:ft=python +from RepSys import config + +def users_wrapper(section, option=None, default=None, walk=False): + d = {"foolano": "Foolano De Tal ", + "ceeclano": "Ceeclano Algumacoisa ", + "beltrano": "Beltrano Bla "} + if walk: + return d.items() + + return d.get(option, default) + +config.wrap("users", handler=users_wrapper) diff --git a/repsys b/repsys index bddbf71..b266321 100755 --- a/repsys +++ b/repsys @@ -1,5 +1,5 @@ #!/usr/bin/python -from RepSys import Error +from RepSys import Error, plugins from RepSys.command import * import getopt import sys @@ -22,14 +22,32 @@ Useful commands: Run "repsys COMMAND --help" for more information. +Run "repsys --help-plugin" for help on loaded plugins. + Written by Gustavo Niemeyer """ +def plugin_help(opt, val, parser, mode): + if parser is None: + prog = sys.argv[0] + print "Use %s --help-plugin " % prog + print "Available plugins:" + print + for name in plugins.list(): + print name + else: + print plugins.help(parser) + raise SystemExit + def parse_options(): parser = OptionParser(help=HELP, version="%prog "+VERSION) parser.disable_interspersed_args() parser.add_option("--debug", action="store_true") + parser.add_option("--help-plugins", action="callback", callback=plugin_help) + parser.add_option("--help-plugin", type="string", dest="__ignore", + action="callback", callback=plugin_help) opts, args = parser.parse_args() + del opts.__ignore if len(args) < 1: parser.print_help(sys.stderr) sys.exit(1) @@ -52,6 +70,7 @@ def dispatch_command(command, argv, debug=0): command_module.main() if __name__ == "__main__": + plugins.load() do_command(parse_options, dispatch_command) # vim:et:ts=4:sw=4 -- cgit v1.2.1 From f76255fe3a7466748de56b422c048039ea59b077 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 17:41:56 +0000 Subject: Introduced the plugin "ldapusers". This plugin allows to obtain the user names and e-mails from a LDAP server. See repsys --help-plugin ldapusers for the configuration options. This plugin also required one small change in the ConfigParser: the class Config should allow one to get one option value in "raw" format, so that python format strings can be used as configuration values. --- RepSys/ConfigParser.py | 4 +- RepSys/plugins/ldapusers.py | 118 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 RepSys/plugins/ldapusers.py diff --git a/RepSys/ConfigParser.py b/RepSys/ConfigParser.py index d995a57..4dc3e3c 100644 --- a/RepSys/ConfigParser.py +++ b/RepSys/ConfigParser.py @@ -388,14 +388,14 @@ class Config: return handler(section, option, walk=True) return self._config.walk(section, option, raw, vars) - def get(self, section, option, default=None, wrap=True): + def get(self, section, option, default=None, raw=False, wrap=True): if wrap: handler = self._wrapped.get(section) if handler: handler = self._wrapped.get(section) return handler(section, option, default) try: - return self._config.get(section, option) + return self._config.get(section, option, raw=raw) except Error: return default diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py new file mode 100644 index 0000000..aa3438e --- /dev/null +++ b/RepSys/plugins/ldapusers.py @@ -0,0 +1,118 @@ +""" +A Repsys plugin for obtaining users from a LDAP server. + +In order to enable the plugin, the user must define the following +options in repsys.conf: + + ldap-server [required] + the host name of the LDAP server + ldap-port [optional] [default: 389] + the port of the LDAP server + ldap-base [required] + the base DN where the search will be performed + ldap-binddn [optional] [default: empty] + the DN used to bind + ldap-bindpw [optional] [default: empty] + the password used to bind + ldap-filterformat [optional] + [default: (&(objectClass=inetOrgPerson)(uid=%s))] + RFC-2254 filter string used in the search of the user entry. + Note that this is a python format string and will have the user + name as parameter. For example: + + ldap-filterformat = (&(objectClass=inetOrgPerson)(uid=%s)) + + Will result in the search filter: + + (&(objectClass=inetOrgPerson)(uid=john)) + + ldap-format [optional] [default: %(cn)s <%(mail)s>] + This is a python format string. This string will be + formatted using one dict object containing the fields + returned in the LDAP search, for example: + + >>> format = "%(cn)s <%(mail)s>" + >>> d = search(basedn, filter) + >>> d = {"cn": "John Doe", "mail": "john@mandriva.org", + "uidNumber": "1290", "loginShell": "/bin/bash", + ... many other attributes ... } + >>> value = format % d + >>> print value + John Doe + + Note that only the first value of the attributes will be + used. + +When the searched option is not found, it will try in repsys.conf. All +the values found. (including from repsys.conf) will be cached between +each configuration acess. + +This plugin requires the package python-ldap. + +For more information, look http://qa.mandriva.com/show_bug.cgi?id=30549 +""" +from RepSys import Error, config + +users_cache = {} + +def strip_entry(entry): + "Leave only the first value in all keys in the entry" + new = dict((key, value[0]) for key, value in entry.iteritems()) + return new + + +def make_handler(): + server = config.get("global", "ldap-server") + port = config.get("global", "ldap-port") + basedn = config.get("global", "ldap-base") + binddn = config.get("global", "ldap-binddn") + bindpw = config.get("global", "ldap-bindpw", "") + filterformat = config.get("global", "ldap-filterformat", + "(&(objectClass=inetOrgPerson)(uid=%s))", raw=1) + format = config.get("global", "ldap-format", "%(cn)s <%(mail)s>", raw=1) + + if server is None: + def dummy_wrapper(section, option=None, default=None, walk=False): + return config.get(section, option, default, wrap=False) + return dummy_wrapper + + # only load ldap if it is enabled in configuration, this way we don't + # require everyone to have python-ldap installed + import ldap + + def users_wrapper(section, option=None, default=None, walk=False): + global users_cache + if walk: + raise Error, "ldapusers plugin does not support user listing" + assert option is not None, \ + "When not section walking, option is required" + + value = users_cache.get(option) + if value is not None: + return value + + l = ldap.open(server) + if binddn: + l.bind(binddn, bindpw) + filter = filterformat % option + found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter) + if found: + dn, entry = found[0] + entry = strip_entry(entry) + try: + value = format % entry + except KeyError, e: + raise Error, "the key %s was not found in LDAP search, " \ + "check your ldap-format configuration" % e + except (TypeError, ValueError), e: + raise Error, "LDAP response formatting error: %s. Check " \ + "your ldap-format configuration" % e + else: + # issue a warning? + value = config.get(section, option, default, wrap=False) + users_cache[option] = value + return value + + return users_wrapper + +config.wrap("users", handler=make_handler()) -- cgit v1.2.1 From 3e164b5a8a34bd0363cca48c88fecfd58c59cdbe Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 18:04:42 +0000 Subject: Typo "acess" --- RepSys/plugins/ldapusers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index aa3438e..ed35c9e 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -45,7 +45,7 @@ options in repsys.conf: When the searched option is not found, it will try in repsys.conf. All the values found. (including from repsys.conf) will be cached between -each configuration acess. +each configuration access. This plugin requires the package python-ldap. -- cgit v1.2.1 From 7e9626635a79bb01fed4223de082cd9bb4c977f1 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 18:05:03 +0000 Subject: Version 1.6.16 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index b266321..9b3bbc7 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.15" +VERSION="1.6.16" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 45f141e9a450a715a99ff78e56db527c7988da48 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 18:31:14 +0000 Subject: Added plugins directory to setup.py and MANIFEST.in --- MANIFEST.in | 1 + setup.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 03bd9ea..c3ff6e8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ recursive-include RepSys *.py +include RepSys/plugins/*.txt include repsys repsys.conf MANIFEST.in include *.chlog include rebrand-mdk create-srpm getsrpm-mdk diff --git a/setup.py b/setup.py index 272ec84..7c4814c 100755 --- a/setup.py +++ b/setup.py @@ -18,7 +18,8 @@ setup(name="repsys", url = "http://qa.mandriva.com/twiki/bin/view/Main/RepositorySystem", license = "GPL", long_description = """Tools for Mandriva Linux repository access and management.""", - packages = ["RepSys", "RepSys.cgi", "RepSys.commands"], + packages = ["RepSys", "RepSys.cgi", "RepSys.commands", + "RepSys.plugins"], scripts = ["repsys", "getsrpm-mdk"], data_files = [ ("/usr/share/repsys/", -- cgit v1.2.1 From e8fd7da285d715ee6f2fb423ca58c01dae462f67 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 18:43:21 +0000 Subject: Typo "--help-plugin" --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 9b3bbc7..c83e04d 100755 --- a/repsys +++ b/repsys @@ -22,7 +22,7 @@ Useful commands: Run "repsys COMMAND --help" for more information. -Run "repsys --help-plugin" for help on loaded plugins. +Run "repsys --help-plugins" for help on loaded plugins. Written by Gustavo Niemeyer """ -- cgit v1.2.1 From 489c2e387450a86a8bc8260995d39d2af93e6daf Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 18:55:38 +0000 Subject: Added reference to the [global] section in the help of ldapusers plugin. --- RepSys/plugins/ldapusers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index ed35c9e..43d8745 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -2,7 +2,7 @@ A Repsys plugin for obtaining users from a LDAP server. In order to enable the plugin, the user must define the following -options in repsys.conf: +options the [global] section of repsys.conf: ldap-server [required] the host name of the LDAP server -- cgit v1.2.1 From a0db56024d803cbe112ce31d8de2aa2701a5d79c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 19:01:18 +0000 Subject: Yet another typo: "options IN the [global] section" --- RepSys/plugins/ldapusers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 43d8745..0c7a6e3 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -2,7 +2,7 @@ A Repsys plugin for obtaining users from a LDAP server. In order to enable the plugin, the user must define the following -options the [global] section of repsys.conf: +options in the [global] section of repsys.conf: ldap-server [required] the host name of the LDAP server -- cgit v1.2.1 From 2e0c7def5895fea29177718abb690b75bc21695e Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 2 May 2007 19:41:47 +0000 Subject: Added initial support to mirrors, as requested by mrl. It was added an option "mirror" to repsys.conf, that will contain an URL to the mirror repository. Also added the subcommand "ci", which will relocate one working copy to the master repository before effectively commiting. --- RepSys/commands/ci.py | 29 +++++++++++++++++++++++++++++ RepSys/mirror.py | 42 ++++++++++++++++++++++++++++++++++++++++++ RepSys/rpmutil.py | 24 ++++++++++++++++++++++++ RepSys/svn.py | 19 +++++++++++++++++++ repsys | 1 + repsys.conf | 1 + 6 files changed, 116 insertions(+) create mode 100644 RepSys/commands/ci.py create mode 100644 RepSys/mirror.py diff --git a/RepSys/commands/ci.py b/RepSys/commands/ci.py new file mode 100644 index 0000000..9ffa3bd --- /dev/null +++ b/RepSys/commands/ci.py @@ -0,0 +1,29 @@ +#!/usr/bin/python +from RepSys.command import * +from RepSys.rpmutil import commit + +HELP = """\ +Usage: repsys ci [TARGET] + +Will commit a change. The difference between an ordinary "svn ci" and +"repsys ci" is that it relocates the working copy to the default repository +in case the option "mirror" is set in repsys.conf. + +Options: + -h Show this message + +Examples: + repsys ci + repsys ci SPECS/package.spec SPECS/package-patch.patch +""" + +def parse_options(): + parser = OptionParser(help=HELP) + parser.add_option("-m", dest="message", default=None) + opts, args = parser.parse_args() + if len(args): + opts.target = args[0] + return opts + +def main(): + do_command(parse_options, commit) diff --git a/RepSys/mirror.py b/RepSys/mirror.py new file mode 100644 index 0000000..a24f594 --- /dev/null +++ b/RepSys/mirror.py @@ -0,0 +1,42 @@ +import os +import urlparse + +from RepSys import config +from RepSys.svn import SVN + +def relocate_path(oldparent, newparent, url): + subpath = url[len(oldparent)-1:] + newurl = newparent + "/" + subpath # subpath usually gets / at begining + return newurl + +def enabled(): + mirror = config.get("global", "mirror") + default_parent = config.get("global", "default_parent") + return (mirror is not None and + default_parent is not None) + +def mirror_relocate(oldparent, newparent, url, wcpath): + svn = SVN(noauth=True) + newurl = relocate_path(oldparent, newparent, url) + svn.switch(newurl, url, path=wcpath, relocate="True") + return newurl + +def switchto_parent(svn, url, path): + """Relocates the working copy to default_parent""" + mirror = config.get("global", "mirror") + default_parent = config.get("global", "default_parent") + newurl = mirror_relocate(mirror, default_parent, url, path) + return newurl + +def switchto_mirror(svn, url, path): + mirror = config.get("global", "mirror") + default_parent = config.get("global", "default_parent") + newurl = mirror_relocate(default_parent, mirror, url, path) + return newurl + +def checkout_url(url): + mirror = config.get("global", "mirror") + default_parent = config.get("global", "default_parent") + if mirror is not None and default_parent is not None: + return relocate_path(default_parent, mirror, url) + return url diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 367fd45..12a8226 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -1,5 +1,6 @@ #!/usr/bin/python from RepSys import Error, config, RepSysTree +from RepSys import mirror from RepSys.svn import SVN from RepSys.rpm import SRPM from RepSys.log import specfile_svn2rpm @@ -357,8 +358,31 @@ def checkout(pkgdirurl, path=None, revision=None): current = os.path.join(pkgdirurl, "current") if path is None: _, path = os.path.split(pkgdirurl) + if mirror.enabled(): + current = mirror.checkout_url(current) + print "checking out from mirror", current svn.checkout(current, path, rev=revision, show=1) +def commit(target=".", message=None): + svn = SVN(noauth=True) + info = svn.info2(target) + url = info.get("URL") + if url is None: + raise Error, "working copy URL not provided by svn info" + if mirror.enabled(): + newurl = mirror.switchto_parent(svn, url, target) + print "relocated to", newurl + try: + # we can't use the svn object here because pexpect hides VISUAL + mopt = "" + if message is not None: + mopt = "-m \"%s\"" % message + os.system("svn ci %s %s" % (mopt, target)) + finally: + if mirror.enabled(): + mirror.switchto_mirror(svn, newurl, target) + print "relocated back to", url + def get_submit_info(path): path = os.path.abspath(path) diff --git a/RepSys/svn.py b/RepSys/svn.py index 4e073dc..a13db8b 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -169,6 +169,12 @@ class SVN: if status == 0: return output.splitlines() return None + + def info2(self, *args, **kwargs): + lines = self.info(*args, **kwargs) + pairs = [[w.strip() for w in line.split(":", 1)] for line in lines] + info = dict(pairs) + return info def ls(self, path, **kwargs): cmd = ["ls", path] @@ -197,6 +203,19 @@ class SVN: return [x.split() for x in output.split()] return None + def switch(self, url, oldurl=None, path=None, relocate=False, **kwargs): + cmd = ["switch"] + if relocate: + if oldurl is None: + raise Error, "You must supply the old URL when "\ + "relocating working copies" + cmd.append("--relocate") + cmd.append(oldurl) + cmd.append(url) + if path is not None: + cmd.append(path) + return self._execsvn_success(*cmd, **kwargs) + def update(self, path, **kwargs): cmd = ["update", path] self._add_revision(cmd, kwargs, optional=1) diff --git a/repsys b/repsys index c83e04d..2157308 100755 --- a/repsys +++ b/repsys @@ -11,6 +11,7 @@ Usage: repsys COMMAND [COMMAND ARGUMENTS] Useful commands: co + ci submit create getspec diff --git a/repsys.conf b/repsys.conf index dce1fe3..87013b0 100644 --- a/repsys.conf +++ b/repsys.conf @@ -2,6 +2,7 @@ verbose = no default_parent = svn+ssh://svn.mandriva.com/svn/packages/cooker url-map = svn\+ssh://svn\.mandriva\.com/(.*) file:///\1 +#mirror = http://svn.mandriva.com/svn/packages/cooker/ #tempdir = /tmp [log] -- cgit v1.2.1 From 42c90df281ab88f947852729ffc77dac98a9f1a1 Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Thu, 3 May 2007 17:11:47 +0000 Subject: - added readme file for ldap support --- README.LDAP | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 README.LDAP diff --git a/README.LDAP b/README.LDAP new file mode 100644 index 0000000..05260f5 --- /dev/null +++ b/README.LDAP @@ -0,0 +1,51 @@ +A Repsys plugin for obtaining users from a LDAP server. + +In order to enable the plugin, the user must define the following +options in the [global] section of repsys.conf: + + ldap-server [required] + the host name of the LDAP server + ldap-port [optional] [default: 389] + the port of the LDAP server + ldap-base [required] + the base DN where the search will be performed + ldap-binddn [optional] [default: empty] + the DN used to bind + ldap-bindpw [optional] [default: empty] + the password used to bind + ldap-filterformat [optional] + [default: (&(objectClass=inetOrgPerson)(uid=%s))] + RFC-2254 filter string used in the search of the user entry. + Note that this is a python format string and will have the user + name as parameter. For example: + + ldap-filterformat = (&(objectClass=inetOrgPerson)(uid=%s)) + + Will result in the search filter: + + (&(objectClass=inetOrgPerson)(uid=john)) + + ldap-format [optional] [default: %(cn)s <%(mail)s>] + This is a python format string. This string will be + formatted using one dict object containing the fields + returned in the LDAP search, for example: + + >>> format = "%(cn)s <%(mail)s>" + >>> d = search(basedn, filter) + >>> d = {"cn": "John Doe", "mail": "john@mandriva.org", + "uidNumber": "1290", "loginShell": "/bin/bash", + ... many other attributes ... } + >>> value = format % d + >>> print value + John Doe + + Note that only the first value of the attributes will be + used. + +When the searched option is not found, it will try in repsys.conf. All +the values found (including from repsys.conf) will be cached between +each configuration access. + +This plugin requires the package python-ldap. + +For more information, look http://qa.mandriva.com/show_bug.cgi?id=30549 -- cgit v1.2.1 From c7db0f3a0c0a561225355456922a34e8ee0092af Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Thu, 3 May 2007 17:19:21 +0000 Subject: - better emptylog message --- default.chlog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.chlog b/default.chlog index c127d4b..f8f1ec5 100644 --- a/default.chlog +++ b/default.chlog @@ -7,7 +7,7 @@ ##+ Status: not released #end if #if not $rel.visible -+ EMPTYLOG: Man is the only animal that blushes -- or needs to. -- Mark Twain ++ rebuild (emptylog) #end if #for $rev in $rel.release_revisions #for $line in $rev.lines -- cgit v1.2.1 From c6d5c4798d57d88d13292810639e985e6a08aff3 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 20:46:44 +0000 Subject: Warn when python-ldap is not installed and the user is really trying to use the plugin. --- RepSys/plugins/ldapusers.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 0c7a6e3..7f08f56 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -76,9 +76,11 @@ def make_handler(): return config.get(section, option, default, wrap=False) return dummy_wrapper - # only load ldap if it is enabled in configuration, this way we don't - # require everyone to have python-ldap installed - import ldap + try: + import ldap + except ImportError: + raise Error, "LDAP support needs the python-ldap package "\ + "to be installed" def users_wrapper(section, option=None, default=None, walk=False): global users_cache -- cgit v1.2.1 From 2779c2048793ba84e291bffc6554f5cc5cbe39e2 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 20:47:35 +0000 Subject: As requested by Andreas, handle LDAP exceptions and provide better error messages. Also improved format error messages a bit. --- RepSys/plugins/ldapusers.py | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 7f08f56..3b83ae2 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -55,11 +55,28 @@ from RepSys import Error, config users_cache = {} +class LDAPError(Error): + def __init__(self, ldaperr): + self.ldaperr = ldaperr + name = ldaperr.__class__.__name__ + desc = ldaperr.message["desc"] + self.message = "LDAP error %s: %s" % (name, desc) + self.args = self.message, + def strip_entry(entry): "Leave only the first value in all keys in the entry" new = dict((key, value[0]) for key, value in entry.iteritems()) return new +def interpolate(optname, format, data): + try: + return format % data + except KeyError, e: + raise Error, "the key %s was not found in LDAP search, " \ + "check your %s configuration" % (e, optname) + except (TypeError, ValueError), e: + raise Error, "LDAP response formatting error: %s. Check " \ + "your %s configuration" % (e, optname) def make_handler(): server = config.get("global", "ldap-server") @@ -93,22 +110,22 @@ def make_handler(): if value is not None: return value - l = ldap.open(server) - if binddn: - l.bind(binddn, bindpw) - filter = filterformat % option - found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter) + try: + l = ldap.open(server) + if binddn: + l.bind(binddn, bindpw) + except ldap.LDAPError, e: + raise LDAPError(e) + + filter = interpolate("ldap-filterformat", filterformat, option) + try: + found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter) + except ldap.LDAPError, e: + raise LDAPError(e) if found: dn, entry = found[0] entry = strip_entry(entry) - try: - value = format % entry - except KeyError, e: - raise Error, "the key %s was not found in LDAP search, " \ - "check your ldap-format configuration" % e - except (TypeError, ValueError), e: - raise Error, "LDAP response formatting error: %s. Check " \ - "your ldap-format configuration" % e + value = interpolate("ldap-format", format, entry) else: # issue a warning? value = config.get(section, option, default, wrap=False) -- cgit v1.2.1 From 566f7d59b539ae76271486c5deb2fab738e67bba Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 20:48:13 +0000 Subject: Fixed the option "ldap-port", which was not being used. --- RepSys/plugins/ldapusers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 3b83ae2..34551ea 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -80,7 +80,7 @@ def interpolate(optname, format, data): def make_handler(): server = config.get("global", "ldap-server") - port = config.get("global", "ldap-port") + port = config.get("global", "ldap-port", 389) basedn = config.get("global", "ldap-base") binddn = config.get("global", "ldap-binddn") bindpw = config.get("global", "ldap-bindpw", "") @@ -111,7 +111,7 @@ def make_handler(): return value try: - l = ldap.open(server) + l = ldap.open(server, port) if binddn: l.bind(binddn, bindpw) except ldap.LDAPError, e: -- cgit v1.2.1 From 0833f46a1926dfe84abf75ad21e8fdf2e1d0736f Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 20:48:49 +0000 Subject: Changed the interpolation method. Now variable are defined with $name. not %(name)s. Things may break. --- RepSys/plugins/ldapusers.py | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 34551ea..e3f696c 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -15,28 +15,29 @@ options in the [global] section of repsys.conf: ldap-bindpw [optional] [default: empty] the password used to bind ldap-filterformat [optional] - [default: (&(objectClass=inetOrgPerson)(uid=%s))] + [default: (&(objectClass=inetOrgPerson)(uid=$username))] RFC-2254 filter string used in the search of the user entry. - Note that this is a python format string and will have the user - name as parameter. For example: + Note that this is a python template string and will have the + user name as parameter. For example: - ldap-filterformat = (&(objectClass=inetOrgPerson)(uid=%s)) + ldap-filterformat = (&(objectClass=inetOrgPerson)(uid=$username)) Will result in the search filter: (&(objectClass=inetOrgPerson)(uid=john)) - ldap-format [optional] [default: %(cn)s <%(mail)s>] - This is a python format string. This string will be + ldap-format [optional] [default: $cn <$mail>] + This is a python template string. This string will be formatted using one dict object containing the fields returned in the LDAP search, for example: - >>> format = "%(cn)s <%(mail)s>" + >>> format = Template("$cn <$mail>") >>> d = search(basedn, filter) - >>> d = {"cn": "John Doe", "mail": "john@mandriva.org", - "uidNumber": "1290", "loginShell": "/bin/bash", - ... many other attributes ... } - >>> value = format % d + >>> d + {"cn": "John Doe", "mail": "john@mandriva.org", + "uidNumber": "1290", "loginShell": "/bin/bash", + ... many other attributes ... } + >>> value = format.substitute(d) >>> print value John Doe @@ -53,6 +54,8 @@ For more information, look http://qa.mandriva.com/show_bug.cgi?id=30549 """ from RepSys import Error, config +import string + users_cache = {} class LDAPError(Error): @@ -69,8 +72,9 @@ def strip_entry(entry): return new def interpolate(optname, format, data): + tmpl = string.Template(format) try: - return format % data + return tmpl.substitute(data) except KeyError, e: raise Error, "the key %s was not found in LDAP search, " \ "check your %s configuration" % (e, optname) @@ -85,8 +89,8 @@ def make_handler(): binddn = config.get("global", "ldap-binddn") bindpw = config.get("global", "ldap-bindpw", "") filterformat = config.get("global", "ldap-filterformat", - "(&(objectClass=inetOrgPerson)(uid=%s))", raw=1) - format = config.get("global", "ldap-format", "%(cn)s <%(mail)s>", raw=1) + "(&(objectClass=inetOrgPerson)(uid=$username))", raw=1) + format = config.get("global", "ldap-format", "$cn <$mail>", raw=1) if server is None: def dummy_wrapper(section, option=None, default=None, walk=False): @@ -117,7 +121,8 @@ def make_handler(): except ldap.LDAPError, e: raise LDAPError(e) - filter = interpolate("ldap-filterformat", filterformat, option) + data = {"username": option} + filter = interpolate("ldap-filterformat", filterformat, data) try: found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter) except ldap.LDAPError, e: -- cgit v1.2.1 From adb75a7908bd19535ca6ba1d8cc6363a3a1530c8 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 20:49:28 +0000 Subject: Changed the configuration field ldap-format to ldap-resultformat, more consistent with ldap-filterformat. --- RepSys/plugins/ldapusers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index e3f696c..7eb6a09 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -26,7 +26,7 @@ options in the [global] section of repsys.conf: (&(objectClass=inetOrgPerson)(uid=john)) - ldap-format [optional] [default: $cn <$mail>] + ldap-resultformat [optional] [default: $cn <$mail>] This is a python template string. This string will be formatted using one dict object containing the fields returned in the LDAP search, for example: @@ -90,7 +90,7 @@ def make_handler(): bindpw = config.get("global", "ldap-bindpw", "") filterformat = config.get("global", "ldap-filterformat", "(&(objectClass=inetOrgPerson)(uid=$username))", raw=1) - format = config.get("global", "ldap-format", "$cn <$mail>", raw=1) + format = config.get("global", "ldap-resultformat", "$cn <$mail>", raw=1) if server is None: def dummy_wrapper(section, option=None, default=None, walk=False): @@ -130,7 +130,7 @@ def make_handler(): if found: dn, entry = found[0] entry = strip_entry(entry) - value = interpolate("ldap-format", format, entry) + value = interpolate("ldap-resultformat", format, entry) else: # issue a warning? value = config.get(section, option, default, wrap=False) -- cgit v1.2.1 From 25406a36a7e418fdb8a3953671549582e26d5c45 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 20:50:01 +0000 Subject: As noted by Andreas, LDAP search results can have only the needed attributes of ldap-resultformat. Fixed it. --- RepSys/plugins/ldapusers.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 7eb6a09..371a2a8 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -82,6 +82,18 @@ def interpolate(optname, format, data): raise Error, "LDAP response formatting error: %s. Check " \ "your %s configuration" % (e, optname) +def used_attributes(format): + class DummyDict: + def __init__(self): + self.found = [] + def __getitem__(self, key): + self.found.append(key) + return key + dd = DummyDict() + t = string.Template(format) + t.safe_substitute(dd) + return dd.found + def make_handler(): server = config.get("global", "ldap-server") port = config.get("global", "ldap-port", 389) @@ -123,8 +135,10 @@ def make_handler(): data = {"username": option} filter = interpolate("ldap-filterformat", filterformat, data) + attrs = used_attributes(format) try: - found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter) + found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter, + attrlist=attrs) except ldap.LDAPError, e: raise LDAPError(e) if found: -- cgit v1.2.1 From 023b84f8f91df6f3062ff2992d1ebe3e94254532 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 20:50:43 +0000 Subject: Updated README.LDAP to recent changes in configuration options (ldap-format and format method used) --- README.LDAP | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.LDAP b/README.LDAP index 05260f5..863be6d 100644 --- a/README.LDAP +++ b/README.LDAP @@ -14,28 +14,29 @@ options in the [global] section of repsys.conf: ldap-bindpw [optional] [default: empty] the password used to bind ldap-filterformat [optional] - [default: (&(objectClass=inetOrgPerson)(uid=%s))] + [default: (&(objectClass=inetOrgPerson)(uid=$username))] RFC-2254 filter string used in the search of the user entry. - Note that this is a python format string and will have the user - name as parameter. For example: + Note that this is a python template string and will have the + user name as parameter. For example: - ldap-filterformat = (&(objectClass=inetOrgPerson)(uid=%s)) + ldap-filterformat = (&(objectClass=inetOrgPerson)(uid=$username)) Will result in the search filter: (&(objectClass=inetOrgPerson)(uid=john)) - ldap-format [optional] [default: %(cn)s <%(mail)s>] - This is a python format string. This string will be + ldap-resultformat [optional] [default: $cn <$mail>] + This is a python template string. This string will be formatted using one dict object containing the fields returned in the LDAP search, for example: - >>> format = "%(cn)s <%(mail)s>" + >>> format = Template("$cn <$mail>") >>> d = search(basedn, filter) - >>> d = {"cn": "John Doe", "mail": "john@mandriva.org", - "uidNumber": "1290", "loginShell": "/bin/bash", - ... many other attributes ... } - >>> value = format % d + >>> d + {"cn": "John Doe", "mail": "john@mandriva.org", + "uidNumber": "1290", "loginShell": "/bin/bash", + ... many other attributes ... } + >>> value = format.substitute(d) >>> print value John Doe @@ -43,7 +44,7 @@ options in the [global] section of repsys.conf: used. When the searched option is not found, it will try in repsys.conf. All -the values found (including from repsys.conf) will be cached between +the values found. (including from repsys.conf) will be cached between each configuration access. This plugin requires the package python-ldap. -- cgit v1.2.1 From 928b0bed6fff9a002fcd10533fd1fa464e1bc10b Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 21:03:27 +0000 Subject: Added one cheap copy of the sync subcommand from mdvsys. It required two sensitive changes: - in order to parse the spec file, "rpm" module was used, so this is the brand new package dependency; and - as RepSys already had one "rpm" module, we had to rename it to "simplerpm" in order to allow access to the module from python-rpm (I think py2.4 is still used a lot so we can't use absolute imports) --- RepSys/commands/markrelease.py | 2 +- RepSys/commands/sync.py | 31 ++++++++++++++++++++++++ RepSys/rpm.py | 19 --------------- RepSys/rpmutil.py | 54 +++++++++++++++++++++++++++++++++++++++++- RepSys/simplerpm.py | 19 +++++++++++++++ RepSys/svn.py | 2 ++ repsys | 1 + repsys.spec | 2 +- 8 files changed, 108 insertions(+), 22 deletions(-) create mode 100644 RepSys/commands/sync.py delete mode 100644 RepSys/rpm.py create mode 100644 RepSys/simplerpm.py diff --git a/RepSys/commands/markrelease.py b/RepSys/commands/markrelease.py index 9e52a31..440775b 100644 --- a/RepSys/commands/markrelease.py +++ b/RepSys/commands/markrelease.py @@ -9,7 +9,7 @@ # from RepSys import Error from RepSys.command import * -from RepSys.rpm import SRPM +from RepSys.simplerpm import SRPM from RepSys.rpmutil import mark_release from RepSys.util import get_auth import getopt diff --git a/RepSys/commands/sync.py b/RepSys/commands/sync.py new file mode 100644 index 0000000..42ede8d --- /dev/null +++ b/RepSys/commands/sync.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +from RepSys.command import * +from RepSys.rpmutil import sync + +HELP = """\ +Usage: repsys sync + +Will add or removed from the working copy new files added or removed +from the spec file. + +"No changes are commited." + +Options: + --dry-run Print results without changing the working copy + -h Show this message + +Examples: + repsys sync +""" + +def parse_options(): + parser = OptionParser(help=HELP) + parser.add_option("--dry-run", dest="dryrun", default=False, + action="store_true") + opts, args = parser.parse_args() + if len(args): + opts.target = args[0] + return opts + +def main(): + do_command(parse_options, sync) diff --git a/RepSys/rpm.py b/RepSys/rpm.py deleted file mode 100644 index d448c5f..0000000 --- a/RepSys/rpm.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/python -from RepSys.util import execcmd - -class SRPM: - def __init__(self, filename): - self.filename = filename - self._getinfo() - - def _getinfo(self): - cmdstr = "rpm -qp --qf '%%{name} %%{epoch} %%{release} %%{version}' %s" - status, output = execcmd(cmdstr % self.filename) - self.name, self.epoch, self.release, self.version = output.split() - if self.epoch == "(none)": - self.epoch = None - - def unpack(self, topdir): - execcmd("rpm -i --define '_topdir %s' %s" % (topdir, self.filename)) - -# vim:et:ts=4:sw=4 diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 12a8226..651d19f 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -2,9 +2,10 @@ from RepSys import Error, config, RepSysTree from RepSys import mirror from RepSys.svn import SVN -from RepSys.rpm import SRPM +from RepSys.simplerpm import SRPM from RepSys.log import specfile_svn2rpm from RepSys.util import execcmd +import rpm import tempfile import shutil import glob @@ -363,6 +364,57 @@ def checkout(pkgdirurl, path=None, revision=None): print "checking out from mirror", current svn.checkout(current, path, rev=revision, show=1) +def sync(dryrun=False): + svn = SVN(noauth=True) + cwd = os.getcwd() + dirname = os.path.basename(cwd) + if dirname == "SPECS" or dirname == "SOURCES": + topdir = os.pardir + else: + topdir = "" + specsdir = os.path.join(topdir, "SPECS/") + sourcesdir = os.path.join(topdir, "SOURCES/") + for path in (specsdir, sourcesdir): + if not os.path.isdir(path): + raise Error, "%s directory not found" % path + specs = glob.glob(os.path.join(specsdir, "*.spec")) + if not specs: + raise Error, "no .spec files found in %s" % specsdir + specpath = specs[0] # FIXME better way? + try: + spec = rpm.TransactionSet().parseSpec(specpath) + except rpm.error, e: + raise Error, "could not load spec file: %s" % e + sources = [name for name, x, y in spec.sources()] + sourcesst = dict((os.path.basename(path), st) + for st, path in svn.status(sourcesdir, noignore=True)) + toadd = [] + for source in sources: + sourcepath = os.path.join(sourcesdir, source) + if sourcesst.get(source): + if os.path.isfile(sourcepath): + toadd.append(sourcepath) + else: + sys.stderr.write("warning: %s not found\n" % sourcepath) + # rm entries not found in sources and still in svn + found = os.listdir(sourcesdir) + toremove = [] + for entry in found: + if entry == ".svn": + continue + status = sourcesst.get(entry) + if status is None and entry not in sources: + path = os.path.join(sourcesdir, entry) + toremove.append(path) + for path in toremove: + print "D\t%s" % path + if not dryrun: + svn.remove(path, local=True) + for path in toadd: + print "A\t%s" % path + if not dryrun: + svn.add(path, local=True) + def commit(target=".", message=None): svn = SVN(noauth=True) info = svn.info2(target) diff --git a/RepSys/simplerpm.py b/RepSys/simplerpm.py new file mode 100644 index 0000000..d448c5f --- /dev/null +++ b/RepSys/simplerpm.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +from RepSys.util import execcmd + +class SRPM: + def __init__(self, filename): + self.filename = filename + self._getinfo() + + def _getinfo(self): + cmdstr = "rpm -qp --qf '%%{name} %%{epoch} %%{release} %%{version}' %s" + status, output = execcmd(cmdstr % self.filename) + self.name, self.epoch, self.release, self.version = output.split() + if self.epoch == "(none)": + self.epoch = None + + def unpack(self, topdir): + execcmd("rpm -i --define '_topdir %s' %s" % (topdir, self.filename)) + +# vim:et:ts=4:sw=4 diff --git a/RepSys/svn.py b/RepSys/svn.py index a13db8b..b4ad4e9 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -187,6 +187,8 @@ class SVN: cmd = ["status", path] if kwargs.get("verbose"): cmd.append("-v") + if kwargs.get("noignore"): + cmd.append("--no-ignore") status, output = self._execsvn(*cmd, **kwargs) if status == 0: return [x.split() for x in output.splitlines()] diff --git a/repsys b/repsys index 2157308..c2f18f4 100755 --- a/repsys +++ b/repsys @@ -12,6 +12,7 @@ Usage: repsys COMMAND [COMMAND ARGUMENTS] Useful commands: co ci + sync submit create getspec diff --git a/repsys.spec b/repsys.spec index 81e251a..edb0cf8 100644 --- a/repsys.spec +++ b/repsys.spec @@ -12,7 +12,7 @@ Buildrequires: python-devel BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRequires: python BuildRequires: python-devel -Requires: python-cheetah +Requires: python-cheetah python-rpm %description Tools for Mandriva Linux repository access and management. -- cgit v1.2.1 From dfa646e76fee3922bc4590296008772233546f1d Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 3 May 2007 21:19:30 +0000 Subject: Added README.LDAP to MANIFEST.in --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index c3ff6e8..1264d01 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ recursive-include RepSys *.py include RepSys/plugins/*.txt include repsys repsys.conf MANIFEST.in +include README.LDAP include *.chlog include rebrand-mdk create-srpm getsrpm-mdk -- cgit v1.2.1 From bb28432a1586891f9edb791729d6027676e05231 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 14:15:27 +0000 Subject: The option ldap-port was not being converted to integer. Fixed. --- RepSys/plugins/ldapusers.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 371a2a8..b43862b 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -96,7 +96,11 @@ def used_attributes(format): def make_handler(): server = config.get("global", "ldap-server") - port = config.get("global", "ldap-port", 389) + try: + port = int(config.get("global", "ldap-port", 389)) + except ValueError: + raise Error, "the option ldap-port requires an integer, please "\ + "check your configuration files" basedn = config.get("global", "ldap-base") binddn = config.get("global", "ldap-binddn") bindpw = config.get("global", "ldap-bindpw", "") -- cgit v1.2.1 From e04d72f060b1a8257bab955f6c0931989d546f99 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 14:16:30 +0000 Subject: Handle plugin initialization exceptions Moved plugins.load() to dispatch_command in order to allow exception handling when plugins are being loaded (in case of ldapusers, checking configuration options) --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index c2f18f4..baf015f 100755 --- a/repsys +++ b/repsys @@ -69,10 +69,10 @@ def dispatch_command(command, argv, debug=0): traceback.print_exc() sys.exit(1) raise Error, "invalid command '%s'" % command + plugins.load() command_module.main() if __name__ == "__main__": - plugins.load() do_command(parse_options, dispatch_command) # vim:et:ts=4:sw=4 -- cgit v1.2.1 From bd030af75529f0f6344252983a9a1f434baedf6b Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 15:49:18 +0000 Subject: Unbind the ldapobject after searching. --- RepSys/plugins/ldapusers.py | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index b43862b..6471f58 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -136,24 +136,26 @@ def make_handler(): l.bind(binddn, bindpw) except ldap.LDAPError, e: raise LDAPError(e) - - data = {"username": option} - filter = interpolate("ldap-filterformat", filterformat, data) - attrs = used_attributes(format) try: - found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter, - attrlist=attrs) - except ldap.LDAPError, e: - raise LDAPError(e) - if found: - dn, entry = found[0] - entry = strip_entry(entry) - value = interpolate("ldap-resultformat", format, entry) - else: - # issue a warning? - value = config.get(section, option, default, wrap=False) - users_cache[option] = value - return value + data = {"username": option} + filter = interpolate("ldap-filterformat", filterformat, data) + attrs = used_attributes(format) + try: + found = l.search_s(basedn, ldap.SCOPE_SUBTREE, filter, + attrlist=attrs) + except ldap.LDAPError, e: + raise LDAPError(e) + if found: + dn, entry = found[0] + entry = strip_entry(entry) + value = interpolate("ldap-resultformat", format, entry) + else: + # issue a warning? + value = config.get(section, option, default, wrap=False) + users_cache[option] = value + return value + finally: + l.unbind_s() return users_wrapper -- cgit v1.2.1 From 17ec0273c2fd7c183782672e910f31d20b52abe7 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 15:50:33 +0000 Subject: Escape values used in LDAP search filters using ldap.filter. --- RepSys/plugins/ldapusers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 6471f58..75d362c 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -118,6 +118,8 @@ def make_handler(): except ImportError: raise Error, "LDAP support needs the python-ldap package "\ "to be installed" + else: + from ldap.filter import escape_filter_chars def users_wrapper(section, option=None, default=None, walk=False): global users_cache @@ -137,7 +139,7 @@ def make_handler(): except ldap.LDAPError, e: raise LDAPError(e) try: - data = {"username": option} + data = {"username": escape_filter_chars(option)} filter = interpolate("ldap-filterformat", filterformat, data) attrs = used_attributes(format) try: -- cgit v1.2.1 From 5e5972ab96383c272af7fe01560a052fec8bacfa Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 18:01:20 +0000 Subject: Use basename of source entries, they may be URLs (and flags don't make clear if it is a URL or not) --- RepSys/rpmutil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 651d19f..a8d0b4a 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -385,7 +385,8 @@ def sync(dryrun=False): spec = rpm.TransactionSet().parseSpec(specpath) except rpm.error, e: raise Error, "could not load spec file: %s" % e - sources = [name for name, x, y in spec.sources()] + sources = [os.path.basename(name) + for name, no, flags in spec.sources()] sourcesst = dict((os.path.basename(path), st) for st, path in svn.status(sourcesdir, noignore=True)) toadd = [] -- cgit v1.2.1 From 411828bbd6fa8b204f1730db8e9d34190b708e58 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 18:02:43 +0000 Subject: Run svn.info before svn.status in order to check if we're in a working copy. --- RepSys/rpmutil.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index a8d0b4a..37b1178 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -372,6 +372,9 @@ def sync(dryrun=False): topdir = os.pardir else: topdir = "" + # run svn info because svn st does not complain when topdir is not an + # working copy + svn.info(topdir or ".") specsdir = os.path.join(topdir, "SPECS/") sourcesdir = os.path.join(topdir, "SOURCES/") for path in (specsdir, sourcesdir): -- cgit v1.2.1 From d1b0bd707ad3c724f7ff6d3b71e5dfed8522cea8 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 18:48:42 +0000 Subject: Updated CHANGES to v1.6.16 and v1.6.17 --- CHANGES | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGES b/CHANGES index 8fa4e03..7b17ed6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,21 @@ +* 1.6.17 +- brought from mdvsys world the sync command +- ldapusers: the configuration format has changed, now it uses python + template strings +- ldapusers: many fixes: better error messages, ldap-port working, results + contain only the fields needed, unbinding after search, filters are + escaped + +* 1.6.16 +- introduced the plugin ldapusers: repsys user data obtained from LDAP; + this plugin is builtin +- added support to plugins, and the hability to wrap configuration sections +- added workaround in the template to ignore empty releases +- added initial support to mirrors, as requested by mrl; it required the + new subcommand "ci" +- changelogs from misc/ will now should come from HEAD and should be + escaped (%%) + * 1.6.15 - empty changelog entries are now shown, with a EMPTYLOG tag to allow rpmlint warn the developer about it -- cgit v1.2.1 From 10bdc4f6a4d35dd6c9a407e084eceff3b3f4a835 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 4 May 2007 18:49:27 +0000 Subject: Version 1.6.17 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index baf015f..c5f4b09 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.16" +VERSION="1.6.17" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 1e082d77b7d44682d6a41c5cf53cc0b132fb5765 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 8 May 2007 17:57:57 +0000 Subject: Make issue an clearer error when python-cheetah is not installed. Closes #27374. --- RepSys/log.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RepSys/log.py b/RepSys/log.py index f298e6f..785214e 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -3,7 +3,10 @@ from RepSys import Error, config, RepSysTree from RepSys.svn import SVN from RepSys.util import execcmd -from Cheetah.Template import Template +try: + from Cheetah.Template import Template +except ImportError: + raise Error, "repsys requires the package python-cheetah" import sys import os -- cgit v1.2.1 From eecca989feb2fd9ca8edff1a26c2f8ac6e7c54f4 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 8 May 2007 19:00:31 +0000 Subject: Show epoch of the release in changelog, even when it has not been markreleased yet. --- RepSys/log.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 785214e..138918f 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -65,7 +65,7 @@ def getrelease(pkgdirurl, rev=None, macros=[]): if found: specpath = found[0] options = rpm_macros_defs(macros) - command = (("rpm -q --qf '%%{VERSION}-%%{RELEASE}\n' " + command = (("rpm -q --qf '%%{EPOCH}:%%{VERSION}-%%{RELEASE}\n' " "--specfile %s %s 2>/dev/null") % (specpath, options)) status, output = execcmd(command) @@ -73,11 +73,17 @@ def getrelease(pkgdirurl, rev=None, macros=[]): raise Error, "Error in command %s: %s" % (command, output) releases = output.split() try: - version, release = releases[0].split("-", 1) + epoch, vr = releases[0].split(":", 1) + version, release = vr.split("-", 1) except ValueError: raise Error, "Invalid command output: %s: %s" % \ (command, output) - return version, release + #XXX check if this is the right way: + if epoch == "(none)": + ev = version + else: + ev = epoch + ":" + version + return ev, release finally: if os.path.isdir(tmpdir): shutil.rmtree(tmpdir) -- cgit v1.2.1 From 3c5a6e1ad7134dda041bec51a9fb50f3d51976b9 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 9 May 2007 14:16:44 +0000 Subject: Reverted previous change in r219469 (r25). Plugins were not being initialized before command line parsing. --- repsys | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/repsys b/repsys index c5f4b09..8180bfe 100755 --- a/repsys +++ b/repsys @@ -69,10 +69,14 @@ def dispatch_command(command, argv, debug=0): traceback.print_exc() sys.exit(1) raise Error, "invalid command '%s'" % command - plugins.load() command_module.main() if __name__ == "__main__": + try: + plugins.load() + except Error, e: + sys.stderr.write("plugin initialization error: %s\n" % e) + sys.exit(1) do_command(parse_options, dispatch_command) # vim:et:ts=4:sw=4 -- cgit v1.2.1 From 2c8e601129147a04b8f3aee299c0cf4365b258e4 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 9 May 2007 14:17:22 +0000 Subject: Fixed use of __import__ incompatible with python2.4. --- RepSys/plugins/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RepSys/plugins/__init__.py b/RepSys/plugins/__init__.py index 8bf4521..e4f4e08 100644 --- a/RepSys/plugins/__init__.py +++ b/RepSys/plugins/__init__.py @@ -8,13 +8,13 @@ def load(): for entry in os.listdir(pluginsdir): if entry != "__init__.py" and entry.endswith(".py"): name = entry[:-3] - loaded[name] = __import__("RepSys.plugins."+name, - fromlist=[name]) + loaded[name] = __import__("RepSys.plugins."+name, {}, {}, + [name]) elif os.path.isdir(entry): initfile = os.path.join(entry, "__init__.py") if os.path.isfile(initfile): - loaded[entry] = __import__("RepSys.plugins."+entry, - fromlist=[entry]) + loaded[entry] = __import__("RepSys.plugins."+entry, {}, {}, + [entry]) def list(): return loaded.keys() -- cgit v1.2.1 From b1d8c33e2cb5d8c2730a6a1c9837055cad0fb00a Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 9 May 2007 14:22:19 +0000 Subject: Version 1.6.18 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 8180bfe..6c4d4b9 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.17" +VERSION="1.6.18" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From fb3c055e36b9d998e46fcae01d085e35b0cb18b3 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 10 May 2007 22:23:42 +0000 Subject: Added TODO.LDAP --- TODO.LDAP | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 TODO.LDAP diff --git a/TODO.LDAP b/TODO.LDAP new file mode 100644 index 0000000..54d6350 --- /dev/null +++ b/TODO.LDAP @@ -0,0 +1,4 @@ +- we should have a generic fqdn here to use round-robin DNS + enhancement for repsys: support multiple ldap servers here + (from repsys.conf in kenobi) +- support STARTTLS -- cgit v1.2.1 From b8c6fade64a262afd9fcfbad46dec7efcb0df3ed Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Fri, 18 May 2007 21:15:56 +0000 Subject: - use sample [users] entry, drop mandriva ones --- repsys.conf | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/repsys.conf b/repsys.conf index 87013b0..216cec0 100644 --- a/repsys.conf +++ b/repsys.conf @@ -24,14 +24,7 @@ create-srpm = /usr/share/repsys/create-srpm upload-srpm = /usr/local/bin/youri.devel [users] -andreas = Andreas Hasenack -boiko = Gustavo Pichorim Boiko -cavassin = Wanderlei Cavassin -fcrozat = Frederic Crozat -flepied = Frederic Lepied -helio = Helio Chissini de Castro -lmontel = Laurent Montel -oden = Oden Eriksson +# jsmith = John Smith [submit] host = kenobi.mandriva.com -- cgit v1.2.1 From 1360b81f4d00b99c10023831b407c8a4fc64733e Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Fri, 18 May 2007 21:51:26 +0000 Subject: - load plugins in standalone create-srpm script as well --- create-srpm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/create-srpm b/create-srpm index 820c81f..3dab068 100755 --- a/create-srpm +++ b/create-srpm @@ -1,6 +1,6 @@ #!/usr/bin/python -from RepSys import Error, config +from RepSys import Error, config, plugins from RepSys.rpmutil import get_srpm from RepSys.cgiutil import get_targets from RepSys.util import mapurl, execcmd, get_helper @@ -96,6 +96,7 @@ def parse_options(): def main(): + plugins.load() iface = CmdIface() opts, args = parse_options() try: -- cgit v1.2.1 From 25a13bb6dcacfdddd986f875e3a2ae2b8102afdb Mon Sep 17 00:00:00 2001 From: Andreas Hasenack Date: Fri, 18 May 2007 21:52:32 +0000 Subject: - updated CHANGES --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 7b17ed6..ce1fa7e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +* 1.6.18 +- initialize plugins in create-srpm too + * 1.6.17 - brought from mdvsys world the sync command - ldapusers: the configuration format has changed, now it uses python -- cgit v1.2.1 From 5c221808ecb832d3419bb96002ede1a553ed7b73 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 4 Jun 2007 14:35:53 +0000 Subject: FIXME possible bugs in get_srpm related to revision numbers. --- RepSys/rpmutil.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 37b1178..a0eb22e 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -77,8 +77,11 @@ def get_srpm(pkgdirurl, submit = not not revision specfile_svn2rpm(pkgdirurl, spec, revision, submit=submit, template=template, macros=macros) + #FIXME revisioreal not needed if revision is None + #FIXME use geturl instead of pkgdirurl revisionreal = svn.revision(pkgdirurl) for script in scripts: + #FIXME revision can be "None" status, output = execcmd(script, tmpdir, spec, str(revision), noerror=1) if status != 0: @@ -92,6 +95,7 @@ def get_srpm(pkgdirurl, srcrpmdir, patchdir, packager, spec, defs)) if revision and revisionreal: + #FIXME duplicate glob line srpm = glob.glob(os.path.join(srpmsdir, "*.src.rpm"))[0] srpminfo = SRPM(srpm) release = srpminfo.release -- cgit v1.2.1 From 5f1a15b9c7b253c0267d05613683ac1fb5f88e6c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Jun 2007 19:17:27 +0000 Subject: Improved (and fixed) the support to mirrors and "switch" subcommand - added the switch subcommand to quickly switch between the default and the mirrored repositories - fixed bug of generating bogus mirror URLs - make "ci" smarter by only relocation if something has been changed in the working copy and it is not already relocated. --- RepSys/commands/switch.py | 32 ++++++++++++++++++++ RepSys/mirror.py | 76 +++++++++++++++++++++++++++++++++++++++++++---- RepSys/rpmutil.py | 29 +++++++++++++++--- RepSys/svn.py | 2 ++ repsys | 1 + 5 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 RepSys/commands/switch.py diff --git a/RepSys/commands/switch.py b/RepSys/commands/switch.py new file mode 100644 index 0000000..dcbdd17 --- /dev/null +++ b/RepSys/commands/switch.py @@ -0,0 +1,32 @@ +#!/usr/bin/python +from RepSys.command import * +from RepSys.rpmutil import switch + +HELP = """\ +Usage: repsys switch [URL] + +Relocates the working copy to the base location URL. If URL is not +provided, it will use the option default_parent from repsys.conf as +default, or, if the current working copy is already based in +default_parent, it will use the location from the mirror option from +repsys.conf. + +If the current work is based in another URL, it will use default_parent. + +Options: + -h Show this message + +Examples: + repsys switch + repsys switch https://mirrors.localnetwork/svn/packages/cooker +""" + +def parse_options(): + parser = OptionParser(help=HELP) + opts, args = parser.parse_args() + if len(args): + opts.mirrorurl = args[0] + return opts + +def main(): + do_command(parse_options, switch) diff --git a/RepSys/mirror.py b/RepSys/mirror.py index a24f594..6acc839 100644 --- a/RepSys/mirror.py +++ b/RepSys/mirror.py @@ -4,16 +4,46 @@ import urlparse from RepSys import config from RepSys.svn import SVN +def _normdirurl(url): + """normalize url for relocate_path needs""" + parsed = urlparse.urlparse(url) + path = os.path.normpath(parsed.path) + path += "/" # assuming we always deal with directories + newurl = urlparse.urlunparse((parsed.scheme, parsed.netloc, path, + parsed.params, parsed.query, parsed.fragment)) + return newurl + +def _joinurl(url, relpath): + parsed = urlparse.urlparse(url) + newpath = os.path.join(parsed.path, relpath) + newurl = urlparse.urlunparse((parsed.scheme, parsed.netloc, newpath, + parsed.params, parsed.query, parsed.fragment)) + return newurl + +def same_base(parent, url): + """returns true if parent is parent of url""" + parent = _normdirurl(parent) + url = _normdirurl(url) + #FIXME handle paths with/without username/password + return url.startswith(parent) + def relocate_path(oldparent, newparent, url): - subpath = url[len(oldparent)-1:] - newurl = newparent + "/" + subpath # subpath usually gets / at begining + oldparent = _normdirurl(oldparent) + newparent = _normdirurl(newparent) + url = _normdirurl(url) + subpath = url[len(oldparent):] + newurl = _joinurl(newparent, subpath) # subpath usually gets / at begining return newurl -def enabled(): +def enabled(wcurl=None): mirror = config.get("global", "mirror") default_parent = config.get("global", "default_parent") - return (mirror is not None and - default_parent is not None) + enabled = False + if mirror and default_parent: + enabled = True + if wcurl and (not same_base(mirror, wcurl)): + enabled = False + return enabled def mirror_relocate(oldparent, newparent, url, wcpath): svn = SVN(noauth=True) @@ -40,3 +70,39 @@ def checkout_url(url): if mirror is not None and default_parent is not None: return relocate_path(default_parent, mirror, url) return url + +def autoswitch(svn, wcpath, wcurl, newbaseurl=None): + """Switches between mirror, default_parent, or newbaseurl""" + nobase = False + mirror = config.get("global", "mirror") + default_parent = config.get("global", "default_parent") + current = default_parent + if default_parent is None: + raise Error, "the option default_parent from repsys.conf is "\ + "required" + indefault = same_base(default_parent, wcurl) + if not newbaseurl: + if not mirror: + raise Error, "an URL is needed when the option mirror "\ + "from repsys.conf is not set" + if indefault: + chosen = mirror + elif same_base(mirror, wcurl): + current = mirror + chosen = default_parent + else: + nobase = True + else: + if mirror and same_base(mirror, wcurl): + current = mirror + elif indefault: + pass # !!!! + else: + nobase = True + chosen = newbaseurl + if nobase: + raise Error, "the URL of this working copy is not based in "\ + "default_parent nor mirror URLs" + assert current != chosen + newurl = mirror_relocate(current, chosen, wcurl, wcpath) + return newurl diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index a0eb22e..413c152 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -368,14 +368,20 @@ def checkout(pkgdirurl, path=None, revision=None): print "checking out from mirror", current svn.checkout(current, path, rev=revision, show=1) -def sync(dryrun=False): - svn = SVN(noauth=True) +def _getpkgtopdir(basedir=None): + if basedir is None: + basedir = os.getcwd() cwd = os.getcwd() dirname = os.path.basename(cwd) if dirname == "SPECS" or dirname == "SOURCES": topdir = os.pardir else: topdir = "" + return topdir + +def sync(dryrun=False): + svn = SVN(noauth=True) + topdir = _getpkgtopdir() # run svn info because svn st does not complain when topdir is not an # working copy svn.info(topdir or ".") @@ -425,11 +431,16 @@ def sync(dryrun=False): def commit(target=".", message=None): svn = SVN(noauth=True) + status = svn.status(target, quiet=True) + if not status: + print "nothing to commit" + return info = svn.info2(target) url = info.get("URL") if url is None: raise Error, "working copy URL not provided by svn info" - if mirror.enabled(): + mirrored = mirror.enabled(url) + if mirrored: newurl = mirror.switchto_parent(svn, url, target) print "relocated to", newurl try: @@ -439,10 +450,20 @@ def commit(target=".", message=None): mopt = "-m \"%s\"" % message os.system("svn ci %s %s" % (mopt, target)) finally: - if mirror.enabled(): + if mirrored: mirror.switchto_mirror(svn, newurl, target) print "relocated back to", url +def switch(mirrorurl=None): + svn = SVN(noauth=True) + topdir = _getpkgtopdir() + info = svn.info2(topdir) + wcurl = info.get("URL") + if wcurl is None: + raise Error, "working copy URL not provided by svn info" + newurl = mirror.autoswitch(svn, topdir, wcurl, mirrorurl) + print "switched to", newurl + def get_submit_info(path): path = os.path.abspath(path) diff --git a/RepSys/svn.py b/RepSys/svn.py index b4ad4e9..cc3811d 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -189,6 +189,8 @@ class SVN: cmd.append("-v") if kwargs.get("noignore"): cmd.append("--no-ignore") + if kwargs.get("quiet"): + cmd.append("--quiet") status, output = self._execsvn(*cmd, **kwargs) if status == 0: return [x.split() for x in output.splitlines()] diff --git a/repsys b/repsys index 6c4d4b9..10b2b55 100755 --- a/repsys +++ b/repsys @@ -21,6 +21,7 @@ Useful commands: changed authoremail putsrpm + switch Run "repsys COMMAND --help" for more information. -- cgit v1.2.1 From 3694f60d68d2332d07e39cde0cbba06061fddb95 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Jun 2007 19:21:07 +0000 Subject: Updated changes about previous fixes in mirror support --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index ce1fa7e..10b83a6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ * 1.6.18 +- added the subcommand "switch" to help with mirrors support - initialize plugins in create-srpm too +- fixed bug of wrong paths when using mirrors * 1.6.17 - brought from mdvsys world the sync command -- cgit v1.2.1 From a2a73182ccef6b7e986e475d2b2a314061fbbd78 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 6 Jun 2007 06:27:06 +0000 Subject: Import "Error" before use it --- RepSys/mirror.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RepSys/mirror.py b/RepSys/mirror.py index 6acc839..29b8bf5 100644 --- a/RepSys/mirror.py +++ b/RepSys/mirror.py @@ -1,7 +1,7 @@ import os import urlparse -from RepSys import config +from RepSys import Error, config from RepSys.svn import SVN def _normdirurl(url): -- cgit v1.2.1 From 4b66a3a0f18650052127dbc9ba87f53c9ceca2cf Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 7 Jun 2007 12:31:07 +0000 Subject: - use correct revision number for last commit (this commit by Andreas was accidentally reverted during SVN recovery) --- RepSys/svn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RepSys/svn.py b/RepSys/svn.py index cc3811d..b91af0c 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -159,8 +159,8 @@ class SVN: status, output = self._execsvn(local=True, *cmd, **kwargs) if status == 0: for line in output.splitlines(): - if line.startswith("Revision: "): - return int(line.split()[1]) + if line.startswith("Last Changed Rev: "): + return int(line.split()[3]) return None def info(self, path, **kwargs): -- cgit v1.2.1 From 01674a4621a88b56c91ca3ad430a441cf6226c64 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 12 Jun 2007 18:36:37 +0000 Subject: Don't force "/" at the end of URLs --- RepSys/mirror.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RepSys/mirror.py b/RepSys/mirror.py index 29b8bf5..0c45c9e 100644 --- a/RepSys/mirror.py +++ b/RepSys/mirror.py @@ -8,7 +8,6 @@ def _normdirurl(url): """normalize url for relocate_path needs""" parsed = urlparse.urlparse(url) path = os.path.normpath(parsed.path) - path += "/" # assuming we always deal with directories newurl = urlparse.urlunparse((parsed.scheme, parsed.netloc, path, parsed.params, parsed.query, parsed.fragment)) return newurl @@ -31,7 +30,7 @@ def relocate_path(oldparent, newparent, url): oldparent = _normdirurl(oldparent) newparent = _normdirurl(newparent) url = _normdirurl(url) - subpath = url[len(oldparent):] + subpath = url[len(oldparent)+1:] newurl = _joinurl(newparent, subpath) # subpath usually gets / at begining return newurl -- cgit v1.2.1 From 84c619563ec69d7ce91e6eaebc1cfc13c1dcdb02 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 12 Jun 2007 18:37:38 +0000 Subject: updated CHANGES regarding compatibility with cheetah-2 and epoch in changelogs --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 10b83a6..9178963 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ * 1.6.18 - added the subcommand "switch" to help with mirrors support - initialize plugins in create-srpm too +- changelog: show epoch even in the entry not released +- changelog: make default.chlog compatible with cheetah-2 - fixed bug of wrong paths when using mirrors * 1.6.17 -- cgit v1.2.1 From ae42a1c062d852e928e81c81546caa80fcbf3fa2 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 12 Jun 2007 18:58:39 +0000 Subject: Added FIXME to strange putsrpm behavior --- RepSys/rpmutil.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 413c152..671908f 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -150,6 +150,8 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""): version = srpm.version versionurl = "/".join([pkgdirurl, "releases", version]) releaseurl = "/".join([versionurl, srpm.release]) + #FIXME when pre-commit hook fails, there's no clear way to know + # what happened ret = svn.mkdir(pkgdirurl, noerror=1, log="Created package directory") if ret: svn.checkout(pkgdirurl, tmpdir) -- cgit v1.2.1 From f7ab5b0c279fe21bfbb65082a512eccabcad5001 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 12 Jun 2007 18:59:27 +0000 Subject: Don't use mirror in 'co' when the user provides one URL --- RepSys/commands/co.py | 2 +- RepSys/rpmutil.py | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/RepSys/commands/co.py b/RepSys/commands/co.py index f2b4d64..693897a 100644 --- a/RepSys/commands/co.py +++ b/RepSys/commands/co.py @@ -23,7 +23,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) not in (1, 2): raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = args[0] if len(args) == 2: opts.path = args[1] else: diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 671908f..fd06627 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -5,6 +5,7 @@ from RepSys.svn import SVN from RepSys.simplerpm import SRPM from RepSys.log import specfile_svn2rpm from RepSys.util import execcmd +from RepSys.command import default_parent import rpm import tempfile import shutil @@ -361,13 +362,17 @@ def check_changed(pkgdirurl, all=0, show=0, verbose=0): "nopristine": nopristine} def checkout(pkgdirurl, path=None, revision=None): - svn = SVN(baseurl=pkgdirurl) + o_pkgdirurl = pkgdirurl + pkgdirurl = default_parent(o_pkgdirurl) current = os.path.join(pkgdirurl, "current") if path is None: _, path = os.path.split(pkgdirurl) - if mirror.enabled(): + # if default_parent changed the URL, we can use mirrors because the + # user did not provided complete package URL + if (o_pkgdirurl != pkgdirurl) and mirror.enabled(): current = mirror.checkout_url(current) print "checking out from mirror", current + svn = SVN(baseurl=pkgdirurl) svn.checkout(current, path, rev=revision, show=1) def _getpkgtopdir(basedir=None): -- cgit v1.2.1 From 9d2e4a776bb8ac4e2a210d83ae2da61a1065757c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 12 Jun 2007 19:00:03 +0000 Subject: Fixed sync to different behavior of parseSpec in rpm-4.8.8 parseSpec must called with _topdir properly defined to the top directory of the package, as it will check the presence of source files. --- RepSys/rpmutil.py | 1 + 1 file changed, 1 insertion(+) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index fd06627..8cc7034 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -402,6 +402,7 @@ def sync(dryrun=False): raise Error, "no .spec files found in %s" % specsdir specpath = specs[0] # FIXME better way? try: + rpm.addMacro("_topdir", os.path.abspath(topdir)) spec = rpm.TransactionSet().parseSpec(specpath) except rpm.error, e: raise Error, "could not load spec file: %s" % e -- cgit v1.2.1 From 6976ec049c85df55f6d99e3aa4d7520feaf2afdc Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Sat, 16 Jun 2007 15:53:56 +0000 Subject: added missing entries in CHANGES: rpm-4.4.8, "co", and python2.4 fix --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 9178963..f2a14fe 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,9 @@ - initialize plugins in create-srpm too - changelog: show epoch even in the entry not released - changelog: make default.chlog compatible with cheetah-2 +- make "sync" compatible with rpm-4.4.8 behavior +- "co" don't use mirror when URL is provided +- fixed use of __import__, incompatible with python2.4 in plugin support - fixed bug of wrong paths when using mirrors * 1.6.17 -- cgit v1.2.1 From 68c3b372c328fe6b37a9286c724c324bc26e4e7e Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Sat, 16 Jun 2007 16:04:53 +0000 Subject: We don't use repsys.macros anymore --- repsys.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/repsys.conf b/repsys.conf index 216cec0..bbe99af 100644 --- a/repsys.conf +++ b/repsys.conf @@ -13,8 +13,6 @@ oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc revision-offset = 0 # commit lines containing this string won't be shown in the changelog: ignore-string = SILENT -# see repsys.macros: -#macros-file = /etc/repsys.macros [template] path = /usr/share/repsys/default.chlog -- cgit v1.2.1 From cb1f86f2e30b8d7311c8ed75e7d4014827cced38 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Sat, 16 Jun 2007 16:05:44 +0000 Subject: prepare for cheetah-2 --- RepSys/log.py | 2 +- default.chlog | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 138918f..7263be3 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -298,7 +298,7 @@ def dump_file(releases, currentlog=None, template=None): "releases" : releases, "revisions_by_author": revisions_author}] t = Template(**params) - return repr(t) + return t.respond() class InvalidEntryError(Exception): diff --git a/default.chlog b/default.chlog index f8f1ec5..aff3958 100644 --- a/default.chlog +++ b/default.chlog @@ -3,9 +3,9 @@ #for $rel in $releases_by_author * $rel.date $rel.author_name <$rel.author_email> $rel.version-$rel.release + Revision: $rel.revision - #if not $rel.released +## #if not $rel.released ##+ Status: not released - #end if +## #end if #if not $rel.visible + rebuild (emptylog) #end if -- cgit v1.2.1 From 1764e182d9cf9937ad78a1452fe48c167372fc1a Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Sat, 16 Jun 2007 16:29:08 +0000 Subject: As requested by mrl, don't relocate back to mirror after commit --- CHANGES | 1 + RepSys/rpmutil.py | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index f2a14fe..fa45585 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ - changelog: make default.chlog compatible with cheetah-2 - make "sync" compatible with rpm-4.4.8 behavior - "co" don't use mirror when URL is provided +- "ci" don't relocate back to mirrors after commit (should use switch) - fixed use of __import__, incompatible with python2.4 in plugin support - fixed bug of wrong paths when using mirrors diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 8cc7034..bd75254 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -451,16 +451,14 @@ def commit(target=".", message=None): if mirrored: newurl = mirror.switchto_parent(svn, url, target) print "relocated to", newurl - try: - # we can't use the svn object here because pexpect hides VISUAL - mopt = "" - if message is not None: - mopt = "-m \"%s\"" % message - os.system("svn ci %s %s" % (mopt, target)) - finally: - if mirrored: - mirror.switchto_mirror(svn, newurl, target) - print "relocated back to", url + # we can't use the svn object here because pexpect hides VISUAL + mopt = "" + if message is not None: + mopt = "-m \"%s\"" % message + os.system("svn ci %s %s" % (mopt, target)) + if mirrored: + print "use \"repsys switch\" in order to switch back to mirror "\ + "later" def switch(mirrorurl=None): svn = SVN(noauth=True) -- cgit v1.2.1 From b1d0787e062a976b33113f08e12c6d9193dbd2e7 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Sun, 17 Jun 2007 15:07:25 +0000 Subject: Perform less svn operations in getsrpm and rpmlog - don't export SPECS/ when current/ is already exported - don't check for the presence of a path that will be exported in the same code, let it raise one exception - complain when no changelogs are found inside SPECS/ --- CHANGES | 1 + RepSys/log.py | 78 ++++++++++++++++++++++++++++++------------------------- RepSys/rpmutil.py | 2 +- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index fa45585..eee610a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ * 1.6.18 - added the subcommand "switch" to help with mirrors support - initialize plugins in create-srpm too +- changelog: perform less svn calls to obtain release number and oldlog - changelog: show epoch even in the entry not released - changelog: make default.chlog compatible with cheetah-2 - make "sync" compatible with rpm-4.4.8 behavior diff --git a/RepSys/log.py b/RepSys/log.py index 7263be3..b5bf212 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -45,7 +45,7 @@ default_template = """ #end for """ -def getrelease(pkgdirurl, rev=None, macros=[]): +def getrelease(pkgdirurl, rev=None, macros=[], exported=None): """Tries to obtain the version-release of the package for a yet-not-markrelease revision of the package. @@ -54,38 +54,40 @@ def getrelease(pkgdirurl, rev=None, macros=[]): """ from RepSys.rpmutil import rpm_macros_defs svn = SVN(baseurl=pkgdirurl) - tmpdir = tempfile.mktemp() + pkgcurrenturl = os.path.join(pkgdirurl, "current") + specurl = os.path.join(pkgcurrenturl, "SPECS") + if exported is None: + tmpdir = tempfile.mktemp() + svn.export(specurl, tmpdir, rev=rev) + else: + tmpdir = os.path.join(exported, "SPECS") try: - pkgname = RepSysTree.pkgname(pkgdirurl) - pkgcurrenturl = os.path.join(pkgdirurl, "current") - specurl = os.path.join(pkgcurrenturl, "SPECS") - if svn.ls(specurl, noerror=1): - svn.export(specurl, tmpdir, rev=rev) - found = glob.glob(os.path.join(tmpdir, "*.spec")) - if found: - specpath = found[0] - options = rpm_macros_defs(macros) - command = (("rpm -q --qf '%%{EPOCH}:%%{VERSION}-%%{RELEASE}\n' " - "--specfile %s %s 2>/dev/null") % - (specpath, options)) - status, output = execcmd(command) - if status != 0: - raise Error, "Error in command %s: %s" % (command, output) - releases = output.split() - try: - epoch, vr = releases[0].split(":", 1) - version, release = vr.split("-", 1) - except ValueError: - raise Error, "Invalid command output: %s: %s" % \ - (command, output) - #XXX check if this is the right way: - if epoch == "(none)": - ev = version - else: - ev = epoch + ":" + version - return ev, release + found = glob.glob(os.path.join(tmpdir, "*.spec")) + if not found: + raise Error, "no .spec file found inside %s" % specurl + specpath = found[0] + options = rpm_macros_defs(macros) + command = (("rpm -q --qf '%%{EPOCH}:%%{VERSION}-%%{RELEASE}\n' " + "--specfile %s %s 2>/dev/null") % + (specpath, options)) + status, output = execcmd(command) + if status != 0: + raise Error, "Error in command %s: %s" % (command, output) + releases = output.split() + try: + epoch, vr = releases[0].split(":", 1) + version, release = vr.split("-", 1) + except ValueError: + raise Error, "Invalid command output: %s: %s" % \ + (command, output) + #XXX check if this is the right way: + if epoch == "(none)": + ev = version + else: + ev = epoch + ":" + version + return ev, release finally: - if os.path.isdir(tmpdir): + if exported is None and os.path.isdir(tmpdir): shutil.rmtree(tmpdir) class _Revision: @@ -360,7 +362,7 @@ def parse_markrelease_log(relentry): def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, - template=None, macros=[]): + template=None, macros=[], exported=None): concat = config.get("log", "concat", "").split() revoffset = get_revision_offset() svn = SVN(baseurl=pkgdirurl) @@ -423,7 +425,8 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, 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) + version, release = getrelease(pkgdirurl, macros=macros, + exported=exported) toprelease = make_release(entries=notsubmitted, released=False, version=version, release=release) releases.append(toprelease) @@ -434,7 +437,7 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, - submit=False, template=None, macros=[]): + submit=False, template=None, macros=[], exported=None): newlines = [] found = 0 @@ -451,7 +454,7 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, # Create new changelog newlines.append("\n\n%changelog\n") newlines.append(svn2rpm(pkgdirurl, rev=rev, size=size, submit=submit, - template=template, macros=macros)) + template=template, macros=macros, exported=exported)) # Merge old changelog, if available oldurl = config.get("log", "oldurl") @@ -461,10 +464,13 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, try: pkgname = RepSysTree.pkgname(pkgdirurl) pkgoldurl = os.path.join(oldurl, pkgname) - if svn.ls(pkgoldurl, noerror=1): + try: # we're using HEAD here because fixes in misc/ (oldurl) may # be newer than packages' last changed revision. svn.export(pkgoldurl, tmpdir) + except Error: + pass + else: logfile = os.path.join(tmpdir, "log") if os.path.isfile(logfile): file = open(logfile) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index bd75254..559b64c 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -77,7 +77,7 @@ def get_srpm(pkgdirurl, if svnlog: submit = not not revision specfile_svn2rpm(pkgdirurl, spec, revision, submit=submit, - template=template, macros=macros) + template=template, macros=macros, exported=tmpdir) #FIXME revisioreal not needed if revision is None #FIXME use geturl instead of pkgdirurl revisionreal = svn.revision(pkgdirurl) -- cgit v1.2.1 From 73133d33137c6c6d70ceca7600f70a39e2a708ba Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 18 Jun 2007 17:31:12 +0000 Subject: ldapusers plugin: ldap-starttls + ldap-uri configuration options (nice commit separation) --- README.LDAP | 11 +++++++++- RepSys/plugins/ldapusers.py | 49 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/README.LDAP b/README.LDAP index 863be6d..c22a7fa 100644 --- a/README.LDAP +++ b/README.LDAP @@ -3,7 +3,13 @@ A Repsys plugin for obtaining users from a LDAP server. In order to enable the plugin, the user must define the following options in the [global] section of repsys.conf: - ldap-server [required] + ldap-uri [required if ldap-server is unset] + the URI of the server, you can refer to more than one server by + adding more URIs separated by spaces:: + + ldap-uri = ldap://ldap.network/ ldaps://backup.network:22389/ + + ldap-server [required if ldap-uri is unset] the host name of the LDAP server ldap-port [optional] [default: 389] the port of the LDAP server @@ -13,6 +19,9 @@ options in the [global] section of repsys.conf: the DN used to bind ldap-bindpw [optional] [default: empty] the password used to bind + ldap-starttls [optional] [default: no] + use "yes" or "no" to enable or disable the use of the STARTTLS + LDAP extension ldap-filterformat [optional] [default: (&(objectClass=inetOrgPerson)(uid=$username))] RFC-2254 filter string used in the search of the user entry. diff --git a/RepSys/plugins/ldapusers.py b/RepSys/plugins/ldapusers.py index 75d362c..e56371d 100644 --- a/RepSys/plugins/ldapusers.py +++ b/RepSys/plugins/ldapusers.py @@ -4,7 +4,13 @@ A Repsys plugin for obtaining users from a LDAP server. In order to enable the plugin, the user must define the following options in the [global] section of repsys.conf: - ldap-server [required] + ldap-uri [required if ldap-server is unset] + the URI of the server, you can refer to more than one server by + adding more URIs separated by spaces:: + + ldap-uri = ldap://ldap.network/ ldaps://backup.network:22389/ + + ldap-server [required if ldap-uri is unset] the host name of the LDAP server ldap-port [optional] [default: 389] the port of the LDAP server @@ -14,6 +20,9 @@ options in the [global] section of repsys.conf: the DN used to bind ldap-bindpw [optional] [default: empty] the password used to bind + ldap-starttls [optional] [default: no] + use "yes" or "no" to enable or disable the use of the STARTTLS + LDAP extension ldap-filterformat [optional] [default: (&(objectClass=inetOrgPerson)(uid=$username))] RFC-2254 filter string used in the search of the user entry. @@ -95,12 +104,23 @@ def used_attributes(format): return dd.found def make_handler(): - server = config.get("global", "ldap-server") - try: - port = int(config.get("global", "ldap-port", 389)) - except ValueError: - raise Error, "the option ldap-port requires an integer, please "\ - "check your configuration files" + uri = config.get("global", "ldap-uri") + if not uri: + server = config.get("global", "ldap-server") + if not server: + # ldap support is not enabled if ldap-uri nor ldap-server are + # defined + def dummy_wrapper(section, option=None, default=None, walk=False): + return config.get(section, option, default, wrap=False) + return dummy_wrapper + + try: + port = int(config.get("global", "ldap-port", 389)) + except ValueError: + raise Error, "the option ldap-port requires an integer, please "\ + "check your configuration files" + uri = "ldap://%s:%d" % (server, port) + basedn = config.get("global", "ldap-base") binddn = config.get("global", "ldap-binddn") bindpw = config.get("global", "ldap-bindpw", "") @@ -108,10 +128,13 @@ def make_handler(): "(&(objectClass=inetOrgPerson)(uid=$username))", raw=1) format = config.get("global", "ldap-resultformat", "$cn <$mail>", raw=1) - if server is None: - def dummy_wrapper(section, option=None, default=None, walk=False): - return config.get(section, option, default, wrap=False) - return dummy_wrapper + valid = {"yes": True, "no": False} + raw = config.get("global", "ldap-starttls", "no") + try: + starttls = valid[raw] + except KeyError: + raise Error, "invalid value %r for ldap-starttls, use "\ + "'yes' or 'no'" % raw try: import ldap @@ -133,7 +156,9 @@ def make_handler(): return value try: - l = ldap.open(server, port) + l = ldap.initialize(uri) + if starttls: + l.start_tls_s() if binddn: l.bind(binddn, bindpw) except ldap.LDAPError, e: -- cgit v1.2.1 From b45a34ad8047b19360bc3f19a8bdb06955ce018a Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 18 Jun 2007 17:32:14 +0000 Subject: updated CHANGES regarding ldapusers changes --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index eee610a..f0a6bdf 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ - make "sync" compatible with rpm-4.4.8 behavior - "co" don't use mirror when URL is provided - "ci" don't relocate back to mirrors after commit (should use switch) +- ldapusers: added options ldap-uri and ldap-starttls - fixed use of __import__, incompatible with python2.4 in plugin support - fixed bug of wrong paths when using mirrors -- cgit v1.2.1 From 128df479745085bc1fbb2d0d8842d2e632c55bb1 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 18 Jun 2007 18:10:37 +0000 Subject: added CHANGES to MANIFEST.in --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 1264d01..c8b18b2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ recursive-include RepSys *.py include RepSys/plugins/*.txt include repsys repsys.conf MANIFEST.in +include CHANGES include README.LDAP include *.chlog include rebrand-mdk create-srpm getsrpm-mdk -- cgit v1.2.1 From e5ac8131f63ee32d79c2d4e8232cd8d047add24c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 21 Sep 2007 15:50:43 +0000 Subject: Fix: unreleased commits are not those newer than the last markrelease Entries considered unreleased must be those newer than the latest released revision in current/. Problem pointed out by mrl. --- RepSys/log.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index b5bf212..009e4e0 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -413,11 +413,11 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, releases.append(release) prevrevision = relrevision - # look for commits that have been not submited (released) yet - # this is done by getting all log entries newer (revision larger) - # than releaseslog[0] (in the case it exists) - if releaseslog: - latest_revision = releaseslog[0].revision + # look for commits that have been not submitted (released) yet + # this is done by getting all log entries newer (greater revision no.) + # than releasesdata[0] (in the case it exists) + if releasesdata: + latest_revision = releasesdata[0][0] # "relrevision" else: latest_revision = 0 notsubmitted = [entry for entry in currentlog -- cgit v1.2.1 From 0b923f7cebcdb0f9435c0961a08c537fad7608e0 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 8 Nov 2007 16:30:08 +0000 Subject: Added the complement to SILENT: CLOG When using CLOG, only those lines beginning with this token will be shown. It only works when enabled in repsys.conf. --- CHANGES | 4 ++++ RepSys/log.py | 26 +++++++++++++++++++------- repsys.conf | 4 ++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index f0a6bdf..b9871b9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +* 1.6.19 +- added complement for SILENT: CLOG, which hides everything that does not + start with this token + * 1.6.18 - added the subcommand "switch" to help with mirrors support - initialize plugins in create-srpm too diff --git a/RepSys/log.py b/RepSys/log.py index 009e4e0..10026c3 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -246,13 +246,25 @@ def parse_raw_date(rawdate): return time.strftime("%a %b %d %Y", rawdate) def filter_log_lines(lines): - # lines in commit messages containing SILENT at any position will be - # skipped; commits with their log messages beggining with SILENT in the - # first positionj of the first line will have all lines ignored. - ignstr = config.get("log", "ignore-string", "SILENT") - if len(lines) and lines[0].startswith(ignstr): - return [] - filtered = [line for line in lines if ignstr not in line] + # Lines in commit messages beginning with CLOG will be the only shown + # in the changelog. These lines will have the CLOG token and blanks + # stripped from the beginning. + onlylines = None + clogstr = config.get("log", "unignore-string") + if clogstr: + clogre = re.compile(r"(^%s[^ \t]?[ \t])" % clogstr) + onlylines = [clogre.sub("", line) + for line in lines if line.startswith(clogstr)] + if onlylines: + filtered = onlylines + else: + # Lines in commit messages containing SILENT at any position will be + # skipped; commits with their log messages beggining with SILENT in the + # first positionj of the first line will have all lines ignored. + ignstr = config.get("log", "ignore-string", "SILENT") + if len(lines) and lines[0].startswith(ignstr): + return [] + filtered = [line for line in lines if ignstr not in line] return filtered diff --git a/repsys.conf b/repsys.conf index bbe99af..2201ac1 100644 --- a/repsys.conf +++ b/repsys.conf @@ -13,6 +13,10 @@ oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc revision-offset = 0 # commit lines containing this string won't be shown in the changelog: ignore-string = SILENT +# and in case of only allowing a few lines to be visible, use this: +#unignore-string = CLOG +# see repsys.macros: +#macros-file = /etc/repsys.macros [template] path = /usr/share/repsys/default.chlog -- cgit v1.2.1 From 5e8e1ed3d41ede6d744fda09b32cffc8de009afc Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 8 Nov 2007 16:32:10 +0000 Subject: Updated CHANGES --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index b9871b9..e39f3a0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ * 1.6.19 - added complement for SILENT: CLOG, which hides everything that does not start with this token +- fixed generation of unreleased commits, it was using the previous + markrelease revision as reference * 1.6.18 - added the subcommand "switch" to help with mirrors support -- cgit v1.2.1 From 5fde037cacbb4a6608c6edd58a1d331452d56f0c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 8 Nov 2007 16:32:54 +0000 Subject: Removed unused configuration option. --- repsys.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/repsys.conf b/repsys.conf index 2201ac1..43dd99b 100644 --- a/repsys.conf +++ b/repsys.conf @@ -15,8 +15,6 @@ revision-offset = 0 ignore-string = SILENT # and in case of only allowing a few lines to be visible, use this: #unignore-string = CLOG -# see repsys.macros: -#macros-file = /etc/repsys.macros [template] path = /usr/share/repsys/default.chlog -- cgit v1.2.1 From c8428377393fab3b0549229cdcc349f34500bc15 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 8 Nov 2007 17:21:09 +0000 Subject: Added option -o to 'co' to disable the use of mirror when checking out --- CHANGES | 1 + RepSys/commands/co.py | 3 +++ RepSys/rpmutil.py | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index e39f3a0..cb649df 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ start with this token - fixed generation of unreleased commits, it was using the previous markrelease revision as reference +- added option -o to 'co' to disable the use of mirror when checking out * 1.6.18 - added the subcommand "switch" to help with mirrors support diff --git a/RepSys/commands/co.py b/RepSys/commands/co.py index 693897a..cadcf56 100644 --- a/RepSys/commands/co.py +++ b/RepSys/commands/co.py @@ -10,6 +10,7 @@ Usage: repsys co [OPTIONS] URL [LOCALPATH] Options: -r REV Revision to checkout + -o Do not use the mirror (use official server) -h Show this message Examples: @@ -20,6 +21,8 @@ Examples: def parse_options(): parser = OptionParser(help=HELP) parser.add_option("-r", dest="revision") + parser.add_option("-o", dest="use_mirror", default=True, + action="store_false") opts, args = parser.parse_args() if len(args) not in (1, 2): raise Error, "invalid arguments" diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 559b64c..865e2dd 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -361,7 +361,7 @@ def check_changed(pkgdirurl, all=0, show=0, verbose=0): "nocurrent": nocurrent, "nopristine": nopristine} -def checkout(pkgdirurl, path=None, revision=None): +def checkout(pkgdirurl, path=None, revision=None, use_mirror=True): o_pkgdirurl = pkgdirurl pkgdirurl = default_parent(o_pkgdirurl) current = os.path.join(pkgdirurl, "current") @@ -369,7 +369,7 @@ def checkout(pkgdirurl, path=None, revision=None): _, path = os.path.split(pkgdirurl) # if default_parent changed the URL, we can use mirrors because the # user did not provided complete package URL - if (o_pkgdirurl != pkgdirurl) and mirror.enabled(): + if (o_pkgdirurl != pkgdirurl) and use_mirror and mirror.enabled(): current = mirror.checkout_url(current) print "checking out from mirror", current svn = SVN(baseurl=pkgdirurl) -- cgit v1.2.1 From 7962bd00f97b35136897039bba9e7eb629d1e4b8 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 8 Nov 2007 19:45:42 +0000 Subject: New version 1.6.19 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 10b2b55..7c9db57 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.18" +VERSION="1.6.19" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 7e0e0014427a3609d3102e47446cfad7d3c52624 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Mon, 12 Nov 2007 20:37:38 +0000 Subject: Fix: don't use versions/ when using -v option of getsrpm --- CHANGES | 3 +++ RepSys/rpmutil.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index cb649df..fb28031 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +* 1.6.20 +- fixed bad url used when using -v in getsrpm + * 1.6.19 - added complement for SILENT: CLOG, which hides everything that does not start with this token diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 865e2dd..69692f1 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -58,7 +58,7 @@ def get_srpm(pkgdirurl, patchdir = "--define '_patchdir %s/%s'" % (tmpdir, "SOURCES") try: if mode == "version": - geturl = os.path.join(pkgdirurl, "versions", + geturl = os.path.join(pkgdirurl, "releases", version, release) elif mode == "pristine": geturl = os.path.join(pkgdirurl, "pristine") -- cgit v1.2.1 From 0fe6300c34bb791ccfb1050b04fbb9afd162b322 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 13 Nov 2007 05:11:28 +0000 Subject: Make package and revision optional options for submit, again This mode has been broken for a long time due to a change in subversion output. The confirmation of the revision being used was removed, as already used by mdvsys. Instead, notify the user and allow him to interrupt the process. --- CHANGES | 1 + RepSys/commands/submit.py | 14 +++++--------- RepSys/rpmutil.py | 25 +++++++++++-------------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index fb28031..e1a5e8b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ * 1.6.20 - fixed bad url used when using -v in getsrpm +- make 'repsys submit' without package name or revision number work again * 1.6.19 - added complement for SILENT: CLOG, which hides everything that does not diff --git a/RepSys/commands/submit.py b/RepSys/commands/submit.py index 5c95526..25d5831 100644 --- a/RepSys/commands/submit.py +++ b/RepSys/commands/submit.py @@ -20,6 +20,9 @@ Usage: repsys submit [OPTIONS] [URL [REVISION]] Submits the package from URL to the submit host. +If no URL and revision are specified, the latest changed revision in +the package working copy of the current directory will be used. + Options: -t TARGET Submit given package URL to given target -l Just list available targets @@ -51,15 +54,8 @@ def parse_options(): opts, args = parser.parse_args() if not args: name, rev = get_submit_info(".") - try: - yn = raw_input("Submit '%s', revision %d (y/N)? " % (name, rev)) - except KeyboardInterrupt: - yn = "n" - if yn.lower() in ("y", "yes"): - args = name, str(rev) - else: - print "Cancelled." - sys.exit(1) + args = name, str(rev) + print "submitting %s at revision %s..." % args elif len(args) > 2: raise Error, "invalid arguments" opts.pkgdirurl = default_parent(args[0]) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 69692f1..774f64f 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -490,20 +490,17 @@ def get_submit_info(path): if not os.path.isdir(os.path.join(path, ".svn")): raise Error, "subversion directory not found" - svn = SVN(baseurl=pkgdirurl) - + svn = SVN(noauth=True) # 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" + info = svn.info2(path) + url = info.get("URL") + if url is None: + raise Error, "missing URL from svn info %s" % path + toks = url.split("/") + if len(toks) < 2 or toks[-1] != "current": + raise Error, "unexpected URL received from 'svn info'" + name = toks[-2] # Finally, guess revision. max = -1 @@ -511,8 +508,8 @@ def get_submit_info(path): 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 line.startswith("Last Changed Rev: "): + rev = int(line.split(":")[1]) if rev > max: max = rev if max == -1: -- cgit v1.2.1 From bbcb7441232303601ccce9a413e104c450477bef Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 13 Nov 2007 17:14:47 +0000 Subject: Reverted "Fix: unreleased commits are not those newer than the last markrelease" It was r228878. Some changelogs are broken. Revert it while a better fix is investigated. --- RepSys/log.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RepSys/log.py b/RepSys/log.py index 10026c3..b476618 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -425,11 +425,11 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, 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[0] (in the case it exists) - if releasesdata: - latest_revision = releasesdata[0][0] # "relrevision" + # look for commits that have been not submited (released) yet + # this is done by getting all log entries newer (revision larger) + # than releaseslog[0] (in the case it exists) + if releaseslog: + latest_revision = releaseslog[0].revision else: latest_revision = 0 notsubmitted = [entry for entry in currentlog -- cgit v1.2.1 From a927524c43d391579a17b3630606f350f44acf3c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 14 Nov 2007 20:29:55 +0000 Subject: Really fixed generation of unreleased commits It was using the previous markrelease revision as reference. The recent broken fix was using "releasesdata[0]" instead of "releasesdata[-1]" which is the newest release revision. --- CHANGES | 2 ++ RepSys/log.py | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index e1a5e8b..7eb334b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ * 1.6.20 - fixed bad url used when using -v in getsrpm - make 'repsys submit' without package name or revision number work again +- the fix for the unreleased commits problem in the previous release was + wrong, really fixed it * 1.6.19 - added complement for SILENT: CLOG, which hides everything that does not diff --git a/RepSys/log.py b/RepSys/log.py index b476618..730c674 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -425,11 +425,11 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, releases.append(release) prevrevision = relrevision - # look for commits that have been not submited (released) yet - # this is done by getting all log entries newer (revision larger) - # than releaseslog[0] (in the case it exists) - if releaseslog: - latest_revision = releaseslog[0].revision + # 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 -- cgit v1.2.1 From fa6fb5c9da640532db63db2aa9111c523cb35fe4 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 14 Nov 2007 22:27:18 +0000 Subject: Don't say "invalid command CMD" when this is not the real error Sometimes when a module used by repsys is missing, the given error message is "invalid command CMD", instead of a exception trace showing that there's something wrong with with the repsys setup. This change fixes this issue by counting the number of frames in the exception trace. When the command module is not available there will be only one frame (being the function that is trying to import the command's module), otherwise there will be more frames (because the found module will already be present in the trace). This fix is probably valid for smart too. --- CHANGES | 2 ++ repsys | 9 ++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 7eb334b..03e363c 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ - make 'repsys submit' without package name or revision number work again - the fix for the unreleased commits problem in the previous release was wrong, really fixed it +- don't give the wrong message "invalid command 'CMD'" when this is not + the case * 1.6.19 - added complement for SILENT: CLOG, which hides everything that does not diff --git a/repsys b/repsys index 7c9db57..a243493 100755 --- a/repsys +++ b/repsys @@ -65,11 +65,10 @@ def dispatch_command(command, argv, debug=0): commands_module = getattr(repsys_module, "commands") command_module = getattr(commands_module, command) except (ImportError, AttributeError): - if debug: - import traceback - traceback.print_exc() - sys.exit(1) - raise Error, "invalid command '%s'" % command + etype, exc, tb = sys.exc_info() + if tb.tb_next is None and not debug: + raise Error, "invalid command '%s'" % command + raise command_module.main() if __name__ == "__main__": -- cgit v1.2.1 From e196e676aa302cd3a1f7b37f259491a8b03cc483 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 15 Nov 2007 05:30:56 +0000 Subject: Dropped all authenticated access support Subversion authentication has been broken for a long time and the workarounds weren't decent. It will be back in 1.7.x. Also added configuration option svn-command in the global section, allowing to replace the default svn command. And use svn+ssh:// URLs to be in BatchMode, in order to not have any interactivity at all with ssh --- CHANGES | 7 + RepSys/log.py | 6 +- RepSys/mirror.py | 2 +- RepSys/pexpect.py | 1052 ----------------------------------------------------- RepSys/rpmutil.py | 27 +- RepSys/svn.py | 79 +--- 6 files changed, 44 insertions(+), 1129 deletions(-) delete mode 100644 RepSys/pexpect.py diff --git a/CHANGES b/CHANGES index 03e363c..27c0899 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,11 @@ * 1.6.20 +- dropped all authenticated access support: subversion authentication has + been broken for a long time and the workarounds weren't decent. It will + be back in 1.7.x. +- added configuration option svn-command in the global section, allowing + to replace the default svn command +- force svn+ssh:// URLs to be in BatchMode, in order to not have any + interactivity at all with ssh - fixed bad url used when using -v in getsrpm - make 'repsys submit' without package name or revision number work again - the fix for the unreleased commits problem in the previous release was diff --git a/RepSys/log.py b/RepSys/log.py index 730c674..df7bc9f 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -53,7 +53,7 @@ def getrelease(pkgdirurl, rev=None, macros=[], exported=None): will be used. """ from RepSys.rpmutil import rpm_macros_defs - svn = SVN(baseurl=pkgdirurl) + svn = SVN() pkgcurrenturl = os.path.join(pkgdirurl, "current") specurl = os.path.join(pkgcurrenturl, "SPECS") if exported is None: @@ -377,7 +377,7 @@ 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(baseurl=pkgdirurl) + svn = SVN() pkgreleasesurl = os.path.join(pkgdirurl, "releases") pkgcurrenturl = os.path.join(pkgdirurl, "current") releaseslog = svn.log(pkgreleasesurl, noerror=1) @@ -471,7 +471,7 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None, # Merge old changelog, if available oldurl = config.get("log", "oldurl") if oldurl: - svn = SVN(baseurl=pkgdirurl) + svn = SVN() tmpdir = tempfile.mktemp() try: pkgname = RepSysTree.pkgname(pkgdirurl) diff --git a/RepSys/mirror.py b/RepSys/mirror.py index 0c45c9e..4fb40ce 100644 --- a/RepSys/mirror.py +++ b/RepSys/mirror.py @@ -45,7 +45,7 @@ def enabled(wcurl=None): return enabled def mirror_relocate(oldparent, newparent, url, wcpath): - svn = SVN(noauth=True) + svn = SVN() newurl = relocate_path(oldparent, newparent, url) svn.switch(newurl, url, path=wcpath, relocate="True") return newurl diff --git a/RepSys/pexpect.py b/RepSys/pexpect.py deleted file mode 100644 index 02a14f5..0000000 --- a/RepSys/pexpect.py +++ /dev/null @@ -1,1052 +0,0 @@ -""" -Pexpect is a Python module for spawning child applications; -controlling them; and responding to expected patterns in their output. -Pexpect can be used for automating interactive applications such as -ssh, ftp, passwd, telnet, etc. It can be used to a automate setup scripts -for duplicating software package installations on different servers. -It can be used for automated software testing. Pexpect is in the spirit of -Don Libes' Expect, but Pexpect is pure Python. Other Expect-like -modules for Python require TCL and Expect or require C extensions to -be compiled. Pexpect does not use C, Expect, or TCL extensions. It -should work on any platform that supports the standard Python pty -module. The Pexpect interface focuses on ease of use so that simple -tasks are easy. - -Pexpect is Open Source, Free, and all Good that stuff. -License: Python Software Foundation License - http://www.opensource.org/licenses/PythonSoftFoundation.html - -Noah Spurrier - -$Revision$ -$Date$ -""" - - -try: - import os, sys - import select - import string - import re - import struct - import resource - from types import * - import pty - import tty - import termios - import fcntl -except ImportError, e: - raise ImportError, str(e) + """ -A critical module was not found. Probably this OS does not support it. -Currently pexpect is intended for UNIX operating systems.""" - - - -__version__ = '0.99' -__revision__ = '$Revision$' -__all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'run', - '__version__', '__revision__'] - - - -# Exception classes used by this module. -class ExceptionPexpect(Exception): - """Base class for all exceptions raised by this module.""" - def __init__(self, value): - self.value = value - def __str__(self): - return `self.value` -class EOF(ExceptionPexpect): - """Raised when EOF is read from a child.""" -class TIMEOUT(ExceptionPexpect): - """Raised when a read time exceeds the timeout.""" -##class MAXBUFFER(ExceptionPexpect): -## """Raised when a scan buffer fills before matching an expected pattern.""" - - - -def run (command, args=[], timeout=30): - """This runs a command; waits for it to finish; then returns - all output as a string. This is a utility interface around - the spawn class. - """ - child = spawn(command, args, timeout) - child.expect (EOF) - return child.before - -class spawn: - """This is the main class interface for Pexpect. Use this class to - start and control child applications. - """ - - def __init__(self, command, args=[], timeout=30): - """This is the constructor. The command parameter may be a string - that includes a command and any arguments to the command. For example: - p = pexpect.spawn ('/usr/bin/ftp') - p = pexpect.spawn ('/usr/bin/ssh user@example.com') - p = pexpect.spawn ('ls -latr /tmp') - You may also construct it with a list of arguments like so: - p = pexpect.spawn ('/usr/bin/ftp', []) - p = pexpect.spawn ('/usr/bin/ssh', ['user@example.com']) - p = pexpect.spawn ('ls', ['-latr', '/tmp']) - After this the child application will be created and - will be ready to talk to. For normal use, see expect() and - send() and sendline(). - - If the command parameter is an integer AND a valid file descriptor - then spawn will talk to the file descriptor instead. This can be - used to act expect features to any file descriptor. For example: - fd = os.open ('somefile.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - The original creator of the file descriptor is responsible - for closing it. Spawn will not try to close it and spawn will - raise an exception if you try to call spawn.close(). - """ - - self.STDIN_FILENO = sys.stdin.fileno() - self.STDOUT_FILENO = sys.stdout.fileno() - self.STDERR_FILENO = sys.stderr.fileno() - - self.stdin = sys.stdin - self.stdout = sys.stdout - self.stderr = sys.stderr - - self.timeout = timeout - self.child_fd = -1 # initially closed - self.__child_fd_owner = None - self.exitstatus = None - self.pid = None - self.log_file = None - self.before = None - self.after = None - self.match = None - self.softspace = 0 # File-like object. - self.name = '' # File-like object. - self.flag_eof = 0 - - # NEW -- to support buffering -- the ability to read more than one - # byte from a TTY at a time. See setmaxread() method. - self.buffer = '' - self.maxread = 1 # Maximum to read at a time - ### IMPLEMENT THIS FEATURE!!! - # anything before maxsearchsize point is preserved, but not searched. - #self.maxsearchsize = 1000 - - # If command is an int type then it must represent an open file descriptor. - if type (command) == type(0): - try: # Command is an int, so now check if it is a file descriptor. - os.fstat(command) - except OSError: - raise ExceptionPexpect, 'Command is an int type, yet is not a valid file descriptor.' - self.pid = -1 - self.child_fd = command - self.__child_fd_owner = 0 # Sets who is reponsible for the child_fd - self.args = None - self.command = None - self.name = '' - return - - if type (args) != type([]): - raise TypeError, 'The second argument, args, must be a list.' - - if args == []: - self.args = _split_command_line(command) - self.command = self.args[0] - else: - self.args = args - self.args.insert (0, command) - self.command = command - self.name = '<' + reduce(lambda x, y: x+' '+y, self.args) + '>' - - self.__spawn() - - def __del__(self): - """This makes sure that no system resources are left open. - Python only garbage collects Python objects. OS file descriptors - are not Python objects, so they must be handled explicitly. - If the child file descriptor was opened outside of this class - (passed to the constructor) then this does not close it. - """ - try: # CNC:2003-09-23 - if self.__child_fd_owner: - self.close() - except OSError: - pass - - def __spawn(self): - """This starts the given command in a child process. This does - all the fork/exec type of stuff for a pty. This is called by - __init__. The args parameter is a list, command is a string. - """ - # The pid and child_fd of this object get set by this method. - # Note that it is difficult for this method to fail. - # You cannot detect if the child process cannot start. - # So the only way you can tell if the child process started - # or not is to try to read from the file descriptor. If you get - # EOF immediately then it means that the child is already dead. - # That may not necessarily be bad, because you may haved spawned a child - # that performs some task; creates no stdout output; and then dies. - # It is a fuzzy edge case. Any child process that you are likely to - # want to interact with Pexpect would probably not fall into this - # category. - # FYI, This essentially does a fork/exec operation. - - assert self.pid == None, 'The pid member is not None.' - assert self.command != None, 'The command member is None.' - - if _which(self.command) == None: - raise ExceptionPexpect ('The command was not found or was not executable: %s.' % self.command) - - try: - self.pid, self.child_fd = pty.fork() - except OSError, e: - raise ExceptionPexpect('Pexpect: pty.fork() failed: ' + str(e)) - - if self.pid == 0: # Child - try: # Some platforms do not like setwinsize (Cygwin). - self.child_fd = sys.stdout.fileno() - self.setwinsize(24, 80) - except: - pass - # Do not allow child to inherit open file descriptors from parent. - max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] - for i in range (3, max_fd): - try: - os.close (i) - except OSError: - pass - - os.environ["LANG"] = "C" - os.environ["LANGUAGE"] = "C" - os.environ["LC_ALL"] = "C" - os.execvp(self.command, self.args) - - # Parent - self.__child_fd_owner = 1 - - def fileno (self): # File-like object. - """This returns the file descriptor of the pty for the child.""" - return self.child_fd - - def close (self, wait=1): # File-like object. - """ This closes the connection with the child application. - It makes no attempt to actually kill the child or wait for its status. - If the file descriptor was set by passing a file descriptor - to the constructor then this method raises an exception. - Note that calling close() more than once is valid. - This emulates standard Python behavior with files. - If wait is set to True then close will wait - for the exit status of the process. Doing a wait is a blocking call, - but this usually takes almost no time at all. Generally, - you don't have to worry about this. If you are - creating lots of children then you usually want to call wait. - Only set wait to false if you know the child will - continue to run after closing the controlling TTY. - Otherwise you will end up with defunct (zombie) processes. - """ - if self.child_fd != -1: - if not self.__child_fd_owner: - raise ExceptionPexpect ('This file descriptor cannot be closed because it was not created by spawn. The original creator is responsible for closing it.') - self.flush() - os.close (self.child_fd) - if wait: - os.waitpid (self.pid, 0) - self.child_fd = -1 - self.__child_fd_owner = None - - def flush (self): # File-like object. - """This does nothing. It is here to support the interface for a File-like object. - """ - pass - - def isatty (self): # File-like object. - """This returns 1 if the file descriptor is open and - connected to a tty(-like) device, else 0. - """ - return os.isatty(self.child_fd) - - def setecho (self, on): - """This sets the terminal echo mode on or off.""" - new = termios.tcgetattr(self.child_fd) - if on: - new[3] = new[3] | termios.ECHO # lflags - else: - new[3] = new[3] & ~termios.ECHO # lflags - termios.tcsetattr(self.child_fd, termios.TCSADRAIN, new) - - def setlog (self, fileobject): - """This sets logging output to go to the given fileobject. - Set fileobject to None to stop logging. - Example: - child = pexpect.spawn('some_command') - fout = file('mylog.txt','w') - child.setlog (fout) - ... - """ - self.log_file = fileobject - - def setmaxread (self, maxread): - """This sets the maximum number of bytes to read from a TTY at one time. - This is used to change the read buffer size. When a pexpect.spawn - object is created the default maxread is 1 (unbuffered). - Set this value higher to turn on buffer. This should help performance - in cases where large amounts of output are read back from the child. - """ - self.maxread = maxread - - def read_nonblocking (self, size = 1, timeout = None): - """ - This reads at most size characters from the child application. - It includes a timeout. If the read does not complete within the - timeout period then a TIMEOUT exception is raised. - If the end of file is read then an EOF exception will be raised. - If a log file was set using setlog() then all data will - also be written to the log file. - - Notice that if this method is called with timeout=None - then it actually may block. - - This is a non-blocking wrapper around os.read(). - It uses select.select() to implement a timeout. - """ - - if self.child_fd == -1: - raise ValueError ('I/O operation on closed file') - - # Note that some systems like Solaris don't seem to ever give - # an EOF when the child dies. In fact, you can still try to read - # from the child_fd -- it will block forever or until TIMEOUT. - # For this case, I test isalive() before doing any reading. - # If isalive() is false, then I pretend that this is the same as EOF. - if not self.isalive(): - r, w, e = select.select([self.child_fd], [], [], 0) - if not r: - self.flag_eof = 1 - raise EOF ('End Of File (EOF) in read(). Braindead platform.') - - r, w, e = select.select([self.child_fd], [], [], timeout) - if not r: - raise TIMEOUT('Timeout exceeded in read().') - - if self.child_fd in r: - try: - s = os.read(self.child_fd, size) - except OSError, e: - self.flag_eof = 1 - raise EOF('End Of File (EOF) in read(). Exception style platform.') - if s == '': - self.flag_eof = 1 - raise EOF('End Of File (EOF) in read(). Empty string style platform.') - - if self.log_file != None: - self.log_file.write (s) - self.log_file.flush() - - return s - - raise ExceptionPexpect('Reached an unexpected state in read().') - - def read (self, size = -1): # File-like object. - """This reads at most size bytes from the file - (less if the read hits EOF before obtaining size bytes). - If the size argument is negative or omitted, - read all data until EOF is reached. - The bytes are returned as a string object. - An empty string is returned when EOF is encountered immediately. - """ - if size == 0: - return '' - if size < 0: - self.expect (EOF) - return self.before - - # I could have done this more directly by not using expect(), but - # I deliberately decided to couple read() to expect() so that - # I would catch any bugs early and ensure consistant behavior. - # It's a little less efficient, but there is less for me to - # worry about if I have to later modify read() or expect(). - cre = re.compile('.{%d}' % size, re.DOTALL) - index = self.expect ([cre, EOF]) - if index == 0: - return self.after ### self.before should be ''. Should I assert this? - return self.before - - def readline (self, size = -1): # File-like object. - """This reads and returns one entire line. A trailing newline is kept in - the string, but may be absent when a file ends with an incomplete line. - Note: This readline() looks for a \r\n pair even on UNIX because this is - what the pseudo tty device returns. So contrary to what you may be used to - you will get a newline as \r\n. - An empty string is returned when EOF is hit immediately. - Currently, the size agument is mostly ignored, so this behavior is not - standard for a file-like object. - """ - if size == 0: - return '' - index = self.expect (['\r\n', EOF]) - if index == 0: - return self.before + '\r\n' - else: - return self.before - - def __iter__ (self): - """This is to support interators over a file-like object. - """ - return self - def next (self): - """This is to support iterators over a file-like object. - """ - result = self.readline() - if result == "": - raise StopIteration - return result - - def readlines (self, sizehint = -1): # File-like object. - """This reads until EOF using readline() and returns a list containing - the lines thus read. The optional sizehint argument is ignored. - """ - lines = [] - while 1: - line = self.readline() - if not line: - break - lines.append(line) - return lines - - def write(self, str): # File-like object. - """This is similar to send() except that there is no return value. - """ - self.send (str) - - def writelines (self, sequence): # File-like object. - """This calls write() for each element in the sequence. - The sequence can be any iterable object producing strings, - typically a list of strings. This does not add line separators - There is no return value. - """ - for str in sequence: - self.write (str) - - def send(self, str): - """This sends a string to the child process. - This returns the number of bytes written. - """ - return os.write(self.child_fd, str) - - def sendline(self, str=''): - """This is like send(), but it adds a line feed (os.linesep). - This returns the number of bytes written. - """ - n = self.send(str) - n = n + self.send (os.linesep) - return n - - def sendeof(self): - """This sends an EOF to the child. - This sends a character which causes the pending parent output - buffer to be sent to the waiting child program without - waiting for end-of-line. If it is the first character of the - line, the read() in the user program returns 0, which - signifies end-of-file. This means to work as expected - a sendeof() has to be called at the begining of a line. - This method does not send a newline. It is the responsibility - of the caller to ensure the eof is sent at the beginning of a line. - """ - ### Hmmm... how do I send an EOF? - ###C if ((m = write(pty, *buf, p - *buf)) < 0) - ###C return (errno == EWOULDBLOCK) ? n : -1; - fd = sys.stdin.fileno() - old = termios.tcgetattr(fd) # remember current state - new = termios.tcgetattr(fd) - new[3] = new[3] | termios.ICANON # lflags - # use try/finally to ensure state gets restored - try: - # EOF is recognized when ICANON is set, so make sure it is set. - termios.tcsetattr(fd, termios.TCSADRAIN, new) - os.write (self.child_fd, '%c' % termios.CEOF) - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old) # restore state - - def eof (self): - """This returns 1 if the EOF exception was raised at some point. - """ - return self.flag_eof - - def isalive(self): - """This tests if the child process is running or not. - This returns 1 if the child process appears to be running or 0 if not. - This also sets the exitstatus attribute. - It can take literally SECONDS for Solaris to return the right status. - This is the most wiggly part of Pexpect, but I think I've almost got - it nailed down. - """ - # I can't use signals. Signals on UNIX suck and they - # mess up Python pipes (setting SIGCHLD to SIGIGNORE). - - # If this class was created from an existing file descriptor then - # I just check to see if the file descriptor is still valid. - if self.pid == -1 and not self.__child_fd_owner: - try: - os.fstat(self.child_fd) - return 1 - except: - return 0 - - try: - pid, status = os.waitpid(self.pid, os.WNOHANG) - except OSError: - return 0 - - # I have to do this twice for Solaris. - # I can't even believe that I figured this out... - if pid == 0 and status == 0: - try: - pid, status = os.waitpid(self.pid, os.WNOHANG) - #print 'Solaris sucks' - except OSError: # This is crufty. When does this happen? - return 0 - # If pid and status is still 0 after two calls to waitpid() then - # the process really is alive. This seems to work on all platforms. - if pid == 0 and status == 0: - return 1 - - # I do not OR this together because I want hooks for debugging. - if os.WIFEXITED (status): - self.exitstatus = os.WEXITSTATUS(status) - return 0 - elif os.WIFSTOPPED (status): - return 0 - elif os.WIFSIGNALED (status): - return 0 - else: - return 0 # Can I ever get here? - - def kill(self, sig): - """This sends the given signal to the child application. - In keeping with UNIX tradition it has a misleading name. - It does not necessarily kill the child unless - you send the right signal. - """ - # Same as os.kill, but the pid is given for you. - if self.isalive(): - os.kill(self.pid, sig) - - def compile_pattern_list(self, patterns): - """This compiles a pattern-string or a list of pattern-strings. - Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or - a list of those. - - This is used by expect() when calling expect_list(). - Thus expect() is nothing more than:: - cpl = self.compile_pattern_list(pl) - return self.expect_list(clp, timeout) - - If you are using expect() within a loop it may be more - efficient to compile the patterns first and then call expect_list(). - This avoid calls in a loop to compile_pattern_list(): - cpl = self.compile_pattern_list(my_pattern) - while some_condition: - ... - i = self.expect_list(clp, timeout) - ... - """ - if type(patterns) is not ListType: - patterns = [patterns] - - compiled_pattern_list = [] - for p in patterns: - if type(p) is StringType: - compiled_pattern_list.append(re.compile(p, re.DOTALL)) - elif p is EOF: - compiled_pattern_list.append(EOF) - elif p is TIMEOUT: - compiled_pattern_list.append(TIMEOUT) - elif type(p) is type(re.compile('')): - compiled_pattern_list.append(p) - else: - raise TypeError, 'Argument must be one of StringType, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p)) - - return compiled_pattern_list - - def expect(self, pattern, timeout = -1): - """This seeks through the stream until a pattern is matched. - The pattern is overloaded and may take several types including a list. - The pattern can be a StringType, EOF, a compiled re, or - a list of those types. Strings will be compiled to re types. - This returns the index into the pattern list. If the pattern was - not a list this returns index 0 on a successful match. - This may raise exceptions for EOF or TIMEOUT. - To avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to - the pattern list. - - After a match is found the instance attributes - 'before', 'after' and 'match' will be set. - You can see all the data read before the match in 'before'. - You can see the data that was matched in 'after'. - The re.MatchObject used in the re match will be in 'match'. - If an error occured then 'before' will be set to all the - data read so far and 'after' and 'match' will be None. - - If timeout is -1 then timeout will be set to the self.timeout value. - - Note: A list entry may be EOF or TIMEOUT instead of a string. - This will catch these exceptions and return the index - of the list entry instead of raising the exception. - The attribute 'after' will be set to the exception type. - The attribute 'match' will be None. - This allows you to write code like this: - index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) - if index == 0: - do_something() - elif index == 1: - do_something_else() - elif index == 2: - do_some_other_thing() - elif index == 3: - do_something_completely_different() - instead of code like this: - try: - index = p.expect (['good', 'bad']) - if index == 0: - do_something() - elif index == 1: - do_something_else() - except EOF: - do_some_other_thing() - except TIMEOUT: - do_something_completely_different() - These two forms are equivalent. It all depends on what you want. - You can also just expect the EOF if you are waiting for all output - of a child to finish. For example: - p = pexpect.spawn('/bin/ls') - p.expect (pexpect.EOF) - print p.before - """ - compiled_pattern_list = self.compile_pattern_list(pattern) - return self.expect_list(compiled_pattern_list, timeout) - - def expect_exact (self, pattern_list, timeout = -1): - """This is similar to expect() except that it takes - list of plain strings instead of regular expressions. - The idea is that this should be much faster. It could also be - useful when you don't want to have to worry about escaping - regular expression characters that you want to match. - You may also pass just a string without a list and the single - string will be converted to a list. - If timeout is -1 then timeout will be set to the self.timeout value. - """ - ### This is dumb. It shares most of the code with expect_list. - ### The only different is the comparison method and that - ### self.match is always None after calling this. - if timeout == -1: - timeout = self.timeout - - if type(pattern_list) is StringType: - pattern_list = [pattern_list] - - try: - #ED# incoming = '' - incoming = self.buffer - while 1: # Keep reading until exception or return. - #ED# c = self.read_nonblocking (1, timeout) - #ED# incoming = incoming + c - - # Sequence through the list of patterns and look for a match. - index = -1 - for str_target in pattern_list: - index = index + 1 - if str_target is EOF or str_target is TIMEOUT: - continue # The Exception patterns are handled differently. - match_index = incoming.find (str_target) - if match_index >= 0: - self.before = incoming [ : match_index] - self.after = incoming [match_index : ] - self.buffer = incoming [match_index + len(str_target):] - self.match = None - return index - c = self.read_nonblocking (self.maxread, timeout) - incoming = incoming + c - - except EOF: - if EOF in pattern_list: - self.before = incoming - self.after = EOF - self.buffer = '' - return pattern_list.index(EOF) - else: - raise - except TIMEOUT: - if TIMEOUT in pattern_list: - self.before = incoming - self.after = TIMEOUT - self.buffer = '' - return pattern_list.index(TIMEOUT) - else: - raise - except Exception: - self.before = incoming - self.after = None - self.match = None - self.buffer = '' - raise - - def expect_list(self, pattern_list, timeout = -1): - """ - This takes a list of compiled regular expressions and returns - the index into the pattern_list that matched the child's output. - This is called by expect(). It is similar to the expect() method - except that expect_list() is not overloaded. You must not pass - anything except a list of compiled regular expressions. - If timeout is -1 then timeout will be set to the self.timeout value. - """ - - if timeout == -1: - timeout = self.timeout - - try: - #ED# incoming = '' - incoming = self.buffer - while 1: # Keep reading until exception or return. - #ED# c = self.read_nonblocking (1, timeout) - #ED# incoming = incoming + c - - # Sequence through the list of patterns and look for a match. - index = -1 - for cre in pattern_list: - index = index + 1 - if cre is EOF or cre is TIMEOUT: - continue # The patterns for PexpectExceptions are handled differently. - match = cre.search(incoming) - if match is not None: - self.before = incoming[ : match.start()] - self.after = incoming[match.start() : ] - self.match = match - self.buffer = incoming[match.end() : ] - return index - # Read more data - c = self.read_nonblocking (self.maxread, timeout) - incoming = incoming + c - - except EOF: - if EOF in pattern_list: - self.before = incoming - self.after = EOF - self.buffer = '' - return pattern_list.index(EOF) - else: - raise - except TIMEOUT: - if TIMEOUT in pattern_list: - self.before = incoming - self.after = TIMEOUT - self.buffer = '' - return pattern_list.index(TIMEOUT) - else: - raise - except Exception: - self.before = incoming - self.after = None - self.match = None - self.buffer = '' - raise - - def getwinsize(self): - """ - This returns the window size of the child tty. - The return value is a tuple of (rows, cols). - """ - - s = struct.pack('HHHH', 0, 0, 0, 0) - x = fcntl.ioctl(self.fileno(), termios.TIOCGWINSZ, s) - return struct.unpack('HHHH', x)[0:2] - - def setwinsize(self, r, c): - """ - This sets the windowsize of the child tty. - This will cause a SIGWINCH signal to be sent to the child. - This does not change the physical window size. - It changes the size reported to TTY-aware applications like - vi or curses -- applications that respond to the SIGWINCH signal. - """ - # Check for buggy platforms. Some Python versions on some platforms - # (notably OSF1 Alpha and RedHat 7.1) truncate the value for - # termios.TIOCSWINSZ. It is not clear why this happens. - # These platforms don't seem to handle the signed int very well; - # yet other platforms like OpenBSD have a large negative value for - # TIOCSWINSZ and they don't have a truncate problem. - # Newer versions of Linux have totally different values for TIOCSWINSZ. - # - # Note that this fix is a hack. - TIOCSWINSZ = termios.TIOCSWINSZ - if TIOCSWINSZ == 2148037735L: # L is not required in Python >= 2.2. - TIOCSWINSZ = -2146929561 # Same bits, but with sign. - - # Note, assume ws_xpixel and ws_ypixel are zero. - s = struct.pack('HHHH', r, c, 0, 0) - fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) - - def interact(self, escape_character = chr(29)): - """This gives control of the child process to the interactive user - (the human at the keyboard). - Keystrokes are sent to the child process, and the stdout and stderr - output of the child process is printed. - When the user types the escape_character this method will stop. - The default for escape_character is ^] (ASCII 29). - This simply echos the child stdout and child stderr to the real - stdout and it echos the real stdin to the child stdin. - """ - # Flush the buffer. - self.stdout.write (self.buffer) - self.buffer = '' - self.stdout.flush() - mode = tty.tcgetattr(self.STDIN_FILENO) - tty.setraw(self.STDIN_FILENO) - try: - self.__interact_copy(escape_character) - finally: - tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) - - def __interact_writen(self, fd, data): - """This is used by the interact() method. - """ - while data != '' and self.isalive(): - n = os.write(fd, data) - data = data[n:] - def __interact_read(self, fd): - """This is used by the interact() method. - """ - return os.read(fd, 1000) - def __interact_copy(self, escape_character = None): - """This is used by the interact() method. - """ - while self.isalive(): - r, w, e = select.select([self.child_fd, self.STDIN_FILENO], [], []) - if self.child_fd in r: - data = self.__interact_read(self.child_fd) - os.write(self.STDOUT_FILENO, data) - if self.STDIN_FILENO in r: - data = self.__interact_read(self.STDIN_FILENO) - self.__interact_writen(self.child_fd, data) - if escape_character in data: - break - -############################################################################## -# End of Spawn -############################################################################## - -def _which (filename): - """This takes a given filename; tries to find it in the - environment path; then checks if it is executable. - """ - - # Special case where filename already contains a path. - if os.path.dirname(filename) != '': - if os.access (filename, os.X_OK): - return filename - - if not os.environ.has_key('PATH') or os.environ['PATH'] == '': - p = os.defpath - else: - p = os.environ['PATH'] - - # Oddly enough this was the one line that made Pexpect - # incompatible with Python 1.5.2. - #pathlist = p.split (os.pathsep) - pathlist = string.split (p, os.pathsep) - - for path in pathlist: - f = os.path.join(path, filename) - if os.access(f, os.X_OK): - return f - return None - -def _split_command_line(command_line): - """This splits a command line into a list of arguments. - It splits arguments on spaces, but handles - embedded quotes, doublequotes, and escaped characters. - It's impossible to do this with a regular expression, so - I wrote a little state machine to parse the command line. - """ - arg_list = [] - arg = '' - state_quote = 0 - state_doublequote = 0 - state_esc = 0 - for c in command_line: - if c == '\\': # Escape the next character - state_esc = 1 - elif c == r"'": # Handle single quote - if state_esc: - state_esc = 0 - elif not state_quote: - state_quote = 1 - else: - state_quote = 0 - elif c == r'"': # Handle double quote - if state_esc: - state_esc = 0 - elif not state_doublequote: - state_doublequote = 1 - else: - state_doublequote = 0 - - # Add arg to arg_list unless in some other state. - elif c == ' 'and not state_quote and not state_doublequote and not state_esc: - arg_list.append(arg) - arg = '' - else: - arg = arg + c - if c != '\\'and state_esc: # escape mode lasts for one character. - state_esc = 0 - - # Handle last argument. - if arg != '': - arg_list.append(arg) - return arg_list - -import shlex -def _split_command_line(command_line): - return shlex.split(command_line) - - -#################### -# -# NOTES -# -#################### - -## def send_human(self, text, delay_min = 0, delay_max = 1): -## pass -## def spawn2(self, command, args): -## """return pid, fd_stdio, fd_stderr -## """ -## pass - - -# Reason for double fork: -# http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC15 -# Reason for ptys: -# http://www.erlenstar.demon.co.uk/unix/faq_4.html#SEC52 - -# Nonblocking on Win32? -# Reasearch this as a way to maybe make pipe work for Win32. -# http://groups.google.com/groups?q=setraw+tty&hl=en&selm=uvgpvisvk.fsf%40roundpoint.com&rnum=7 -# -# if istty: -# if os.name=='posix': -# import tty -# tty.setraw(sys.stdin.fileno()) -# elif os.name=='nt': -# import win32file, win32con -# hstdin = win32file._get_osfhandle(sys.stdin.fileno()) -# modes = (win32file.GetConsoleMode(hstdin) -# & ~(win32con.ENABLE_LINE_INPUT -# |win32con.ENABLE_ECHO_INPUT)) -# win32file.SetConsoleMode(hstdin, modes) - -# Basic documentation: -# Explain use of lists of patterns and return index. -# Explain exceptions for non-handled special cases like EOF - -# Test bad fork -# Test ENOENT. In other words, no more TTY devices. - -#GLOBAL_SIGCHLD_RECEIVED = 0 -#def childdied (signum, frame): -# print 'Signal handler called with signal', signum -# frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED = 1 -# print str(frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED) -# GLOBAL_SIGCHLD_RECEIVED = 1 - -### Weird bug. If you read too fast after doing a sendline() -# Sometimes you will read the data back that you just sent even if -# the child did not echo the data. This is particularly a problem if -# you send a password. - -# This was previously used to implement a look-ahead in reads. -# if the lookahead failed then Pexpect would "push-back" the data -# that was read. The idea was to allow read() to read blocks of data. -# What I do now is just read one character at a time and then try a -# match. This is not as efficient, but it works well enough for the -# output of most applications and it makes program logic much simpler. -##class PushbackReader: -## """This class is a wrapper around os.read. It adds the features of buffering -## to allow push-back of data and to provide a timeout on a read. -## """ -## def __init__(self, file_descriptor): -## self.fd = file_descriptor -## self.buffer = '' -## -## def read(self, n, timeout = None): -## """This does a read restricted by a timeout and -## it includes any cached data from previous calls. -## This is a non-blocking wrapper around os.read. -## it uses select.select to supply a timeout. -## Note that if this is called with timeout=None (the default) -## then this actually MAY block. -## """ -## # The read() call is a problem. -## # Some platforms return an empty string '' at EOF. -## # Whereas other platforms raise an Input/output exception. -## -## avail = len(self.buffer) -## if n > avail: -## result = self.buffer -## n = n-avail -## else: -## result = self.buffer[: n] -## self.buffer = self.buffer[n:] -## -## r, w, e = select.select([self.fd], [], [], timeout) -## if not r: -## self.flag_timeout = 1 -## raise TIMEOUT('Read exceeded time: %d'%timeout) -## -## if self.fd in r: -## try: -## s = os.read(self.fd, n) -## except OSError, e: -## self.flag_eof = 1 -## raise EOF('Read reached End Of File (EOF). Exception platform.') -## if s == '': -## self.flag_eof = 1 -## raise EOF('Read reached End Of File (EOF). Empty string platform.') -## return s -## -## self.flag_error = 1 -## raise ExceptionPexpect('PushbackReader.read() reached an unexpected state.'+ -## ' There is a logic error in the Pexpect source code.') -## -## def pushback(self, data): -## self.buffer = piece+self.buffer - - -#def _setwinsize(r, c): -# """This sets the windowsize of the tty for stdout. -# This does not change the physical window size. -# It changes the size reported to TTY-aware applications like -# vi or curses -- applications that respond to the SIGWINCH signal. -# This is used by __spawn to set the tty window size of the child. -# """ -# # Check for buggy platforms. Some Pythons on some platforms -# # (notably OSF1 Alpha and RedHat 7.1) truncate the value for -# # termios.TIOCSWINSZ. It is not clear why this happens. -# # These platforms don't seem to handle the signed int very well; -# # yet other platforms like OpenBSD have a large negative value for -# # TIOCSWINSZ and they don't truncate. -# # Newer versions of Linux have totally different values for TIOCSWINSZ. -# # -# # Note that this fix is a hack. -# TIOCSWINSZ = termios.TIOCSWINSZ -# if TIOCSWINSZ == 2148037735L: # L is not required in Python 2.2. -# TIOCSWINSZ = -2146929561 # Same number in binary, but with sign. -# -# # Assume ws_xpixel and ws_ypixel are zero. -# s = struct.pack("HHHH", r, c, 0, 0) -# fcntl.ioctl(sys.stdout.fileno(), TIOCSWINSZ, s) -# -#def _getwinsize(): -# s = struct.pack("HHHH", 0, 0, 0, 0) -# x = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, s) -# return struct.unpack("HHHH", x) - diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 774f64f..a461fc2 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -14,7 +14,7 @@ import sys import os def get_spec(pkgdirurl, targetdir=".", submit=False): - svn = SVN(baseurl=pkgdirurl) + svn = SVN() tmpdir = tempfile.mktemp() try: geturl = "/".join([pkgdirurl, "current", "SPECS"]) @@ -47,7 +47,7 @@ def get_srpm(pkgdirurl, template = None, macros = [], verbose = 0): - svn = SVN(baseurl=pkgdirurl) + svn = SVN() tmpdir = tempfile.mktemp() topdir = "--define '_topdir %s'" % tmpdir builddir = "--define '_builddir %s/%s'" % (tmpdir, "BUILD") @@ -120,7 +120,7 @@ def get_srpm(pkgdirurl, shutil.rmtree(tmpdir) def patch_spec(pkgdirurl, patchfile, log=""): - svn = SVN(baseurl=pkgdirurl) + svn = SVN() tmpdir = tempfile.mktemp() try: geturl = "/".join([pkgdirurl, "current", "SPECS"]) @@ -142,7 +142,7 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""): srpm = SRPM(srpmfile) if appendname: pkgdirurl = "/".join([pkgdirurl, srpm.name]) - svn = SVN(baseurl=pkgdirurl) + svn = SVN() tmpdir = tempfile.mktemp() try: if srpm.epoch: @@ -239,7 +239,7 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""): (version, srpm.release)) def create_package(pkgdirurl, log="", verbose=0): - svn = SVN(baseurl=pkgdirurl) + svn = SVN() tmpdir = tempfile.mktemp() try: basename = RepSysTree.pkgname(pkgdirurl) @@ -280,7 +280,7 @@ revision: %s return log def mark_release(pkgdirurl, version, release, revision): - svn = SVN(baseurl=pkgdirurl) + svn = SVN() releasesurl = "/".join([pkgdirurl, "releases"]) versionurl = "/".join([releasesurl, version]) releaseurl = "/".join([versionurl, release]) @@ -302,7 +302,7 @@ def mark_release(pkgdirurl, version, release, revision): log=markreleaselog) def check_changed(pkgdirurl, all=0, show=0, verbose=0): - svn = SVN(baseurl=pkgdirurl) + svn = SVN() if all: baseurl = pkgdirurl packages = [] @@ -372,7 +372,7 @@ def checkout(pkgdirurl, path=None, revision=None, use_mirror=True): if (o_pkgdirurl != pkgdirurl) and use_mirror and mirror.enabled(): current = mirror.checkout_url(current) print "checking out from mirror", current - svn = SVN(baseurl=pkgdirurl) + svn = SVN() svn.checkout(current, path, rev=revision, show=1) def _getpkgtopdir(basedir=None): @@ -387,7 +387,7 @@ def _getpkgtopdir(basedir=None): return topdir def sync(dryrun=False): - svn = SVN(noauth=True) + svn = SVN() topdir = _getpkgtopdir() # run svn info because svn st does not complain when topdir is not an # working copy @@ -438,7 +438,7 @@ def sync(dryrun=False): svn.add(path, local=True) def commit(target=".", message=None): - svn = SVN(noauth=True) + svn = SVN() status = svn.status(target, quiet=True) if not status: print "nothing to commit" @@ -451,7 +451,8 @@ def commit(target=".", message=None): if mirrored: newurl = mirror.switchto_parent(svn, url, target) print "relocated to", newurl - # we can't use the svn object here because pexpect hides VISUAL + # we can't use the svn object here because svn --non-interactive option + # hides VISUAL mopt = "" if message is not None: mopt = "-m \"%s\"" % message @@ -461,7 +462,7 @@ def commit(target=".", message=None): "later" def switch(mirrorurl=None): - svn = SVN(noauth=True) + svn = SVN() topdir = _getpkgtopdir() info = svn.info2(topdir) wcurl = info.get("URL") @@ -490,7 +491,7 @@ def get_submit_info(path): if not os.path.isdir(os.path.join(path, ".svn")): raise Error, "subversion directory not found" - svn = SVN(noauth=True) + svn = SVN() # Now, extract the package name. info = svn.info2(path) diff --git a/RepSys/svn.py b/RepSys/svn.py index b91af0c..3244c3a 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -1,4 +1,4 @@ -from RepSys import Error, config, pexpect +from RepSys import Error, config from RepSys.util import execcmd, get_auth import sys import re @@ -18,67 +18,26 @@ class SVNLogEntry: return cmp(self.date, other.date) class SVN: - def __init__(self, username=None, password=None, noauth=0, baseurl=None): - self.noauth = noauth or ( - baseurl and ( - baseurl.startswith("file:") or - baseurl.startswith("svn+ssh:"))) - if not self.noauth: # argh - self.username, self.password = get_auth() - - def _execsvn(self, *args, **kwargs): - cmdstr = "svn "+" ".join(args) - if kwargs.get("local") or kwargs.get("noauth") or self.noauth: + if not kwargs.get("show"): + args = list(args) + args.append("--non-interactive") + svn_command = config.get("global", "svn-command", + "SVN_SSH='ssh -o \"BatchMode yes\"' svn") + cmdstr = svn_command + " " + " ".join(args) + try: return execcmd(cmdstr, **kwargs) - show = kwargs.get("show") - noerror = kwargs.get("noerror") - p = pexpect.spawn(cmdstr, timeout=1) - p.setmaxread(1024) - p.setecho(False) - outlist = [] - while True: - i = p.expect_exact([pexpect.EOF, pexpect.TIMEOUT, - "username:", "password:", - "(p)ermanently?", - "Authorization failed"]) - if i == 0: - if show and p.before: - print p.before, - outlist.append(p.before) - break - elif i == 1: - if show and p.before: - print p.before, - outlist.append(p.before) - elif i == 2: - p.sendline(self.username) - outlist = [] - elif i == 3: - p.sendline(self.password) - outlist = [] - elif i == 4: - p.sendline("p") - outlist = [] - elif i == 5: - if not noerror: - raise Error, "authorization failed" - else: - break - while p.isalive(): - try: - time.sleep(1) - except (pexpect.TIMEOUT, pexpect.EOF): - # Continue until the child dies - pass - status, output = p.exitstatus, "".join(outlist).strip() - if status != 0 and not kwargs.get("noerror"): - sys.stderr.write(cmdstr) - sys.stderr.write("\n") - sys.stderr.write(output) - sys.stderr.write("\n") - raise Error, "command failed: "+cmdstr - return status, output + except Error, e: + if "Permission denied" in e.message: + raise Error, ("%s\n" + "Seems ssh-agent or ForwardAgent are not setup, see " + "http://wiki.mandriva.com/en/Development/Docs/Contributor_Tricks#SSH_configuration" + " for more information." % e) + elif "authorization failed": + raise Error, ("%s\n" + "Note that repsys does not support any HTTP " + "authenticated access." % e) + raise def _execsvn_success(self, *args, **kwargs): status, output = self._execsvn(*args, **kwargs) -- cgit v1.2.1 From 007212afccceca682e0f98f2871398a3ff35db03 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:47:14 +0000 Subject: Added option -F to repsys ci, as in svn ci --- CHANGES | 1 + RepSys/commands/ci.py | 4 ++++ RepSys/rpmutil.py | 11 +++++++---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 27c0899..b7f67a7 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,7 @@ interactivity at all with ssh - fixed bad url used when using -v in getsrpm - make 'repsys submit' without package name or revision number work again +- added option -F to repsys ci to set a log message file - the fix for the unreleased commits problem in the previous release was wrong, really fixed it - don't give the wrong message "invalid command 'CMD'" when this is not diff --git a/RepSys/commands/ci.py b/RepSys/commands/ci.py index 9ffa3bd..b6a54f6 100644 --- a/RepSys/commands/ci.py +++ b/RepSys/commands/ci.py @@ -11,6 +11,8 @@ in case the option "mirror" is set in repsys.conf. Options: -h Show this message + -m MSG Use the MSG as the log message + -F FILE Read log message from FILE Examples: repsys ci @@ -20,6 +22,8 @@ Examples: def parse_options(): parser = OptionParser(help=HELP) parser.add_option("-m", dest="message", default=None) + parser.add_option("-F", dest="logfile", type="string", + default=None) opts, args = parser.parse_args() if len(args): opts.target = args[0] diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index a461fc2..7481b72 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -437,7 +437,7 @@ def sync(dryrun=False): if not dryrun: svn.add(path, local=True) -def commit(target=".", message=None): +def commit(target=".", message=None, logfile=None): svn = SVN() status = svn.status(target, quiet=True) if not status: @@ -453,10 +453,13 @@ def commit(target=".", message=None): print "relocated to", newurl # we can't use the svn object here because svn --non-interactive option # hides VISUAL - mopt = "" + opts = [] if message is not None: - mopt = "-m \"%s\"" % message - os.system("svn ci %s %s" % (mopt, target)) + opts.append("-m \"%s\"" % message) + if logfile is not None: + opts.append("-F \"%s\"" % logfile) + mopts = " ".join(opts) + os.system("svn ci %s %s" % (mopts, target)) if mirrored: print "use \"repsys switch\" in order to switch back to mirror "\ "later" -- cgit v1.2.1 From 2295fcbbaa57f13a838a2f18714b17d0b755cb2f Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:47:58 +0000 Subject: Fixed the use of file:/// URLs when using just the package name --- CHANGES | 1 + RepSys/command.py | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index b7f67a7..fa2089f 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,7 @@ - added option -F to repsys ci to set a log message file - the fix for the unreleased commits problem in the previous release was wrong, really fixed it +- fixed the use of file:/// URLs when using just the package name - don't give the wrong message "invalid command 'CMD'" when this is not the case diff --git a/RepSys/command.py b/RepSys/command.py index 8029e08..1833bcd 100644 --- a/RepSys/command.py +++ b/RepSys/command.py @@ -1,6 +1,7 @@ #!/usr/bin/python from RepSys import Error, config -import sys, os, urllib +import sys, os +import urlparse import optparse __all__ = ["OptionParser", "do_command", "default_parent"] @@ -46,8 +47,9 @@ def default_parent(url): if not default_parent: raise Error, "received a relative url, " \ "but default_parent was not setup" - type, rest = urllib.splittype(default_parent) - url = type+':'+os.path.normpath(rest+'/'+url) + parsed = list(urlparse.urlparse(default_parent)) + parsed[2] = os.path.normpath(parsed[2] + "/" + url) + url = urlparse.urlunparse(parsed) return url # vim:et:ts=4:sw=4 -- cgit v1.2.1 From bd902e2a4a1214bb34dadb58d5606888807778cc Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:48:40 +0000 Subject: Make REPSYS_CONF override /etc/repsys.conf and ~/.repsys/config This way we can have real control over where to look for configuration file. The old behavior was a problem for testes and things like. --- CHANGES | 2 ++ RepSys/ConfigParser.py | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index fa2089f..849b3ae 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,8 @@ interactivity at all with ssh - fixed bad url used when using -v in getsrpm - make 'repsys submit' without package name or revision number work again +- if REPSYS_CONF is set, /etc/repsys.conf and ~/.repsys/config will not be + readed anymore - added option -F to repsys ci to set a log message file - the fix for the unreleased commits problem in the previous release was wrong, really fixed it diff --git a/RepSys/ConfigParser.py b/RepSys/ConfigParser.py index 4dc3e3c..3b4e213 100644 --- a/RepSys/ConfigParser.py +++ b/RepSys/ConfigParser.py @@ -350,11 +350,12 @@ class Config: self._config = ConfigParser() self._wrapped = {} conffiles = [] - conffiles.append("/etc/repsys.conf") repsys_conf = os.environ.get("REPSYS_CONF") if repsys_conf: conffiles.append(repsys_conf) - conffiles.append(os.path.expanduser("~/.repsys/config")) + else: + conffiles.append("/etc/repsys.conf") + conffiles.append(os.path.expanduser("~/.repsys/config")) for file in conffiles: if os.path.isfile(file): self._config.read(file) -- cgit v1.2.1 From 91d55b129c0b8fb2980aaa372e053e8a3c157935 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:49:18 +0000 Subject: Make SVN.info2 to return None when the target is not versioned --- RepSys/svn.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RepSys/svn.py b/RepSys/svn.py index 3244c3a..4b1e9da 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -125,12 +125,14 @@ class SVN: def info(self, path, **kwargs): cmd = ["info", path] status, output = self._execsvn(local=True, *cmd, **kwargs) - if status == 0: + if status == 0 and "Not a versioned resource" not in output: return output.splitlines() return None def info2(self, *args, **kwargs): lines = self.info(*args, **kwargs) + if lines is None: + return None pairs = [[w.strip() for w in line.split(":", 1)] for line in lines] info = dict(pairs) return info -- cgit v1.2.1 From 936d5717d1b4afc17b04afbe02ad7aff8770722d Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:51:43 +0000 Subject: Small changes in help messages: - Added URL of the repository system Quickstart - Make the help message of ci clearer - Removed reference to --help-plugins - Added a simple description for repsys in main help - Added short description of interesting subcommands in main help - Updated CHANGES - Reformeatted the 'switch' message to make it easier to read - Improved the help message of 'submit', added reference to the status page - Better help message for rpmlog - Added help message for patchspec - Better help message for markrelease - Added a help message for getsrpm - Added help message for getspec - Better help message for 'create' + changed example URL - Added a clearer help message for co - Added some text explaining 'changed' - Better authoremail help - Clearer message about uncommenting config option - Removed all configuration options that are not needed by one external - Putsrpm is not working, remove from help message - Added another usage example for submit --- CHANGES | 1 + RepSys/commands/authoremail.py | 3 +++ RepSys/commands/changed.py | 2 ++ RepSys/commands/ci.py | 8 +++++--- RepSys/commands/co.py | 6 ++++++ RepSys/commands/create.py | 5 ++++- RepSys/commands/getspec.py | 5 ++++- RepSys/commands/getsrpm.py | 4 ++++ RepSys/commands/markrelease.py | 5 +++++ RepSys/commands/patchspec.py | 2 ++ RepSys/commands/rpmlog.py | 5 ++++- RepSys/commands/submit.py | 9 +++++++++ RepSys/commands/switch.py | 7 ++++--- repsys | 29 +++++++++++++++-------------- repsys.conf | 38 +------------------------------------- 15 files changed, 69 insertions(+), 60 deletions(-) diff --git a/CHANGES b/CHANGES index 849b3ae..d1db357 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ - fixed the use of file:/// URLs when using just the package name - don't give the wrong message "invalid command 'CMD'" when this is not the case +- added more help messages in subcommands * 1.6.19 - added complement for SILENT: CLOG, which hides everything that does not diff --git a/RepSys/commands/authoremail.py b/RepSys/commands/authoremail.py index aee7b58..f5b8b70 100644 --- a/RepSys/commands/authoremail.py +++ b/RepSys/commands/authoremail.py @@ -7,6 +7,9 @@ import getopt HELP = """\ Usage: repsys authoremail [OPTIONS] AUTHOR +Shows the e-mail of an SVN author. It is just a simple interface to access +the [authors] section of repsys.conf. + Options: -h Show this message diff --git a/RepSys/commands/changed.py b/RepSys/commands/changed.py index d3094a8..62b20b6 100644 --- a/RepSys/commands/changed.py +++ b/RepSys/commands/changed.py @@ -8,6 +8,8 @@ import sys HELP = """\ Usage: repsys changed [OPTIONS] URL +Shows if there are pending changes since the last package release. + Options: -a Check all packages in given URL -s Show differences diff --git a/RepSys/commands/ci.py b/RepSys/commands/ci.py index b6a54f6..8d373b5 100644 --- a/RepSys/commands/ci.py +++ b/RepSys/commands/ci.py @@ -5,9 +5,11 @@ from RepSys.rpmutil import commit HELP = """\ Usage: repsys ci [TARGET] -Will commit a change. The difference between an ordinary "svn ci" and -"repsys ci" is that it relocates the working copy to the default repository -in case the option "mirror" is set in repsys.conf. +Will commit recent modifications in the package. + +The difference between an ordinary "svn ci" and "repsys ci" is that it +relocates the working copy to the default repository in case the option +"mirror" is set in repsys.conf. Options: -h Show this message diff --git a/RepSys/commands/co.py b/RepSys/commands/co.py index cadcf56..830b7e7 100644 --- a/RepSys/commands/co.py +++ b/RepSys/commands/co.py @@ -8,12 +8,18 @@ import sys HELP = """\ Usage: repsys co [OPTIONS] URL [LOCALPATH] +Checkout the package source from the Mandriva repository. + +If the 'mirror' option is enabled, the package is obtained from the mirror +repository. + Options: -r REV Revision to checkout -o Do not use the mirror (use official server) -h Show this message Examples: + repsys co pkgname repsys co http://repos/svn/cnc/snapshot/foo repsys co http://repos/svn/cnc/snapshot/foo foo-pkg """ diff --git a/RepSys/commands/create.py b/RepSys/commands/create.py index 56af1ef..a8709f0 100644 --- a/RepSys/commands/create.py +++ b/RepSys/commands/create.py @@ -8,11 +8,14 @@ import sys HELP = """\ Usage: repsys create [OPTIONS] URL +Creates the minimal structure of a package in the repository. + Options: -h Show this message Examples: - repsys create http://repos/svn/cnc/snapshot/newpkg + repsys create newpkg + repsys create svn+ssh://svn.mandriva.com/svn/packages/cooker/newpkg """ def parse_options(): diff --git a/RepSys/commands/getspec.py b/RepSys/commands/getspec.py index 1079a81..5e44074 100644 --- a/RepSys/commands/getspec.py +++ b/RepSys/commands/getspec.py @@ -8,12 +8,15 @@ import sys HELP = """\ Usage: repsys getspec [OPTIONS] REPPKGURL +Prints the .spec file of a given package. + Options: -t DIR Use DIR as target for spec file (default is ".") -h Show this message Examples: - repsys getspec http://repos/svn/cnc/snapshot/foo + repsys getspec pkgname + repsys getspec svn+ssh://svn.mandriva.com/svn/packages/cooker/pkgname """ def parse_options(): diff --git a/RepSys/commands/getsrpm.py b/RepSys/commands/getsrpm.py index d76aca7..f1ebfe1 100644 --- a/RepSys/commands/getsrpm.py +++ b/RepSys/commands/getsrpm.py @@ -16,6 +16,8 @@ import os HELP = """\ Usage: repsys getsrpm [OPTIONS] REPPKGURL +Generates the source RPM (.srpm) file of a given package. + Options: -c Use files in current/ directory (default) -p Use files in pristine/ directory @@ -30,6 +32,8 @@ Options: -h Show this message Examples: + repsys getsrpm python + repsys getsrpm -l python repsys getsrpm http://foo.bar/svn/cnc/snapshot/python repsys getsrpm -p http://foo.bar/svn/cnc/releases/8cl/python repsys getsrpm -r 1001 file:///svn/cnc/snapshot/python diff --git a/RepSys/commands/markrelease.py b/RepSys/commands/markrelease.py index 440775b..1707f39 100644 --- a/RepSys/commands/markrelease.py +++ b/RepSys/commands/markrelease.py @@ -21,6 +21,11 @@ HELP = """\ Usage: repsys markrelease [OPTIONS] REPPKGURL +This subcommand creates a 'tag' for a given revision of a given package. + +The tag will be stored in the directory releases/ inside the package +structure. + Options: -f FILE Try to extract information from given file -r REV Revision which will be used to make the release copy tag diff --git a/RepSys/commands/patchspec.py b/RepSys/commands/patchspec.py index 155ff4f..8330cc3 100644 --- a/RepSys/commands/patchspec.py +++ b/RepSys/commands/patchspec.py @@ -11,6 +11,8 @@ import sys HELP = """\ Usage: repsys patchspec [OPTIONS] REPPKGURL PATCHFILE +It will try to patch a spec file from a given package url. + Options: -l LOG Use LOG as log message -h Show this message diff --git a/RepSys/commands/rpmlog.py b/RepSys/commands/rpmlog.py index 7ea1ac0..5ba5fdd 100644 --- a/RepSys/commands/rpmlog.py +++ b/RepSys/commands/rpmlog.py @@ -12,6 +12,8 @@ import sys HELP = """\ Usage: repsys rpmlog [OPTIONS] REPPKGDIRURL +Prints the RPM changelog of a given package. + Options: -r REV Collect logs from given revision to revision 0 -n NUM Output only last NUM entries @@ -19,7 +21,8 @@ Options: -h Show this message Examples: - repsys rpmlog https://repos/snapshot/python + repsys rpmlog python + repsys rpmlog http://svn.mandriva.com/svn/packages/cooker/python """ def parse_options(): diff --git a/RepSys/commands/submit.py b/RepSys/commands/submit.py index 25d5831..bd6e01c 100644 --- a/RepSys/commands/submit.py +++ b/RepSys/commands/submit.py @@ -20,6 +20,14 @@ Usage: repsys submit [OPTIONS] [URL [REVISION]] Submits the package from URL to the submit host. +The submit host will try to build the package, and upon successful +completion will 'tag' the package and upload it to the official +repositories. + +The status of the submit can visualized at: + +http://kenobi.mandriva.com/bs/output.php + If no URL and revision are specified, the latest changed revision in the package working copy of the current directory will be used. @@ -40,6 +48,7 @@ Examples: repsys submit https://repos/svn/mdv/cooker/foo 14800 repsys submit -r 14800 https://repos/svn/mdv/cooker/foo repsys submit -l https://repos + repsys submit --define section=main/testing -t 2008.0 """ def parse_options(): diff --git a/RepSys/commands/switch.py b/RepSys/commands/switch.py index dcbdd17..5cbe2d7 100644 --- a/RepSys/commands/switch.py +++ b/RepSys/commands/switch.py @@ -5,9 +5,10 @@ from RepSys.rpmutil import switch HELP = """\ Usage: repsys switch [URL] -Relocates the working copy to the base location URL. If URL is not -provided, it will use the option default_parent from repsys.conf as -default, or, if the current working copy is already based in +Relocates the working copy to the base location URL. + +If URL is not provided, it will use the option default_parent from +repsys.conf as default, or, if the current working copy is already based in default_parent, it will use the location from the mirror option from repsys.conf. diff --git a/repsys b/repsys index a243493..9896404 100755 --- a/repsys +++ b/repsys @@ -9,24 +9,25 @@ VERSION="1.6.19" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] +Tool to access and manage a package repository structure. + +http://wiki.mandriva.com/en/Development/Packaging/RepositorySystem/Quickstart + Useful commands: - co - ci - sync - submit - create - getspec - getsrpm - rpmlog - changed - authoremail - putsrpm - switch + co checkout a package + ci commit changes + sync add-remove all file changes from the .spec + submit submit a package for build + getspec prints the spec + rpmlog prints the RPM changelog + getsrpm creates the source RPM + create create the structure of a new package + changed shows changes not submitted + authoremail prints the e-mail of a given author + switch relocate to mirror or upstream repository Run "repsys COMMAND --help" for more information. -Run "repsys --help-plugins" for help on loaded plugins. - Written by Gustavo Niemeyer """ diff --git a/repsys.conf b/repsys.conf index 43dd99b..2b119c3 100644 --- a/repsys.conf +++ b/repsys.conf @@ -1,20 +1,10 @@ [global] -verbose = no default_parent = svn+ssh://svn.mandriva.com/svn/packages/cooker -url-map = svn\+ssh://svn\.mandriva\.com/(.*) file:///\1 +## uncomment it in case you don't have a account in the Mandriva cluster: #mirror = http://svn.mandriva.com/svn/packages/cooker/ -#tempdir = /tmp [log] oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc -# controls up to which revision the rpm changelog -# will be constructed (default zero, i.e., oldest -# commit) -revision-offset = 0 -# commit lines containing this string won't be shown in the changelog: -ignore-string = SILENT -# and in case of only allowing a few lines to be visible, use this: -#unignore-string = CLOG [template] path = /usr/share/repsys/default.chlog @@ -23,32 +13,6 @@ path = /usr/share/repsys/default.chlog create-srpm = /usr/share/repsys/create-srpm upload-srpm = /usr/local/bin/youri.devel -[users] -# jsmith = John Smith - [submit] host = kenobi.mandriva.com default = Cooker - -[submit Cooker] -target = /export/home/repsys -allowed = svn+ssh://svn.mandriva.com/svn/packages/cooker -scripts = /usr/share/repsys/rebrand-mdk -## -## rpm-macros refers to the sections containing the macros used for this -## target. The values will be used to build the rpmbuild command line. For -## example: -## -## [macros cooker] -## a = b -## c = %a -## -## will render in the command line: --define "a b" --define "c %a". -## -#rpm-macros = global cooker - -#[macros global] -#distsuffix = mdv - -#[macros cooker] -#mandriva_release = 2007.1 -- cgit v1.2.1 From 49898e3e1977b32f26e8045aafb5e24afdccb167 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:52:24 +0000 Subject: Changed get_submit_info to use svn.info2 and properly handle non-versioned files --- RepSys/rpmutil.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 7481b72..45c9758 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -511,9 +511,13 @@ def get_submit_info(path): files = [] files.extend(glob.glob("%s/*" % specsdir)) files.extend(glob.glob("%s/*" % sourcesdir)) - for line in svn.info(" ".join(files)): - if line.startswith("Last Changed Rev: "): - rev = int(line.split(":")[1]) + for file in files: + info = svn.info2(file) + if info is None: + continue + rawrev = info.get("Last Changed Rev") + if rawrev: + rev = int(rawrev) if rev > max: max = rev if max == -1: -- cgit v1.2.1 From fb388c2b7d01c98b0456ce97cf163f5394710b10 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:53:09 +0000 Subject: Added --strict option to getsrpm + equivalent configuration option This option makes repsys to fail if the revision provided by the user does not contain any changed path inside the package URL. This should prevent mistakes such as submitting update packages using the Cooker URL. --- CHANGES | 4 ++++ RepSys/commands/getsrpm.py | 25 ++++++++++++++----------- RepSys/rpmutil.py | 25 ++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index d1db357..bad90d2 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,10 @@ - if REPSYS_CONF is set, /etc/repsys.conf and ~/.repsys/config will not be readed anymore - added option -F to repsys ci to set a log message file +- added option --strict to getsrpm to check if the revision provided + matches the package URL; +- added boolean configuration option strict-revision in the submit + section, to allow forcing the use of --strict - the fix for the unreleased commits problem in the previous release was wrong, really fixed it - fixed the use of file:/// URLs when using just the package name diff --git a/RepSys/commands/getsrpm.py b/RepSys/commands/getsrpm.py index f1ebfe1..f9a63d2 100644 --- a/RepSys/commands/getsrpm.py +++ b/RepSys/commands/getsrpm.py @@ -19,17 +19,18 @@ Usage: repsys getsrpm [OPTIONS] REPPKGURL Generates the source RPM (.srpm) file of a given package. Options: - -c Use files in current/ directory (default) - -p Use files in pristine/ directory - -v VER Use files from the version specified by VER (e.g. 2.2.1-2cl) - -r REV Use files from current directory, in revision REV (e.g. 1001) - -t DIR Put SRPM file in directory DIR when done (default is ".") - -P USER Define the RPM packager inforamtion to USER - -s FILE Run script with "FILE TOPDIR SPECFILE" command - -n Rename the package to include the revision number - -l Use subversion log to build rpm %changelog - -T FILE Template to be used to generate the %changelog - -h Show this message + -c Use files in current/ directory (default) + -p Use files in pristine/ directory + -v VER Use files from the version specified by VER (e.g. 2.2.1-2cl) + -r REV Use files from current directory, in revision REV (e.g. 1001) + -t DIR Put SRPM file in directory DIR when done (default is ".") + -P USER Define the RPM packager inforamtion to USER + -s FILE Run script with "FILE TOPDIR SPECFILE" command + -n Rename the package to include the revision number + -l Use subversion log to build rpm %changelog + -T FILE Template to be used to generate the %changelog + -h Show this message + --strict Check if the given revision contains changes in REPPKGURL Examples: repsys getsrpm python @@ -73,6 +74,8 @@ def parse_options(): parser.add_option("-n", dest="revname", action="store_true") parser.add_option("-l", dest="svnlog", action="store_true") parser.add_option("-T", dest="template", type="string", default=None) + parser.add_option("--strict", dest="strict", default=False, + action="store_true") opts, args = parser.parse_args() del opts.__ignore if len(args) != 1: diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 45c9758..6fae669 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -33,6 +33,22 @@ def rpm_macros_defs(macros): args = " ".join(defs) return args +def rev_touched_url(url, rev): + svn = SVN() + info = svn.info2(url) + if info is None: + raise Error, "can't fetch svn info about the URL: %s" % url + root = info["Repository Root"] + urlpath = url[len(root):] + touched = False + entries = svn.log(root, start=rev, limit=1) + entry = entries[0] + for change in entry.changed: + path = change.get("path") + if path and path.startswith(urlpath): + touched = True + return touched + def get_srpm(pkgdirurl, mode = "current", targetdirs = None, @@ -46,7 +62,8 @@ def get_srpm(pkgdirurl, submit = False, template = None, macros = [], - verbose = 0): + verbose = 0, + strict = False): svn = SVN() tmpdir = tempfile.mktemp() topdir = "--define '_topdir %s'" % tmpdir @@ -66,6 +83,12 @@ def get_srpm(pkgdirurl, geturl = os.path.join(pkgdirurl, "current") 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) svn.export(geturl, tmpdir, rev=revision) srpmsdir = os.path.join(tmpdir, "SRPMS") os.mkdir(srpmsdir) -- cgit v1.2.1 From 3f8b8f70d7d81c956e0f4e3dbc66d97e91d4e55b Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:54:35 +0000 Subject: Moved all old defaults to repsys-example.conf and document it better Only a few configuration options in repsys.conf are really useful. Removed the remaining [template] section. --- CHANGES | 2 ++ repsys-example.conf | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ repsys.conf | 3 --- setup.py | 3 ++- 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 repsys-example.conf diff --git a/CHANGES b/CHANGES index bad90d2..223528c 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,8 @@ section, to allow forcing the use of --strict - the fix for the unreleased commits problem in the previous release was wrong, really fixed it +- moved all configuration options that will hardly be changed to + repsys-example.conf; we now have a shorter repsys.conf - fixed the use of file:/// URLs when using just the package name - don't give the wrong message "invalid command 'CMD'" when this is not the case diff --git a/repsys-example.conf b/repsys-example.conf new file mode 100644 index 0000000..99c5d30 --- /dev/null +++ b/repsys-example.conf @@ -0,0 +1,62 @@ +[global] +verbose = no +default_parent = svn+ssh://svn.mandriva.com/svn/packages/cooker +url-map = svn\+ssh://svn\.mandriva\.com/(.*) file:///\1 +#tempdir = /tmp + +[log] +oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc +# controls up to which revision the rpm changelog +# will be constructed (default zero, i.e., oldest +# commit) +revision-offset = 0 +# commit lines containing this string won't be shown in the changelog: +ignore-string = SILENT +# and in case of only allowing a few lines to be visible, use this: +#unignore-string = CLOG + +[template] +# set the cheetah template used to generate the spec changelog from svn +path = /usr/share/repsys/default.chlog + +[helper] +# create-srpm is called by repsys on the server-side when submitting a +# package +create-srpm = /usr/share/repsys/create-srpm +# upload-srpm is called by create-srpm to copy the generated .src.rpm to +# the proper build queue +upload-srpm = /usr/local/bin/youri.devel + +# this section maps usernames found in svn commits to the ones that must be +# shown in the changelog +# users can be retrieved from LDAP through the use of the repsys-ldap +# plugin +[users] +# jsmith = John Smith + +[submit] +host = kenobi.mandriva.com +default = Cooker + +[submit Cooker] +target = /export/home/repsys +allowed = svn+ssh://svn.mandriva.com/svn/packages/cooker +scripts = /usr/share/repsys/rebrand-mdk +## +## rpm-macros refers to the sections containing the macros used for this +## target. The values will be used to build the rpmbuild command line. For +## example: +## +## [macros cooker] +## a = b +## c = %a +## +## will render in the command line: --define "a b" --define "c %a". +## +#rpm-macros = global cooker + +#[macros global] +#distsuffix = mdv + +#[macros cooker] +#mandriva_release = 2007.1 diff --git a/repsys.conf b/repsys.conf index 2b119c3..0d1ddc5 100644 --- a/repsys.conf +++ b/repsys.conf @@ -6,9 +6,6 @@ default_parent = svn+ssh://svn.mandriva.com/svn/packages/cooker [log] oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc -[template] -path = /usr/share/repsys/default.chlog - [helper] create-srpm = /usr/share/repsys/create-srpm upload-srpm = /usr/local/bin/youri.devel diff --git a/setup.py b/setup.py index 7c4814c..2df6e49 100755 --- a/setup.py +++ b/setup.py @@ -28,7 +28,8 @@ setup(name="repsys", "oldfashion.chlog", "compatv15.chlog", "create-srpm", - "rebrand-mdk"]), + "rebrand-mdk", + "repsys-example.conf"]), ("/etc/", ["repsys.conf"])] ) -- cgit v1.2.1 From 57c80e59a9f3b38c4c1dc00fd3e8001b5e2b4283 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:56:25 +0000 Subject: Allow listing targets through SSH submit host It required to add a option --list on create-srpm and change repsys submit to use this option. --- CHANGES | 2 ++ RepSys/commands/submit.py | 12 +++++++++++- create-srpm | 12 ++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 223528c..fa7889a 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,8 @@ matches the package URL; - added boolean configuration option strict-revision in the submit section, to allow forcing the use of --strict +- added option --list in create-srpm to list the available targets +- make submit -l work on svn+ssh:// targets - the fix for the unreleased commits problem in the previous release was wrong, really fixed it - moved all configuration options that will hardly be changed to diff --git a/RepSys/commands/submit.py b/RepSys/commands/submit.py index bd6e01c..f1726dc 100644 --- a/RepSys/commands/submit.py +++ b/RepSys/commands/submit.py @@ -55,7 +55,7 @@ def parse_options(): parser = OptionParser(help=HELP) parser.defaults["revision"] = "" parser.add_option("-t", dest="target", default="Cooker") - parser.add_option("-l", dest="list", action="store_true") + 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) @@ -77,6 +77,16 @@ def parse_options(): raise Error, "provide -l or a revision number" return opts +def list_targets(option, opt, val, parser): + host = config.get("submit", "host") + if host is None: + raise Error, "no submit host defined in repsys.conf" + createsrpm = get_helper("create-srpm") + #TODO make it configurable + command = "ssh %s %s --list" % (host, createsrpm) + execcmd(command, show=True) + sys.exit(0) + def submit(pkgdirurl, revision, target, list=0, define=[], submithost=None): #if not NINZ: # raise Error, "you must have NINZ installed to use this command" diff --git a/create-srpm b/create-srpm index 3dab068..0c51e97 100755 --- a/create-srpm +++ b/create-srpm @@ -89,8 +89,11 @@ def parse_options(): dest="urlmap", default=False, help="disable url mapping") parser.add_option("--define", action="append") + parser.add_option("--list", dest="list_targets", default=False, + action="store_true", + help="list submit targets available") opts, args = parser.parse_args() - if not args: + if not opts.list_targets and not args: parser.error("you must supply a package url") return opts, args @@ -100,7 +103,12 @@ def main(): iface = CmdIface() opts, args = parse_options() try: - iface.submit_package(args[0], opts.revision, opts.target, opts.urlmap, opts.define) + if opts.list_targets: + for target in iface.submit_targets(): + print target + else: + iface.submit_package(args[0], opts.revision, opts.target, + opts.urlmap, opts.define) except Error, e: sys.stderr.write("error: %s\n" % str(e)) sys.exit(1) -- cgit v1.2.1 From 970849f41b0370f1b225d53ee39a8fd3ed07eab3 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:57:03 +0000 Subject: Don't use --non-interactive with the commands "add", "revert" and "cleanup" --- RepSys/svn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RepSys/svn.py b/RepSys/svn.py index 4b1e9da..7459033 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -19,7 +19,8 @@ class SVNLogEntry: class SVN: def _execsvn(self, *args, **kwargs): - if not kwargs.get("show"): + localcmds = ("add", "revert", "cleanup") + if not kwargs.get("show") and args[0] not in localcmds: args = list(args) args.append("--non-interactive") svn_command = config.get("global", "svn-command", -- cgit v1.2.1 From 66fb7a96a4101acc06de59492ab74f00e5c85210 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 20:57:42 +0000 Subject: Fixed mistake in svn error message handling --- RepSys/svn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RepSys/svn.py b/RepSys/svn.py index 7459033..985329d 100644 --- a/RepSys/svn.py +++ b/RepSys/svn.py @@ -34,7 +34,7 @@ class SVN: "Seems ssh-agent or ForwardAgent are not setup, see " "http://wiki.mandriva.com/en/Development/Docs/Contributor_Tricks#SSH_configuration" " for more information." % e) - elif "authorization failed": + elif "authorization failed" in e.message: raise Error, ("%s\n" "Note that repsys does not support any HTTP " "authenticated access." % e) -- cgit v1.2.1 From ffdaa7d17062bf450a040b34056aaf0e096a9599 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Tue, 5 Feb 2008 21:06:50 +0000 Subject: Set the default template path and update the built-in one to match default.chlog --- CHANGES | 1 + RepSys/log.py | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index fa7889a..5a57363 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ - make 'repsys submit' without package name or revision number work again - if REPSYS_CONF is set, /etc/repsys.conf and ~/.repsys/config will not be readed anymore +- changed the built-in template to the current default.chlog - added option -F to repsys ci to set a log message file - added option --strict to getsrpm to check if the revision provided matches the package URL; diff --git a/RepSys/log.py b/RepSys/log.py index df7bc9f..68cbbc0 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -23,17 +23,27 @@ locale.setlocale(locale.LC_ALL, "C") default_template = """ #for $rel in $releases_by_author * $rel.date $rel.author_name <$rel.author_email> $rel.version-$rel.release - ## - #if not $rel.released - (not released yet) ++ Revision: $rel.revision +## #if not $rel.released +##+ Status: not released +## #end if + #if not $rel.visible ++ rebuild (emptylog) #end if #for $rev in $rel.release_revisions #for $line in $rev.lines - $line +$line #end for #end for #for $author in $rel.authors + #if $author.revisions and not $author.revisions[0].lines + #continue + #end if + ##alternatively, one could use: + ###if $author.email == "root" + ## #continue + ###end if + $author.name <$author.email> #for $rev in $author.revisions #for $line in $rev.lines @@ -298,7 +308,8 @@ def make_release(author=None, revision=None, date=None, lines=None, def dump_file(releases, currentlog=None, template=None): - templpath = template or config.get("template", "path", None) + templpath = template or config.get("template", "path", + "/usr/share/repsys/default.chlog") params = {} if templpath is None or not os.path.exists(templpath): params["source"] = default_template -- cgit v1.2.1 From 05810ef9f0e1dc761317f909146f1a201c876a64 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 6 Feb 2008 01:34:08 +0000 Subject: Fixed URL normalization to make it compatible with py2.4 In py2.4 the function urlparse doesn't return a "named" tuple. --- CHANGES | 1 + RepSys/mirror.py | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 5a57363..cfed07f 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ to replace the default svn command - force svn+ssh:// URLs to be in BatchMode, in order to not have any interactivity at all with ssh +- fixed incompatibility with Python-2.4 on urlparse - fixed bad url used when using -v in getsrpm - make 'repsys submit' without package name or revision number work again - if REPSYS_CONF is set, /etc/repsys.conf and ~/.repsys/config will not be diff --git a/RepSys/mirror.py b/RepSys/mirror.py index 4fb40ce..5b114df 100644 --- a/RepSys/mirror.py +++ b/RepSys/mirror.py @@ -7,16 +7,16 @@ from RepSys.svn import SVN def _normdirurl(url): """normalize url for relocate_path needs""" parsed = urlparse.urlparse(url) - path = os.path.normpath(parsed.path) - newurl = urlparse.urlunparse((parsed.scheme, parsed.netloc, path, - parsed.params, parsed.query, parsed.fragment)) + path = os.path.normpath(parsed[2]) + newurl = urlparse.urlunparse((parsed[0], parsed[1], path, + parsed[3], parsed[4], parsed[5])) return newurl def _joinurl(url, relpath): parsed = urlparse.urlparse(url) - newpath = os.path.join(parsed.path, relpath) - newurl = urlparse.urlunparse((parsed.scheme, parsed.netloc, newpath, - parsed.params, parsed.query, parsed.fragment)) + newpath = os.path.join(parsed[2], relpath) + newurl = urlparse.urlunparse((parsed[0], parsed[1], newpath, + parsed[3], parsed[4], parsed[5])) return newurl def same_base(parent, url): -- cgit v1.2.1 From 11c6a91f79529e1e6ab029f81f8b1582fff74842 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 6 Feb 2008 01:39:28 +0000 Subject: Fixed emptylog to be shown when necessary As emptylog started working again another problem arose: the first release in most of the packages is SILENTed and result in a emptlog entry. The problem is that the log gathered from misc/ already contains (in most of the cases, at least) the version-release with the right message. --- CHANGES | 2 ++ RepSys/log.py | 53 ++++++++++++++++++++++++++++++----------------------- default.chlog | 6 ++++++ 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index cfed07f..c605e5e 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,8 @@ - force svn+ssh:// URLs to be in BatchMode, in order to not have any interactivity at all with ssh - fixed incompatibility with Python-2.4 on urlparse +- fixed emptylog message, which was not being shown when needed +- template: hide the first release when it has only invisible lines - fixed bad url used when using -v in getsrpm - make 'repsys submit' without package name or revision number work again - if REPSYS_CONF is set, /etc/repsys.conf and ~/.repsys/config will not be diff --git a/RepSys/log.py b/RepSys/log.py index 68cbbc0..60cf0d5 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -21,6 +21,12 @@ import shutil locale.setlocale(locale.LC_ALL, "C") default_template = """ +#if not $releases_by_author[-1].visible + ## Hide the first release that contains no changes. It must be a + ## reimported package and the log gathered from misc/ already should + ## contain a correct entry for the version-release: + #set $releases_by_author = $releases_by_author[:-1] +#end if #for $rel in $releases_by_author * $rel.date $rel.author_name <$rel.author_email> $rel.version-$rel.release + Revision: $rel.revision @@ -174,49 +180,50 @@ def group_releases_by_author(releases): allauthors = [] grouped = [] for release in releases: + + # group revisions of the release by author authors = {} latest = None for revision in release.revisions: authors.setdefault(revision.author, []).append(revision) - # all the mess below is to sort by author and by revision number + # create _Authors and sort them by their latest revisions decorated = [] for authorname, revs in authors.iteritems(): author = _Author() author.name = revs[0].author_name author.email = revs[0].author_email - revdeco = [(r.revision, r) for r in revs] - revdeco.sort(reverse=1) - author.revisions = [t[1] for t in revdeco] + author.revisions = revs revlatest = author.revisions[0] - # keep the latest revision even for silented authors (below) + # keep the latest revision even for completely invisible + # authors (below) if latest is None or revlatest.revision > latest.revision: latest = revlatest count = sum(len(rev.lines) for rev in author.revisions) if count == 0: - # skipping author with only silented lines + # only sort those visible authors, invisible ones are used + # only in "latest" continue - decorated.append((revdeco[0][0], author)) + decorated.append((revlatest.revision, author)) + decorated.sort(reverse=1) - if not decorated: - # skipping release with only authors with silented lines - continue + if release.visible: + release.authors = [t[1] for t in decorated] + firstrel, release.authors = release.authors[0], release.authors[1:] + release.author_name = firstrel.name + release.author_email = firstrel.email + release.release_revisions = firstrel.revisions + else: + # we don't care about other possible authors in completely + # invisible releases + firstrev = release.revisions[0] + release.author_name = firstrev.author_name + release.author_email = firstrev.author_email + release.raw_date = firstrev.raw_date + release.date = firstrev.date - decorated.sort(reverse=1) - release.authors = [t[1] for t in decorated] - # the difference between a released and a not released _Release is - # the way the release numbers is obtained. So, when this is a - # released, we already have it, but if we don't, we should get de - # version/release string using getrelease and then get the first - first, release.authors = release.authors[0], release.authors[1:] - release.author_name = first.name - release.author_email = first.email - release.release_revisions = first.revisions - - #release.date = first.revisions[0].date release.date = latest.date release.raw_date = latest.raw_date - #release.revision = first.revisions[0].revision release.revision = latest.revision grouped.append(release) diff --git a/default.chlog b/default.chlog index aff3958..93dcd1b 100644 --- a/default.chlog +++ b/default.chlog @@ -1,5 +1,11 @@ ## Sample Changelog template ## +#if not $releases_by_author[-1].visible + ## Hide the first release that contains no changes. It must be a + ## reimported package and the log gathered from misc/ already should + ## contain a correct entry for the version-release: + #set $releases_by_author = $releases_by_author[:-1] +#end if #for $rel in $releases_by_author * $rel.date $rel.author_name <$rel.author_email> $rel.version-$rel.release + Revision: $rel.revision -- cgit v1.2.1 From 778123f5695848b2830f61b0564cd6a192db68df Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Wed, 6 Feb 2008 01:51:18 +0000 Subject: Don't install repsys-example.conf in datadir, move it to MANIFEST.in --- MANIFEST.in | 1 + setup.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index c8b18b2..f014036 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,5 +3,6 @@ include RepSys/plugins/*.txt include repsys repsys.conf MANIFEST.in include CHANGES include README.LDAP +include repsys-example.conf include *.chlog include rebrand-mdk create-srpm getsrpm-mdk diff --git a/setup.py b/setup.py index 2df6e49..7c4814c 100755 --- a/setup.py +++ b/setup.py @@ -28,8 +28,7 @@ setup(name="repsys", "oldfashion.chlog", "compatv15.chlog", "create-srpm", - "rebrand-mdk", - "repsys-example.conf"]), + "rebrand-mdk"]), ("/etc/", ["repsys.conf"])] ) -- cgit v1.2.1 From 5eb9f215eca3378738cddce68ce0977c6069357c Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 8 Feb 2008 00:42:19 +0000 Subject: New version 1.6.20 --- repsys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repsys b/repsys index 9896404..67bb180 100755 --- a/repsys +++ b/repsys @@ -4,7 +4,7 @@ from RepSys.command import * import getopt import sys -VERSION="1.6.19" +VERSION="1.6.20" HELP = """\ Usage: repsys COMMAND [COMMAND ARGUMENTS] -- cgit v1.2.1 From 1e929f67375b699cdcac0b1557d115eed7035ae8 Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Fri, 8 Feb 2008 00:43:26 +0000 Subject: Added option -d to sync, to download the missing files It also added a configuration option download-command, in the [global] section to define which command will be used to download. The default is wget. --- CHANGES | 1 + RepSys/commands/sync.py | 4 ++++ RepSys/rpmutil.py | 31 ++++++++++++++++++++++++------- repsys-example.conf | 3 +++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index c605e5e..43bb51d 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ - if REPSYS_CONF is set, /etc/repsys.conf and ~/.repsys/config will not be readed anymore - changed the built-in template to the current default.chlog +- added option -d to repsys sync, to download the missing source files - added option -F to repsys ci to set a log message file - added option --strict to getsrpm to check if the revision provided matches the package URL; diff --git a/RepSys/commands/sync.py b/RepSys/commands/sync.py index 42ede8d..a51db22 100644 --- a/RepSys/commands/sync.py +++ b/RepSys/commands/sync.py @@ -12,6 +12,8 @@ from the spec file. Options: --dry-run Print results without changing the working copy + --download -d + Try to download the source files not found -h Show this message Examples: @@ -22,6 +24,8 @@ def parse_options(): parser = OptionParser(help=HELP) parser.add_option("--dry-run", dest="dryrun", default=False, action="store_true") + parser.add_option("-d", "--download", dest="download", default=False, + action="store_true") opts, args = parser.parse_args() if len(args): opts.target = args[0] diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py index 6fae669..3bb1b50 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -9,6 +9,7 @@ from RepSys.command import default_parent import rpm import tempfile import shutil +import string import glob import sys import os @@ -409,7 +410,7 @@ def _getpkgtopdir(basedir=None): topdir = "" return topdir -def sync(dryrun=False): +def sync(dryrun=False, download=False): svn = SVN() topdir = _getpkgtopdir() # run svn info because svn st does not complain when topdir is not an @@ -429,18 +430,34 @@ def sync(dryrun=False): spec = rpm.TransactionSet().parseSpec(specpath) except rpm.error, e: raise Error, "could not load spec file: %s" % e - sources = [os.path.basename(name) - for name, no, flags in spec.sources()] - sourcesst = dict((os.path.basename(path), st) + sources = dict((os.path.basename(name), name) + for name, no, flags in spec.sources()) + sourcesst = dict((os.path.basename(path), (path, st)) for st, path in svn.status(sourcesdir, noignore=True)) toadd = [] - for source in sources: + for source, url in sources.iteritems(): sourcepath = os.path.join(sourcesdir, source) - if sourcesst.get(source): + pst = sourcesst.get(source) + if pst: if os.path.isfile(sourcepath): toadd.append(sourcepath) else: - sys.stderr.write("warning: %s not found\n" % sourcepath) + sys.stderr.write("warning: %s not found, skipping\n" % sourcepath) + elif download and not os.path.isfile(sourcepath): + print "%s not found, downloading from %s" % (sourcepath, url) + fmt = config.get("global", "download-command", + "wget -c -O '$dest' $url") + context = {"dest": sourcepath, "url": url} + try: + cmd = string.Template(fmt).substitute(context) + except KeyError, e: + raise Error, "invalid variable %r in download-command "\ + "configuration option" % e + execcmd(cmd, show=True) + if os.path.isfile(sourcepath): + toadd.append(sourcepath) + else: + raise Error, "file not found: %s" % sourcepath # rm entries not found in sources and still in svn found = os.listdir(sourcesdir) toremove = [] diff --git a/repsys-example.conf b/repsys-example.conf index 99c5d30..99c44f5 100644 --- a/repsys-example.conf +++ b/repsys-example.conf @@ -3,6 +3,9 @@ verbose = no default_parent = svn+ssh://svn.mandriva.com/svn/packages/cooker url-map = svn\+ssh://svn\.mandriva\.com/(.*) file:///\1 #tempdir = /tmp +## the command used to download files when using repsys sync -d +#download-command = wget -c -O '$dest' $url + [log] oldurl = svn+ssh://svn.mandriva.com/svn/packages/misc -- cgit v1.2.1