aboutsummaryrefslogtreecommitdiffstats
path: root/RepSys/mirror.py
blob: 5b114df86780903332affb08e8cda898dfd914bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import os
import urlparse

from RepSys import Error, config
from RepSys.svn import SVN

def _normdirurl(url):
    """normalize url for relocate_path needs"""
    parsed = urlparse.urlparse(url)
    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[2], relpath)
    newurl = urlparse.urlunparse((parsed[0], parsed[1], newpath,
        parsed[3], parsed[4], parsed[5]))
    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):
    oldparent = _normdirurl(oldparent)
    newparent = _normdirurl(newparent)
    url = _normdirurl(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")
    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()
    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

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