From 5c7f585c08c8ffb944095ae031fbf82a54ba13bc Mon Sep 17 00:00:00 2001 From: Bogdano Arendartchuk Date: Thu, 17 Jul 2008 12:24:21 +0000 Subject: Allow specifying distro branches without using complete URLs Added the configuration option "repository", which will have the URL to the root of the repository. The change also allowed using mirrors in all the read-only commands. --- RepSys/__init__.py | 16 ---- RepSys/commands/changed.py | 4 +- RepSys/commands/co.py | 14 ++- RepSys/commands/create.py | 3 +- RepSys/commands/editlog.py | 3 +- RepSys/commands/getspec.py | 4 +- RepSys/commands/getsrpm.py | 4 +- RepSys/commands/markrelease.py | 3 +- RepSys/commands/patchspec.py | 3 +- RepSys/commands/putsrpm.py | 3 +- RepSys/commands/rpmlog.py | 10 +- RepSys/commands/submit.py | 14 ++- RepSys/layout.py | 207 +++++++++++++++++++++++++++++++++++++++++ RepSys/log.py | 8 +- RepSys/mirror.py | 81 +++++++++------- RepSys/rpmutil.py | 97 ++++++------------- 16 files changed, 330 insertions(+), 144 deletions(-) create mode 100644 RepSys/layout.py (limited to 'RepSys') diff --git a/RepSys/__init__.py b/RepSys/__init__.py index b303065..2759e8f 100644 --- a/RepSys/__init__.py +++ b/RepSys/__init__.py @@ -11,20 +11,4 @@ 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/commands/changed.py b/RepSys/commands/changed.py index 62b20b6..7d05604 100644 --- a/RepSys/commands/changed.py +++ b/RepSys/commands/changed.py @@ -1,6 +1,7 @@ #!/usr/bin/python from RepSys import Error from RepSys.command import * +from RepSys.layout import package_url from RepSys.rpmutil import check_changed import getopt import sys @@ -13,6 +14,7 @@ Shows if there are pending changes since the last package release. Options: -a Check all packages in given URL -s Show differences + -M Do not use the mirror (use the main repository) -h Show this message Examples: @@ -27,7 +29,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) != 1: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = package_url(args[0]) opts.verbose = 1 # Unconfigurable return opts diff --git a/RepSys/commands/co.py b/RepSys/commands/co.py index 830b7e7..5349049 100644 --- a/RepSys/commands/co.py +++ b/RepSys/commands/co.py @@ -13,13 +13,19 @@ Checkout the package source from the Mandriva repository. If the 'mirror' option is enabled, the package is obtained from the mirror repository. +You can specify the distro branch to checkout from by using distro/pkgname. + Options: + -d The distribution branch to checkout from + -b The package branch -r REV Revision to checkout - -o Do not use the mirror (use official server) + -M Do not use the mirror (use the main repository) -h Show this message Examples: repsys co pkgname + repsys co -d 2009.0 pkgname + repsys co 2009.0/pkgame repsys co http://repos/svn/cnc/snapshot/foo repsys co http://repos/svn/cnc/snapshot/foo foo-pkg """ @@ -27,11 +33,13 @@ 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") + parser.add_option("--distribution", "-d", dest="distro", default=None) + parser.add_option("--branch", "-b", dest="branch", default=None) opts, args = parser.parse_args() if len(args) not in (1, 2): raise Error, "invalid arguments" + # here we don't use package_url in order to notify the user we are + # using the mirror opts.pkgdirurl = args[0] if len(args) == 2: opts.path = args[1] diff --git a/RepSys/commands/create.py b/RepSys/commands/create.py index a8709f0..ded8abe 100644 --- a/RepSys/commands/create.py +++ b/RepSys/commands/create.py @@ -1,6 +1,7 @@ #!/usr/bin/python from RepSys import Error from RepSys.command import * +from RepSys.layout import package_url from RepSys.rpmutil import create_package import getopt import sys @@ -23,7 +24,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) != 1: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = package_url(args[0], mirrored=False) opts.verbose = 1 # Unconfigurable return opts diff --git a/RepSys/commands/editlog.py b/RepSys/commands/editlog.py index 1962ed8..9d1afc5 100644 --- a/RepSys/commands/editlog.py +++ b/RepSys/commands/editlog.py @@ -1,6 +1,7 @@ #!/usr/bin/python from RepSys import Error from RepSys.command import * +from RepSys.layout import package_url from RepSys.svn import SVN import re @@ -24,7 +25,7 @@ def parse_options(): pkgdirurl, revision = "", args[0] else: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(pkgdirurl) + opts.pkgdirurl = package_url(pkgdirurl, mirrored=False) opts.revision = re.compile(r".*?(\d+).*").sub(r"\1", revision) return opts diff --git a/RepSys/commands/getspec.py b/RepSys/commands/getspec.py index 5e44074..6a8f7ea 100644 --- a/RepSys/commands/getspec.py +++ b/RepSys/commands/getspec.py @@ -1,6 +1,7 @@ #!/usr/bin/python from RepSys import Error from RepSys.command import * +from RepSys.layout import package_url from RepSys.rpmutil import get_spec import getopt import sys @@ -12,6 +13,7 @@ Prints the .spec file of a given package. Options: -t DIR Use DIR as target for spec file (default is ".") + -M Do not use the mirror (use the main repository) -h Show this message Examples: @@ -25,7 +27,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) != 1: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = package_url(args[0]) return opts def main(): diff --git a/RepSys/commands/getsrpm.py b/RepSys/commands/getsrpm.py index f9a63d2..8cbe1f1 100644 --- a/RepSys/commands/getsrpm.py +++ b/RepSys/commands/getsrpm.py @@ -5,6 +5,7 @@ # from RepSys import Error, config from RepSys.command import * +from RepSys.layout import package_url from RepSys.rpmutil import get_srpm import tempfile import shutil @@ -29,6 +30,7 @@ Options: -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 + -M Do not use the mirror (use the main repository) -h Show this message --strict Check if the given revision contains changes in REPPKGURL @@ -80,7 +82,7 @@ def parse_options(): del opts.__ignore if len(args) != 1: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = package_url(args[0]) opts.verbose = 1 return opts diff --git a/RepSys/commands/markrelease.py b/RepSys/commands/markrelease.py index 1707f39..057cf1d 100644 --- a/RepSys/commands/markrelease.py +++ b/RepSys/commands/markrelease.py @@ -9,6 +9,7 @@ # from RepSys import Error from RepSys.command import * +from RepSys.layout import package_url from RepSys.simplerpm import SRPM from RepSys.rpmutil import mark_release from RepSys.util import get_auth @@ -60,7 +61,7 @@ def parse_options(): if len(args) != 1: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = package_url(args[0], mirrored=False) filename = opts.filename appendname = opts.appendname diff --git a/RepSys/commands/patchspec.py b/RepSys/commands/patchspec.py index 8330cc3..9a4881b 100644 --- a/RepSys/commands/patchspec.py +++ b/RepSys/commands/patchspec.py @@ -5,6 +5,7 @@ from RepSys import Error from RepSys.rpmutil import patch_spec from RepSys.command import * +from RepSys.layout import package_url import getopt import sys @@ -27,7 +28,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) != 2: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = package_url(args[0], mirrored=False) opts.patchfile = args[1] return opts diff --git a/RepSys/commands/putsrpm.py b/RepSys/commands/putsrpm.py index 21ad234..0717cd6 100644 --- a/RepSys/commands/putsrpm.py +++ b/RepSys/commands/putsrpm.py @@ -9,6 +9,7 @@ # from RepSys import Error from RepSys.command import * +from RepSys.layout import package_url from RepSys.rpmutil import put_srpm import getopt import sys, os @@ -34,7 +35,7 @@ def parse_options(): opts, args = parser.parse_args() if len(args) != 2: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = package_url(args[0], mirrored=False) opts.srpmfile = args[1] return opts diff --git a/RepSys/commands/rpmlog.py b/RepSys/commands/rpmlog.py index 3cdcc02..11fe36d 100644 --- a/RepSys/commands/rpmlog.py +++ b/RepSys/commands/rpmlog.py @@ -3,7 +3,7 @@ # This program will convert the output of "svn log" to be suitable # for usage in an rpm %changelog session. # -from RepSys import Error, RepSysTree +from RepSys import Error, layout from RepSys.command import * from RepSys.svn import SVN from RepSys.log import get_changelog, split_spec_changelog @@ -24,6 +24,7 @@ Options: -o Append old package changelog -p Append changelog found in .spec file -s Sort changelog entries, even from the old log + -M Do not use the mirror (use the main repository) -h Show this message Examples: @@ -45,17 +46,14 @@ def parse_options(): opts, args = parser.parse_args() if len(args) != 1: raise Error, "invalid arguments" - opts.pkgdirurl = default_parent(args[0]) + opts.pkgdirurl = layout.package_url(args[0]) return opts def rpmlog(pkgdirurl, revision, size, template, oldlog, usespec, sort): another = None if usespec: svn = SVN() - pkgname = RepSysTree.pkgname(pkgdirurl) - #FIXME don't hardcode current/, it may already be in the URL - specurl = os.path.join(pkgdirurl, "current/SPECS", pkgname + - ".spec") + specurl = layout.package_spec_url(pkgdirurl) rawspec = svn.cat(specurl, rev=revision) spec, another = split_spec_changelog(StringIO(rawspec)) newlog = get_changelog(pkgdirurl, another=another, rev=revision, diff --git a/RepSys/commands/submit.py b/RepSys/commands/submit.py index 2869ff4..334a424 100644 --- a/RepSys/commands/submit.py +++ b/RepSys/commands/submit.py @@ -1,7 +1,8 @@ #!/usr/bin/python from RepSys import Error, config from RepSys.command import * -from RepSys.rpmutil import get_spec, get_submit_info, svn_url_rev +from RepSys.layout import package_url, distro_branch +from RepSys.rpmutil import get_spec, get_submit_info from RepSys.util import get_auth, execcmd, get_helper import urllib import getopt @@ -41,16 +42,19 @@ Options: Examples: repsys submit repsys submit foo + repsys submit 2009.1/foo repsys submit foo@14800 bar baz@11001 repsys submit https://repos/svn/mdv/cooker/foo repsys submit -l https://repos repsys submit --define section=main/testing -t 2008.1 """ +DEFAULT_TARGET = "Cooker" + def parse_options(): parser = OptionParser(help=HELP) parser.defaults["revision"] = None - parser.add_option("-t", dest="target", default="Cooker") + parser.add_option("-t", dest="target", default=None) parser.add_option("-l", action="callback", callback=list_targets) parser.add_option("-r", dest="revision", type="string", nargs=1) parser.add_option("-s", dest="submithost", type="string", nargs=1, @@ -79,7 +83,11 @@ def parse_options(): else: raise Error, "the format is deprecated, "\ "use @ instead" - opts.urls = [default_parent(nameurl) for nameurl in args] + opts.urls = [package_url(nameurl, mirrored=False) for nameurl in args] + if opts.target is None: + target = distro_branch(opts.urls[0]) or DEFAULT_TARGET + print "Implicit target: %s" % target + opts.target = target return opts def list_targets(option, opt, val, parser): diff --git a/RepSys/layout.py b/RepSys/layout.py new file mode 100644 index 0000000..a4a3846 --- /dev/null +++ b/RepSys/layout.py @@ -0,0 +1,207 @@ +""" Handles repository layout scheme and package URLs.""" + +import os +import urlparse + +from RepSys import Error, config +from RepSys.svn import SVN + +__all__ = ["package_url", "checkout_url", "repository_url", "get_url_revision"] + +def layout_dirs(): + devel_branch = config.get("global", "trunk-dir", "cooker/") + devel_branch = os.path.normpath(devel_branch) + branches_dir = config.get("global", "branches-dir", "updates/") + branches_dir = os.path.normpath(branches_dir) + return devel_branch, branches_dir + +def get_url_revision(url, retrieve=True): + """Get the revision from a given URL + + If the URL contains an explicit revision number (URL@REV), just use it + without even checking if the revision really exists. + + The parameter retrieve defines whether it must ask the SVN server for + the revision number or not when it is not found in the URL. + """ + url, rev = split_url_revision(url) + if rev is None and retrieve: + # if no revspec was found, ask the server + svn = SVN() + rev = svn.revision(url) + return rev + +def unsplit_url_revision(url, rev): + if rev is None: + newurl = url + else: + parsed = list(urlparse.urlparse(url)) + path = os.path.normpath(parsed[2]) + parsed[2] = path + "@" + str(rev) + newurl = urlparse.urlunparse(parsed) + return newurl + +def split_url_revision(url): + """Returns a tuple (url, rev) from an subversion URL with @REV + + If the revision is not present in the URL, rev is None. + """ + parsed = list(urlparse.urlparse(url)) + path = os.path.normpath(parsed[2]) + dirs = path.rsplit("/", 1) + lastname = dirs[-1] + newname = lastname + index = lastname.rfind("@") + rev = None + if index != -1: + newname = lastname[:index] + rawrev = lastname[index+1:] + if rawrev: + try: + rev = int(rawrev) + if rev < 0: + raise ValueError + except ValueError: + raise Error, "invalid revision specification on URL: %s" % url + dirs[-1] = newname + newpath = "/".join(dirs) + parsed[2] = newpath + newurl = urlparse.urlunparse(parsed) + return newurl, rev + +def checkout_url(pkgdirurl, branch=None, version=None, release=None, + releases=False, pristine=False, append_path=None): + """Get the URL of a branch of the package, defaults to current/ + + It tries to preserve revisions in the format @REV. + """ + parsed = list(urlparse.urlparse(pkgdirurl)) + path, rev = split_url_revision(parsed[2]) + if releases: + path = os.path.normpath(path + "/releases") + elif version: + assert release is not None + path = os.path.normpath(path + "/releases/" + version + "/" + release) + elif pristine: + path = os.path.join(path, "pristine") + elif branch: + path = os.path.join(path, "branches", branch) + else: + path = os.path.join(path, "current") + if append_path: + path = os.path.join(path, append_path) + path = unsplit_url_revision(path, rev) + parsed[2] = path + newurl = urlparse.urlunparse(parsed) + return newurl + +def convert_default_parent(url): + """Removes the cooker/ component from the URL""" + parsed = list(urlparse.urlparse(url)) + path = os.path.normpath(parsed[2]) + rest, last = os.path.split(path) + parsed[2] = rest + newurl = urlparse.urlunparse(parsed) + return newurl + +def remove_current(pkgdirurl): + parsed = list(urlparse.urlparse(pkgdirurl)) + path = os.path.normpath(parsed[2]) + rest, last = os.path.split(path) + if last == "current": + # FIXME this way we will not allow packages to be named "current" + path = rest + parsed[2] = path + newurl = urlparse.urlunparse(parsed) + return newurl + +def repository_url(mirrored=False): + url = None + if mirrored and config.get("global", "use-mirror"): + url = config.get("global", "mirror") + if url is None: + url = config.get("global", "repository") + if not url: + # compatibility with the default_parent configuration option + default_parent = config.get("global", "default_parent") + if default_parent is None: + raise Error, "you need to set the 'repository' " \ + "configuration option on repsys.conf" + url = convert_default_parent(default_parent) + return url + +def package_url(name_or_url, version=None, release=None, distro=None, + mirrored=True): + """Returns a tuple with the absolute package URL and its name + + @name_or_url: name, relative path, or URL of the package. In case it is + a URL, the URL will just be 'normalized'. + @version: the version to be fetched from releases/ (requires release) + @release: the release number to be fetched from releases/$version/ + @distro: the name of the repository branch inside updates/ + @mirrored: return an URL based on the mirror repository, if enabled + """ + from RepSys import mirror + if "://" in name_or_url: + pkgdirurl = mirror.normalize_path(name_or_url) + pkgdirurl = remove_current(pkgdirurl) + if mirror.using_on(pkgdirurl) and not mirrored: + pkgdirurl = mirror.relocate_path(mirror.mirror_url(), + repository_url(), pkgdirurl) + else: + name = name_or_url + devel_branch, branches_dir = layout_dirs() + if distro or "/" in name: + default_branch = branches_dir + if distro: + default_branch = os.path.join(default_branch, distro) + else: + default_branch = devel_branch # cooker + path = os.path.join(default_branch, name) + parsed = list(urlparse.urlparse(repository_url(mirrored=mirrored))) + parsed[2] = os.path.join(parsed[2], path) + pkgdirurl = urlparse.urlunparse(parsed) + return pkgdirurl + +def package_name(pkgdirurl): + """Returns the package name from a package URL + + It takes care of revision numbers""" + parsed = urlparse.urlparse(pkgdirurl) + path, rev = split_url_revision(parsed[2]) + rest, name = os.path.split(path) + return name + +def package_spec_url(pkgdirurl, *args, **kwargs): + """Returns the URL of the specfile of a given package URL + + The parameters are the same used by checkout_url, except append_path. + """ + kwargs["append_path"] = "SPECS/" + package_name(pkgdirurl) + ".spec" + specurl = checkout_url(pkgdirurl, *args, **kwargs) + return specurl + +def distro_branch(pkgdirurl): + """Tries to guess the distro branch name from a package URL""" + from RepSys.mirror import same_base + found = None + repo = repository_url() + if same_base(repo, pkgdirurl): + devel_branch, branches_dir = layout_dirs() + repo_path = urlparse.urlparse(repo)[2] + devel_path = os.path.join(repo_path, devel_branch) + branches_path = os.path.join(repo_path, branches_dir) + parsed = urlparse.urlparse(pkgdirurl) + path = os.path.normpath(parsed[2]) + if path.startswith(devel_path): + # devel_branch must be before branches_dir in order to allow + # devel_branch to be inside branches_dir, as in /branches/cooker + _, found = os.path.split(devel_branch) + elif path.startswith(branches_path): + comps = path.split("/") + if branches_path == "/": + found = comps[1] + elif len(comps) >= 2: # must be at least branch/pkgname + found = comps[branches_path.count("/")+1] + return found + diff --git a/RepSys/log.py b/RepSys/log.py index ca1d107..a1d1944 100644 --- a/RepSys/log.py +++ b/RepSys/log.py @@ -1,5 +1,5 @@ #!/usr/bin/python -from RepSys import Error, config, RepSysTree +from RepSys import Error, config, layout from RepSys.svn import SVN from RepSys.util import execcmd @@ -400,8 +400,8 @@ def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, concat = config.get("log", "concat", "").split() revoffset = get_revision_offset() svn = SVN() - pkgreleasesurl = os.path.join(pkgdirurl, "releases") - pkgcurrenturl = os.path.join(pkgdirurl, "current") + pkgreleasesurl = layout.checkout_url(pkgdirurl, releases=True) + pkgcurrenturl = layout.checkout_url(pkgdirurl) releaseslog = svn.log(pkgreleasesurl, noerror=1) currentlog = svn.log(pkgcurrenturl, limit=size, start=rev, end=revoffset) @@ -535,7 +535,7 @@ def get_old_log(pkgdirurl): svn = SVN() tmpdir = tempfile.mktemp() try: - pkgname = RepSysTree.pkgname(pkgdirurl) + pkgname = layout.package_name(pkgdirurl) pkgoldurl = os.path.join(oldurl, pkgname) try: # we're using HEAD here because fixes in misc/ (oldurl) may diff --git a/RepSys/mirror.py b/RepSys/mirror.py index 20570d5..09d72de 100644 --- a/RepSys/mirror.py +++ b/RepSys/mirror.py @@ -1,10 +1,16 @@ +import sys import os import urlparse +import urllib -from RepSys import Error, config +from RepSys import Error, config, layout from RepSys.svn import SVN -def _normdirurl(url): +def mirror_url(): + mirror = config.get("global", "mirror") + return mirror + +def normalize_path(url): """normalize url for relocate_path needs""" parsed = urlparse.urlparse(url) path = os.path.normpath(parsed[2]) @@ -19,31 +25,51 @@ def _joinurl(url, relpath): parsed[3], parsed[4], parsed[5])) return newurl + +def strip_username(url): + parsed = list(urlparse.urlparse(url)) + _, parsed[1] = urllib.splituser(parsed[1]) + newurl = urlparse.urlunparse(parsed) + 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 + parent = normalize_path(parent) + url = normalize_path(url) + url = strip_username(url) return url.startswith(parent) def relocate_path(oldparent, newparent, url): - oldparent = _normdirurl(oldparent) - newparent = _normdirurl(newparent) - url = _normdirurl(url) + oldparent = normalize_path(oldparent) + newparent = normalize_path(newparent) + url = normalize_path(url) subpath = url[len(oldparent)+1:] newurl = _joinurl(newparent, subpath) # subpath usually gets / at begining return newurl def enabled(wcurl=None): - mirror = config.get("global", "mirror") - default_parent = config.get("global", "default_parent") + mirror = mirror_url() + repository = layout.repository_url() enabled = False - if mirror and default_parent: + if mirror and repository: enabled = True - if wcurl and (not same_base(mirror, wcurl)): + if wcurl and not same_base(mirror, wcurl): enabled = False return enabled +def using_on(url): + """returnes True if the URL points to the mirror repository""" + mirror = mirror_url() + if mirror: + using = same_base(mirror, url) + else: + using = False + return using + +def info(url, stream=sys.stderr): + if using_on(url): + stream.write("using mirror\n") + def mirror_relocate(oldparent, newparent, url, wcpath): svn = SVN() newurl = relocate_path(oldparent, newparent, url) @@ -52,34 +78,23 @@ def mirror_relocate(oldparent, newparent, url, wcpath): 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) + newurl = mirror_relocate(mirror_url(), layout.repository_url(), 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) + newurl = mirror_relocate(layout.repository_url(), mirror_url(), 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 - 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 "\ + mirror = mirror_url() + repository = layout.repository_url() + current = repository + if repository is None: + raise Error, "the option repository from repsys.conf is "\ "required" - indefault = same_base(default_parent, wcurl) + indefault = same_base(repository, wcurl) if not newbaseurl: if not mirror: raise Error, "an URL is needed when the option mirror "\ @@ -88,7 +103,7 @@ def autoswitch(svn, wcpath, wcurl, newbaseurl=None): chosen = mirror elif same_base(mirror, wcurl): current = mirror - chosen = default_parent + chosen = repository else: nobase = True else: @@ -101,7 +116,7 @@ def autoswitch(svn, wcpath, wcurl, newbaseurl=None): chosen = newbaseurl if nobase: raise Error, "the URL of this working copy is not based in "\ - "default_parent nor mirror URLs" + "repository 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 b73a9e2..32b7145 100644 --- a/RepSys/rpmutil.py +++ b/RepSys/rpmutil.py @@ -1,6 +1,6 @@ #!/usr/bin/python -from RepSys import Error, config, RepSysTree -from RepSys import mirror +from RepSys import Error, config +from RepSys import mirror, layout from RepSys.svn import SVN from RepSys.simplerpm import SRPM from RepSys.log import specfile_svn2rpm @@ -19,7 +19,7 @@ def get_spec(pkgdirurl, targetdir=".", submit=False): svn = SVN() tmpdir = tempfile.mktemp() try: - geturl = "/".join([pkgdirurl, "current", "SPECS"]) + geturl = layout.checkout_url(pkgdirurl, append_path="SPECS") svn.export("'%s'" % geturl, tmpdir) speclist = glob.glob(os.path.join(tmpdir, "*.spec")) if not speclist: @@ -52,51 +52,6 @@ def rev_touched_url(url, rev): touched = True return touched -def svn_url_rev(url, retrieve=True): - """Get the revision from a given URL - - If the URL contains an explicit revision number (URL@REV), just use it - without even checking if the revision really exists. - - The parameter retrieve defines whether it must ask the SVN server for - the revision number or not when it is not found in the URL. - """ - parsed = urlparse.urlparse(url) - path = os.path.normpath(parsed[2]) - dirs = path.rsplit("/", 1) - lastname = dirs[-1] - index = lastname.rfind("@") - rev = None - if index != -1: - rawrev = lastname[index+1:] - if rawrev: - try: - rev = int(rawrev) - if rev < 0: - raise ValueError - except ValueError: - raise Error, "invalid revision specification on URL: %s" % url - if rev is None and retrieve: - # if no revspec was found, ask the server - svn = SVN() - rev = svn.revision(url) - return rev - -def strip_url_rev(url): - """Removes the @REV from a string in the URL@REV scheme""" - parsed = list(urlparse.urlparse(url)) - path = os.path.normpath(parsed[2]) - dirs = path.rsplit("/", 1) - name = lastname = dirs[-1] - try: - index = lastname.rindex("@") - except ValueError: - pass - else: - name = lastname[:index] - parsed[2] = os.path.join(dirs[0], name) - return urlparse.urlunparse(parsed) - def get_srpm(pkgdirurl, mode = "current", targetdirs = None, @@ -121,15 +76,16 @@ def get_srpm(pkgdirurl, specdir = "--define '_specdir %s/%s'" % (tmpdir, "SPECS") srcrpmdir = "--define '_srcrpmdir %s/%s'" % (tmpdir, "SRPMS") patchdir = "--define '_patchdir %s/%s'" % (tmpdir, "SOURCES") + try: if mode == "version": - geturl = os.path.join(pkgdirurl, "releases", - version, release) + geturl = layout.checkout_url(pkgdirurl, version=version, + release=release) elif mode == "pristine": - geturl = os.path.join(pkgdirurl, "pristine") + geturl = layout.checkout_url(pkgdirurl, pristine=True) elif mode == "current" or mode == "revision": #FIXME we should handle revisions specified using @REV - geturl = os.path.join(pkgdirurl, "current") + geturl = layout.checkout_url(pkgdirurl) else: raise Error, "unsupported get_srpm mode: %s" % mode strict = strict or config.getbool("submit", "strict-revision", False) @@ -138,6 +94,7 @@ def get_srpm(pkgdirurl, # revision is None raise Error, "the revision %s does not change anything "\ "inside %s" % (revision or "HEAD", geturl) + mirror.info(geturl) svn.export(geturl, tmpdir, rev=revision) srpmsdir = os.path.join(tmpdir, "SRPMS") os.mkdir(srpmsdir) @@ -168,7 +125,7 @@ def get_srpm(pkgdirurl, targetsrpms = [] urlrev = None if revname: - urlrev = revision or svn_url_rev(geturl) + urlrev = revision or layout.get_url_revision(geturl) if not targetdirs: targetdirs = (".",) srpms = glob.glob(os.path.join(srpmsdir, "*.src.rpm")) @@ -194,10 +151,11 @@ def get_srpm(pkgdirurl, shutil.rmtree(tmpdir) def patch_spec(pkgdirurl, patchfile, log=""): + #FIXME use get_spec svn = SVN() tmpdir = tempfile.mktemp() try: - geturl = "/".join([pkgdirurl, "current", "SPECS"]) + geturl = layout.checkout_url(pkgdirurl, append_path="SPECS") svn.checkout(geturl, tmpdir) speclist = glob.glob(os.path.join(tmpdir, "*.spec")) if not speclist: @@ -301,10 +259,10 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""): shutil.rmtree(tmpdir) # Do revision and pristine tag copies - pristineurl = os.path.join(pkgdirurl, "pristine") + pristineurl = layout.checkout_url(pkgdirurl, pristine=True) svn.remove(pristineurl, noerror=1, log="Removing previous pristine/ directory.") - currenturl = os.path.join(pkgdirurl, "current") + currenturl = layout.checkout_url(pkgdirurl) svn.copy(currenturl, pristineurl, log="Copying release %s-%s to pristine/ directory." % (version, srpm.release)) @@ -316,7 +274,7 @@ def create_package(pkgdirurl, log="", verbose=0): svn = SVN() tmpdir = tempfile.mktemp() try: - basename = RepSysTree.pkgname(pkgdirurl) + basename = layout.package_name(pkgdirurl) if verbose: print "Creating package directory...", sys.stdout.flush() @@ -364,10 +322,10 @@ def mark_release(pkgdirurl, version, release, revision): log="Created releases directory.") svn.mkdir(versionurl, noerror=1, log="Created directory for version %s." % version) - pristineurl = os.path.join(pkgdirurl, "pristine") + pristineurl = layout.checkout_url(pkgdirurl, pristine=True) svn.remove(pristineurl, noerror=1, log="Removing previous pristine/ directory.") - currenturl = os.path.join(pkgdirurl, "current") + currenturl = layout.checkout_url(pkgdirurl) svn.copy(currenturl, pristineurl, log="Copying release %s-%s to pristine/ directory." % (version, release)) @@ -397,8 +355,8 @@ def check_changed(pkgdirurl, all=0, show=0, verbose=0): nocurrent = [] for package in packages: pkgdirurl = os.path.join(baseurl, package) - current = os.path.join(pkgdirurl, "current") - pristine = os.path.join(pkgdirurl, "pristine") + current = layout.checkout_url(pkgdirurl) + pristine = layout.checkout_url(pkgdirurl, pristine=True) if verbose: print "Checking package %s..." % package, sys.stdout.flush() @@ -435,17 +393,14 @@ def check_changed(pkgdirurl, all=0, show=0, verbose=0): "nocurrent": nocurrent, "nopristine": nopristine} -def checkout(pkgdirurl, path=None, revision=None, use_mirror=True): +def checkout(pkgdirurl, path=None, revision=None, branch=None, + distro=None): o_pkgdirurl = pkgdirurl - pkgdirurl = default_parent(o_pkgdirurl) - current = os.path.join(pkgdirurl, "current") + pkgdirurl = layout.package_url(o_pkgdirurl, distro=distro) + current = layout.checkout_url(pkgdirurl, branch=branch) if path is 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 use_mirror and mirror.enabled(): - current = mirror.checkout_url(current) - print "checking out from mirror", current + path = layout.package_name(pkgdirurl) + mirror.info(current) svn = SVN() svn.checkout(current, path, rev=revision, show=1) @@ -537,7 +492,7 @@ def commit(target=".", message=None, logfile=None): url = info.get("URL") if url is None: raise Error, "working copy URL not provided by svn info" - mirrored = mirror.enabled(url) + mirrored = mirror.using_on(url) if mirrored: newurl = mirror.switchto_parent(svn, url, target) print "relocated to", newurl -- cgit v1.2.1