aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBogdano Arendartchuk <bogdano@mandriva.org>2007-06-06 20:41:50 +0000
committerBogdano Arendartchuk <bogdano@mandriva.org>2007-06-06 20:41:50 +0000
commitd84ac920943e07b4dd78b8ee446f23de6859a1fe (patch)
tree9891d421b977e84894b38ea76ebba8ea8148ce14
parentb2ce8ef1c40f7c58f4bb4629b5b5e95ce8c252d2 (diff)
downloadmgarepo-d84ac920943e07b4dd78b8ee446f23de6859a1fe.tar
mgarepo-d84ac920943e07b4dd78b8ee446f23de6859a1fe.tar.gz
mgarepo-d84ac920943e07b4dd78b8ee446f23de6859a1fe.tar.bz2
mgarepo-d84ac920943e07b4dd78b8ee446f23de6859a1fe.tar.xz
mgarepo-d84ac920943e07b4dd78b8ee446f23de6859a1fe.zip
Frontported fixes in mirror support from repsys-1.6
- fixed bad URLs being used when checking out from mirrors - "switch" subcommand to ease switching between mirror and real repositories - smarter "ci"
-rw-r--r--RepSys/commands/switch.py32
-rw-r--r--RepSys/mirror.py80
-rw-r--r--RepSys/rpmutil.py31
-rw-r--r--RepSys/svn.py13
-rwxr-xr-xrepsys1
5 files changed, 144 insertions, 13 deletions
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..7a0bc4e 100644
--- a/RepSys/mirror.py
+++ b/RepSys/mirror.py
@@ -4,21 +4,51 @@ 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)
+ svn = SVN()
newurl = relocate_path(oldparent, newparent, url)
- svn.switch(newurl, url, path=wcpath, relocate="True")
+ svn.relocate(url, newurl, wcpath)
return newurl
def switchto_parent(svn, url, path):
@@ -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 39e78fc..40aa4fe 100644
--- a/RepSys/rpmutil.py
+++ b/RepSys/rpmutil.py
@@ -369,17 +369,23 @@ def checkout(pkgdirurl, path=None, revision=None):
print "checking out from mirror", current
svn.checkout(current, path, revision=SVN.makerev(revision), show=1)
-def sync(dryrun=False):
- svn = SVN()
+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 = ""
+ topdir = "."
+ return topdir
+
+def sync(dryrun=False):
+ svn = SVN()
+ topdir = _getpkgtopdir()
# run svn info because svn st does not complain when topdir is not an
# working copy
- svn.info(topdir or ".")
+ svn.info(topdir)
specsdir = os.path.join(topdir, "SPECS/")
sourcesdir = os.path.join(topdir, "SOURCES/")
for path in (specsdir, sourcesdir):
@@ -426,11 +432,16 @@ def sync(dryrun=False):
def commit(target=".", message=None):
svn = SVN()
+ status = svn.status(target, silent=True)
+ if not status:
+ print "nothing to commit"
+ return
info = svn.info(target)
url = info.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:
@@ -440,10 +451,18 @@ 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()
+ topdir = _getpkgtopdir()
+ info = svn.info(topdir)
+ wcurl = info.url
+ 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 2fe9ad1..575651f 100644
--- a/RepSys/svn.py
+++ b/RepSys/svn.py
@@ -157,6 +157,19 @@ class SVN:
def exists(self, path):
return self.ls(path, noerror=1) is not None
+ def status(self, *args, **kwargs):
+ # add one keywork "silent" that workaround the strange behavior of
+ # pysvn's get_all, which seems to be broken, this way we also have
+ # the same interface of svn.py from repsys 1.6.x
+ meth = self._cllient_wrap("status")
+ silent = kwargs.pop("silent", None)
+ st = meth(*args, **kwargs)
+ if silent:
+ unversioned = pysvn.wc_status_kind.unversioned
+ st = [entry for entry in st
+ if entry.text_status is not unversioned]
+ return st
+
def diff(self, *args, **kwargs):
head = pysvn.Revision(pysvn.opt_revision_kind.head)
revision1 = kwargs.pop("revision1", head)
diff --git a/repsys b/repsys
index 804ad05..c68df11 100755
--- a/repsys
+++ b/repsys
@@ -24,6 +24,7 @@ Useful commands:
changed
authoremail
putsrpm
+ switch
Run "repsys COMMAND --help" for more information.