source: CMT/HEAD/mgr/cmt_svn_checkout.py @ 497

Last change on this file since 497 was 497, checked in by rybkin, 15 years ago

See C.L. 392

  • Property svn:executable set to *
File size: 12.1 KB
Line 
1#!/usr/bin/env python
2
3"""cmt_svn_checkout.py: Checkout CMT package(s) from Subversion repository.
4
5Usage: cmt_svn_checkout.py [OPTION]... PATH...
6Checkout PATH(s) relative to or being Subversion repository URL(s).
7
8Mandatory arguments to long options are mandatory for short options too.
9  -r, --version-tag=REV        checkout version tag REV of PATH
10      --version-dir=DIR        use DIR as version directory instead of version tag
11  -d, --directory=DIR          checkout into DIR instead of (basename of) PATH
12  -o, --offset=OFFSET          checkout PATH at OFFSET relative to repository URL
13      --no_config              disable config step upon checkout
14      --without_version_directory do not create version directory upon PATH checkout
15      --with_version_directory create version directory upon PATH checkout (default)
16      --url=URL                checkout PATH from repository URL
17  -h, --help                   display this help and exit
18      --version                output version information and exit
19
20The SVNROOT, SVNTRUNK, SVNTAGS, and SVNBRANCHES environment variables specify repository URL of PATH, location of PATH trunk, tags, and branches (relatively to PATH) respectively.
21
22Report bugs to <CMT-L@IN2P3.FR>.
23"""
24
25__version__ = '0.1.2'
26__date__ = 'Mon Apr 28 2009'
27__author__ = 'Grigory Rybkin'
28
29import sys
30import getopt
31import os
32import posixpath
33import os.path
34import urlparse
35
36self = 'cmt_svn_checkout.py'
37try:
38    from svn import client, core
39except ImportError, e:
40    print >>sys.stderr, '%s: %s: cannot import Subversion Python bindings' \
41          % (self, str(e))
42    sys.exit(1)
43
44class ClientContext(object):
45    def __init__(self):
46        core.svn_config_ensure(None)
47        self.ctx = client.create_context()
48        self.providers = [
49            client.get_simple_provider(),
50            client.get_username_provider(),
51            client.get_ssl_server_trust_file_provider(),
52            client.get_ssl_client_cert_file_provider(),
53            client.get_ssl_client_cert_pw_file_provider()
54            ]
55        self.ctx.auth_baton = core.svn_auth_open(self.providers)
56        self.ctx.config = core.svn_config_get_config(None)
57
58    def __call__(self):
59        return self.ctx
60
61def cwd():
62    _gcwd = os.getcwd()
63    try:
64        _cwd = os.environ['PWD']
65        if _cwd and os.path.samefile(_cwd, _gcwd):
66            return _cwd
67        else:
68            return _gcwd
69    except (KeyError, AttributeError):
70        return _gcwd
71
72def cd(path):
73    new = os.path.normpath(os.path.join(cwd(), path))
74    os.chdir(path)
75    _gcwd = os.getcwd()
76    try:
77        if os.path.samefile(new, _gcwd):
78            os.environ['PWD'] = new
79        else:
80            os.environ['PWD'] = _gcwd
81    except AttributeError:
82        pass
83
84class CmtContext(object):
85    def __init__(self,
86                 config = True,
87                 with_version_directory = True,
88                 cleanup = False):
89        self.config = config
90        self.with_version_directory = with_version_directory
91        self.cleanup = cleanup
92
93    def write(self, p, version):
94        #print >> sys.stderr, 'write:', p, version
95        try:
96            t = version + '\n'
97            if os.path.exists(p):
98                f = open(p, 'r+')
99                b = f.tell()
100                v = f.read()
101                if v != t:
102                    f.seek(b)
103                    f.write(t)
104                    f.truncate()
105            else:
106                f = open(p, 'w')
107                f.write(t)
108            f.close()
109        except IOError, e:
110            print >> sys.stderr, e
111            return 1
112        return 0
113       
114    def generate(self, p):
115        #print >> sys.stderr, 'generate:', p
116        curdir = cwd()
117        cmd = 'cmt -disable_warnings'
118        if self.with_version_directory:
119            cmd += ' -with_version_directory'
120        else:
121            cmd += ' -without_version_directory'
122        if self.cleanup:
123            cmd += ' -cleanup'
124        else:
125            cmd += ' -no_cleanup'
126        cmd += ' config'
127        cd(p)
128        sc = os.system(cmd)
129        if sc != 0: sc = 1
130        cd(curdir)
131        return sc
132
133    def configure(self, path, version):
134        sc = 0
135        for d in ('cmt', 'mgr'):
136            p = os.path.join(path, d)
137            if os.path.isdir(p):
138                if not self.with_version_directory:
139                    sc += self.write(os.path.join(p,'version.cmt'), version)
140                if self.config:
141                    sc += self.generate(p)
142                return sc
143        return sc
144        #print >> sys.stderr, 'Cannot configure %s ' % (path, version)
145
146class Module(object):
147    def __init__(self, module):
148        self.module = module
149        self.init = False
150       
151class Checkout(object):
152    def __init__(self,
153                 url = None,
154                 trunk = None,
155                 tags = None,
156                 branches = None,
157                 version = None,
158                 version_dir = None,
159                 directory = None,
160                 offset = None,
161                 modules = []):
162        self.url = url
163        self.trunk = trunk
164        self.tags = tags
165        self.branches = branches
166        self.version = version
167        self.version_dir = version_dir
168        self.directory = directory
169        self.offset = offset
170        self.modules = modules
171        self.reposLayout()
172       
173    def reposLayout(self):
174        if self.url is None:
175            try:
176                self.url = os.environ['SVNROOT']
177            except KeyError:
178                pass
179        if self.trunk is None:
180            try:
181                self.trunk = os.environ['SVNTRUNK']
182            except KeyError:
183                self.trunk = 'trunk'
184        if self.tags is None:
185            try:
186                self.tags = os.environ['SVNTAGS']
187            except KeyError:
188                self.tags = 'tags'
189        if self.branches is None:
190            try:
191                self.branches = os.environ['SVNBRANCHES']
192            except KeyError:
193                self.branches = 'branches'
194
195    def cmtRepos(self):
196        self.url = 'https://svn.lal.in2p3.fr/projects/CMT'
197        self.trunk = 'HEAD'
198        self.tags= '.'
199        self.branches = '.'
200
201    def add(self, module):
202        self.modules.append(module)
203
204    def initialize(self, cmt_context, client_context):
205        sc = 0
206        self.head_revision = core.svn_opt_revision_t()
207        self.head_revision.kind = core.svn_opt_revision_head
208
209        for m in self.modules:
210            if urlparse.urlparse(m.module)[0] in ('http', 'https',
211                                                  'svn', 'svn+ssh', 'file'):
212                m.url = m.module
213                m.path = posixpath.basename(m.module)
214            elif posixpath.isabs(m.module):
215                m.url = urlparse.urljoin('file://', m.module)
216                m.path = posixpath.basename(m.module)
217            else:
218                if self.url is None:
219                    self.cmtRepos()
220
221                if self.offset is None:
222                    m.url = posixpath.join(self.url, m.module)
223                else:
224                    m.url = posixpath.join(self.url, self.offset, m.module)
225                m.path = os.path.join(*m.module.split(posixpath.sep))
226
227            if self.directory is not None:
228                m.path = os.path.normpath(self.directory)
229               
230            if self.version is None:
231                m.head = True
232                tags = core.svn_path_canonicalize(posixpath.join(m.url, self.tags))
233                try:
234                    #print 'client.ls2:', tags
235                    ls_tags = client.ls2(tags,
236                                         self.head_revision,
237                                         self.head_revision,
238                                         False,
239                                         client_context())
240                    rev_tag = dict([(ls_tags[p].created_rev, p) for p in ls_tags if ls_tags[p].kind == core.svn_node_dir])
241#                rev_latest = max(rev_tag.keys())
242#                tag_latest = rev_tag[rev_latest]
243                    m.version = rev_tag[max(rev_tag.keys())]
244                except core.SubversionException, e:
245                    print >> sys.stderr, e
246                    m.version = 'HEAD'
247                except ValueError, e: # max() arg is an empty sequence
248                    #print >> sys.stderr, e
249                    m.version = 'HEAD'
250            else:
251                m.head = False
252                m.version = self.version
253
254            if m.head:
255                m.url = posixpath.join(m.url, self.trunk)
256            else:
257                m.url = posixpath.join(m.url, self.tags, m.version)
258            m.url = core.svn_path_canonicalize(m.url)
259
260            if cmt_context.with_version_directory:
261                if self.version_dir is None:
262                    m.path = os.path.join(m.path, m.version)
263                else:
264                    m.path = os.path.join(m.path, self.version_dir)
265
266            m.init = True
267           
268#        for m in self.modules:
269#            print m.url, m.path, m.init
270        return sc
271
272    def execute(self, cmt_context, client_context):
273        sc = 0
274
275        for m in self.modules:
276            if not m.init: continue
277            try:
278#                print 'client.checkout2:', m.url, m.path
279                result_rev = client.checkout2(m.url,
280                                              m.path,
281                                              self.head_revision,
282                                              self.head_revision,
283                                              True,
284                                              True,
285                                              client_context())
286            except core.SubversionException, e:
287                print >> sys.stderr, e
288                sc += 1
289                continue
290#            print 'Checked out revision %i.' % result_rev
291            scc = cmt_context.configure(m.path, m.version)
292            if scc != 0:
293                print >> sys.stderr, \
294                      '%s %s: configure returned %i.' % (m.path, m.version, scc)
295            sc += scc
296
297        return sc
298
299def main(argv=[__name__]):
300    self = os.path.basename(argv[0])
301    try:
302        opts, args = getopt.getopt(argv[1:],
303                                   "hr:d:o:",
304                                   ["help", "version", "version-tag=",
305                                    "version-dir=", "directory=",
306                                    "offset=", "no_config",
307                                    "with_version_directory",
308                                    "without_version_directory", "url="])
309    except getopt.error, e:
310        print >>sys.stderr, '%s: %s' % (self, str(e))
311        print >>sys.stderr, "Try '%s --help' for more information." % self
312        return 1
313
314    cmt_context = CmtContext()
315    checkout = Checkout()
316
317    for o, v in opts:
318        if o in ("-h", "--help"):
319            print sys.modules[__name__].__doc__
320            return 0
321        elif o in ("--version",):
322            print '%s %s (%s)' % (self, __version__, __date__)
323            print '%sWritten by %s.' % (os.linesep, __author__)
324            return 0
325        elif o in ("-r", "--version-tag"):
326            checkout.version = v
327        elif o in ("--version-dir",):
328            checkout.version_dir = v
329        elif o in ("-d", "--directory"):
330            checkout.directory = v
331        elif o in ("-o", "--offset"):
332            checkout.offset = v
333        elif o in ("--no_config",):
334            cmt_context.config = False
335        elif o in ("--without_version_directory",):
336            cmt_context.with_version_directory = False
337        elif o in ("--with_version_directory",):
338            cmt_context.with_version_directory = True
339        elif o in ("--url",):
340            checkout.url = v
341
342    if not args:
343        print >>sys.stderr, '%s: missing path argument' % self
344        print >>sys.stderr, "Try '%s --help' for more information." % self
345        return 1
346
347    for arg in args:
348        checkout.add(Module(arg))
349
350    client_context = ClientContext()
351    sci = checkout.initialize(cmt_context, client_context)
352    sce = checkout.execute(cmt_context, client_context)
353
354    if sci != 0 or sce !=0:
355        return 1
356    else:
357        return 0
358
359if __name__ == '__main__':
360    sys.exit(main(sys.argv))
Note: See TracBrowser for help on using the repository browser.