Changeset 513 for CMT/HEAD/mgr


Ignore:
Timestamp:
Jun 27, 2009, 9:58:12 PM (15 years ago)
Author:
rybkin
Message:

See C.L. 402

Location:
CMT/HEAD/mgr
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • CMT/HEAD/mgr/cmt_svn_checkout.py

    r512 r513  
    2323"""
    2424
    25 __version__ = '0.2.0'
    26 __date__ = 'Thu Jun 18 2009'
     25__version__ = '0.3.0'
     26__date__ = 'Thu Jun 27 2009'
    2727__author__ = 'Grigory Rybkin'
    2828
     
    3333import os.path
    3434import urlparse
     35# for Python 2.3 and older
     36if sys.version_info[0] == 2 and sys.version_info[1] < 4:
     37    for p in ('svn', 'svn+ssh'):
     38        if p not in urlparse.uses_netloc:
     39            urlparse.uses_netloc.append(p)
    3540import tempfile
     41import commands
     42import re
    3643
    3744self = 'cmt_svn_checkout.py'
    38 try:
    39     from svn import client, core
    40 except ImportError, e:
    41     print >>sys.stderr, '%s: cannot import Subversion Python bindings: %s' \
    42           % (self, str(e))
    43     sys.exit(1)
     45# try:
     46#     from svn import client, core
     47# except ImportError, e:
     48#     print >>sys.stderr, '%s: cannot import Subversion Python bindings: %s' \
     49#           % (self, str(e))
     50#     sys.exit(1)
    4451
    4552class ClientContext(object):
    46     def __init__(self):
    47         core.svn_config_ensure(None)
    48         self.ctx = client.create_context()
    49         self.providers = [
    50             client.get_simple_provider(),
    51             client.get_username_provider(),
    52             client.get_ssl_server_trust_file_provider(),
    53             client.get_ssl_client_cert_file_provider(),
    54             client.get_ssl_client_cert_pw_file_provider()
    55             ]
    56         self.ctx.auth_baton = core.svn_auth_open(self.providers)
    57         self.ctx.config = core.svn_config_get_config(None)
    58 
    59     def __call__(self):
    60         return self.ctx
     53
     54    schemes = ('http', 'https', 'svn', 'svn+ssh', 'file')
     55
     56    def svn_path_canonicalize(self, path):
     57        """Return a new path (or URL) like path, but transformed such that some types of path specification redundancies are removed.
     58
     59        This involves collapsing redundant "/./" elements, removing multiple adjacent separator characters, removing trailing separator characters, and possibly other semantically inoperative transformations. Convert the scheme and hostname to lowercase."""
     60        scheme, netloc, path, query, fragment = urlparse.urlsplit(path)
     61        scheme = scheme.lower()
     62        netloc = netloc.lower()
     63        if path.startswith('/'): b = '/'
     64        else: b = ''
     65        path = b + '/'.join([s for s in path.split('/') if s and s != '.'])
     66        return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
     67
     68    def urljoin(self, *args):
     69        urls = [urlparse.urlsplit(arg) for arg in args]
     70        if not urls: return ''
     71       
     72        schemes = [url[0] for url in urls]
     73        schemes.reverse()
     74        for i, s in enumerate(schemes):
     75            if s and s in self.schemes:
     76                scheme = s
     77                index = i
     78                break
     79        else:
     80            scheme = ''
     81            index = len(urls) - 1
     82       
     83        netlocs = [url[1] for url in urls]
     84        netlocs.reverse()
     85        for i, s in enumerate(netlocs[:index + 1]):
     86            if s:
     87                netloc = s
     88                index = i
     89                break
     90        else:
     91            netloc = ''
     92       
     93        path = posixpath.join(*[url[2] for url in urls][len(urls) - 1 - index:])
     94
     95        query = fragment = ''
     96        return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
     97
     98#         scheme = self.last_nonempty([url[0] for url in urls if url[0] in self.schemes])
     99#         netloc = self.last_nonempty([url[1] for url in urls])
     100#         path = posixpath.join(*[url[2] for url in urls])
     101#         query = self.last_nonempty([url[3] for url in urls])
     102#         fragment = self.last_nonempty([url[4] for url in urls])
     103       
     104#         return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
     105
     106    def last_nonempty(self, list, default = ''):
     107        list.reverse()
     108        for i in list:
     109            if i: return i
     110        else:
     111            return default
     112       
     113#     def __init__(self):
     114#         core.svn_config_ensure(None)
     115#         self.ctx = client.create_context()
     116#         self.providers = [
     117#             client.get_simple_provider(),
     118#             client.get_username_provider(),
     119#             client.get_ssl_server_trust_file_provider(),
     120#             client.get_ssl_client_cert_file_provider(),
     121#             client.get_ssl_client_cert_pw_file_provider()
     122#             ]
     123#         self.ctx.auth_baton = core.svn_auth_open(self.providers)
     124#         self.ctx.config = core.svn_config_get_config(None)
     125
     126#     def __call__(self):
     127#         return self.ctx
    61128
    62129def cwd():
     
    95162                 config = True,
    96163                 with_version_directory = True,
    97                  cleanup = False):
     164                 cleanup = False,
     165                 head_version = None):
    98166        self.config = config
    99167        self.with_version_directory = with_version_directory
    100168        self.cleanup = cleanup
     169        self.head_version = head_version
     170        self.env()
     171
     172    def env(self):
     173        if self.head_version is None:
     174            self.set_head_version(os.getenv('CMTHEADVERSION', 'HEAD'))
     175#        print >>sys.stderr, 'env: set head_version: %s' % self.head_version
     176
     177    def set_head_version(self, version):
     178        self.head_version = str(version).replace('<package>', '%(package)s').replace('<PACKAGE>', '%(PACKAGE)s').replace('<revision>', '%(revision)i')
     179
     180    def eval_head_version(self, m):
     181        return self.head_version % \
     182               {'package' : m.package,
     183                'PACKAGE' : m.package.upper(),
     184                'revision' : m.info.last_changed_rev}
    101185
    102186    def write(self, p, version):
     
    124208        #print >> sys.stderr, 'generate:', p
    125209        curdir = cwd()
    126         cmd = 'cmt -disable_warnings'
     210#        cmd = 'cmt -disable_warnings'
     211        cmd = 'cmt -q'
    127212        if self.with_version_directory:
    128213            cmd += ' -with_version_directory'
     
    138223        if sc != 0: sc = 1
    139224        cd(curdir)
    140         return sc
     225#        return sc
     226        return 0
    141227
    142228    def configure(self, path, version):
     
    157243        self.module = module
    158244        self.init = False
     245        class info(object):
     246            last_changed_rev = 0
     247        self.info = info
     248#         print >>sys.stderr, 'init module %s: last_changed_rev %i' % \
     249#               (self.module, self.info.last_changed_rev)
    159250       
    160251class Checkout(object):
     
    167258                 version_dir = None,
    168259                 directory = None,
    169                  offset = None,
     260                 offset = '',
    170261                 modules = []):
    171262        self.url = url
     
    182273    def reposLayout(self):
    183274        if self.url is None:
    184             try:
    185                 self.url = os.environ['SVNROOT']
    186             except KeyError:
    187                 pass
     275            self.url = os.getenv('SVNROOT', '')
     276#             try:
     277#                 self.url = os.environ['SVNROOT']
     278#             except KeyError:
     279#                 pass
    188280        if self.trunk is None:
    189             try:
    190                 self.trunk = os.environ['SVNTRUNK']
    191             except KeyError:
    192                 self.trunk = 'trunk'
     281            self.trunk = os.getenv('SVNTRUNK', 'trunk')
    193282        if self.tags is None:
    194             try:
    195                 self.tags = os.environ['SVNTAGS']
    196             except KeyError:
    197                 self.tags = 'tags'
     283            self.tags = os.getenv('SVNTAGS', 'tags')
    198284        if self.branches is None:
    199             try:
    200                 self.branches = os.environ['SVNBRANCHES']
    201             except KeyError:
    202                 self.branches = 'branches'
     285            self.branches = os.getenv('SVNBRANCHES', 'branches')
    203286
    204287    def cmtRepos(self):
     
    214297        self.path = path
    215298        self.info = info
     299        pool.info = info
    216300
    217301    def cmp(self, path1, path2, client_context):
    218         outfile = tempfile.TemporaryFile('wb')
    219         errfile = tempfile.TemporaryFile('wb')
    220         outb = outfile.tell()
    221         errb = errfile.tell()
    222         client.diff([]
    223                     , path1
    224                     , self.head_revision
    225                     , path2
    226                     , self.head_revision
    227                     , True, True, False
    228                     , outfile
    229                     , errfile
    230                     , client_context())
    231 
    232         # position at the end of the file
    233         outfile.seek(0, 2)
    234         errfile.seek(0, 2)
    235         oute = outfile.tell()
    236         erre = errfile.tell()
    237 
    238         if erre > errb: return 2
    239         elif oute > outb: return 1
     302        cmd = 'svn diff %s %s' % (path1, path2)
     303#        cmd = 'svn diff --summarize %s %s' % (path1, path2)
     304        sc, out = commands.getstatusoutput(cmd)
     305        if sc != 0:
     306            return 2
     307        if out: return 1
    240308        else: return 0
     309
     310#         outfile = tempfile.TemporaryFile('wb')
     311#         errfile = tempfile.TemporaryFile('wb')
     312#         outb = outfile.tell()
     313#         errb = errfile.tell()
     314#         client.diff([]
     315#                     , path1
     316#                     , self.head_revision
     317#                     , path2
     318#                     , self.head_revision
     319#                     , True, True, False
     320#                     , outfile
     321#                     , errfile
     322#                     , client_context())
     323
     324#         # position at the end of the file
     325#         outfile.seek(0, 2)
     326#         errfile.seek(0, 2)
     327#         oute = outfile.tell()
     328#         erre = errfile.tell()
     329
     330#         if erre > errb: return 2
     331#         elif oute > outb: return 1
     332#         else: return 0
    241333
    242334    def trunk_tag(self, module, client_context):
     
    246338        its last_changed_rev is greater than the trunk created_rev, None otherwise.
    247339        """
    248         try:
    249             trunk = core.svn_path_canonicalize(posixpath.join(module.url, self.trunk))
    250             client.info(trunk,
    251                         self.head_revision,
    252                         self.head_revision,
    253                         self.info_receiver,
    254                         False,
    255                         client_context())
     340        trunk = posixpath.join(module.url, self.trunk)
     341#        trunk = posixpath.normpath(posixpath.join(module.url, self.trunk))
     342        cmd = 'svn info %s' % trunk
     343        sc, out = commands.getstatusoutput(cmd)
     344        if sc != 0:
     345            return None
     346        p = r'last\s+changed\s+rev:\s+(?P<rev>\d+)'
     347        m = re.search(p, out, re.I)
     348        if m:
     349            class info(object): pass
     350            info.last_changed_rev = int(m.group('rev'))
     351            self.info_receiver(trunk, info, module)
     352#            self.info_receiver(trunk, info, None)
     353#             print >>sys.stderr, '%s: last_changed_rev %i' % \
     354#                   (trunk, self.info.last_changed_rev)
     355#            last_changed_rev = int(m.group('rev'))
     356        else:
     357            return None
     358
     359        tags = posixpath.join(module.url, self.tags)
     360#        tags = posixpath.normpath(posixpath.join(module.url, self.tags))
     361        cmd = 'svn ls -v %s' % tags
     362        sc, out = commands.getstatusoutput(cmd)
     363        if sc != 0:
     364            return None
     365
     366        tags_dirent = [line.split() for line in out.splitlines()]
     367        rev_tag = dict([(int(line[0]), line[-1].rstrip(posixpath.sep)) for line in tags_dirent if line[-1].endswith(posixpath.sep)])
     368        revs = rev_tag.keys()
     369        revs.sort()
     370        revs.reverse()
     371
     372        for rev in revs:
     373            if rev < self.info.last_changed_rev: break
     374#            if rev < last_changed_rev: break
     375            tag = posixpath.join(tags, rev_tag[rev])
     376#            tag = posixpath.normpath(posixpath.join(tags, rev_tag[rev]))
     377            if 0 == self.cmp(trunk, tag, client_context):
     378                return rev_tag[rev]
     379
     380        return None
     381
     382#         try:
     383#             trunk = core.svn_path_canonicalize(posixpath.join(module.url, self.trunk))
     384#             client.info(trunk,
     385#                         self.head_revision,
     386#                         self.head_revision,
     387#                         self.info_receiver,
     388#                         False,
     389#                         client_context())
    256390           
    257             tags = core.svn_path_canonicalize(posixpath.join(module.url, self.tags))
    258             tags_dirent = client.ls(tags,
    259                                     self.head_revision,
    260                                     False,
    261                                     client_context())
     391#             tags = core.svn_path_canonicalize(posixpath.join(module.url, self.tags))
     392#             tags_dirent = client.ls(tags,
     393#                                     self.head_revision,
     394#                                     False,
     395#                                     client_context())
    262396           
    263             rev_tag = dict([(tags_dirent[p].created_rev, p) for p in tags_dirent if tags_dirent[p].kind == core.svn_node_dir])
    264             revs = rev_tag.keys()
    265             revs.sort()
    266             revs.reverse()
    267 
    268             for rev in revs:
    269                 if rev < self.info.last_changed_rev: break
    270                 tag = core.svn_path_canonicalize(posixpath.join(tags, rev_tag[rev]))
    271                 if 0 == self.cmp(trunk, tag, client_context):
    272                     return rev_tag[rev]
    273 
    274             return None
    275         except core.SubversionException, e:
    276             return None
     397#             rev_tag = dict([(tags_dirent[p].created_rev, p) for p in tags_dirent if tags_dirent[p].kind == core.svn_node_dir])
     398#             revs = rev_tag.keys()
     399#             revs.sort()
     400#             revs.reverse()
     401
     402#             for rev in revs:
     403#                 if rev < self.info.last_changed_rev: break
     404#                 tag = core.svn_path_canonicalize(posixpath.join(tags, rev_tag[rev]))
     405#                 if 0 == self.cmp(trunk, tag, client_context):
     406#                     return rev_tag[rev]
     407
     408#             return None
     409#         except core.SubversionException, e:
     410#             return None
    277411
    278412    def initialize(self, cmt_context, client_context):
    279413        sc = 0
    280         self.head_revision = core.svn_opt_revision_t()
    281         self.head_revision.kind = core.svn_opt_revision_head
     414#         self.head_revision = core.svn_opt_revision_t()
     415#         self.head_revision.kind = core.svn_opt_revision_head
     416
     417        # canonicalize:
     418        self.url = client_context.svn_path_canonicalize(self.url)
     419        self.offset = client_context.svn_path_canonicalize(self.offset)
    282420
    283421        for m in self.modules:
    284             if urlparse.urlparse(m.module)[0] in ('http', 'https',
    285                                                   'svn', 'svn+ssh', 'file'):
    286                 m.url = m.module
    287                 m.path = posixpath.basename(m.module)
    288             elif posixpath.isabs(m.module):
    289                 m.url = urlparse.urljoin('file://', m.module)
    290                 m.path = posixpath.basename(m.module)
    291             else:
    292                 if self.url is None:
    293                     self.cmtRepos()
    294 
    295                 if self.offset is None:
    296                     m.url = posixpath.join(self.url, m.module)
    297                 else:
    298                     m.url = posixpath.join(self.url, self.offset, m.module)
    299                 m.path = os.path.join(*m.module.split(posixpath.sep))
     422            m.module = client_context.svn_path_canonicalize(m.module)
     423            m.url = client_context.urljoin(self.url, self.offset, m.module)
     424
     425            if urlparse.urlparse(m.url)[0] not in client_context.schemes:
     426                error('%s: Not a valid Subversion URL' % m.url)
     427                sc += 1; continue
     428#             print >>sys.stderr, '%s: URL constructed from %s %s %s' % \
     429#                   (m.url, `self.url`, `self.offset`, `m.module`)
     430
     431            m.package = posixpath.basename(m.url)
    300432
    301433            if self.directory is not None:
    302434                m.path = os.path.normpath(self.directory)
    303                
     435            else:
     436                scheme, netloc, path, query, fragment = urlparse.urlsplit(m.module)
     437                if not scheme and not netloc:
     438                    m.path = os.path.normpath(os.path.join(*path.split(posixpath.sep)))
     439                else:
     440                    m.path = posixpath.basename(m.url)
     441
    304442            if self.version is None:
    305443                m.head = True
    306                 m.version = self.trunk_tag(m, client_context) or 'HEAD'
     444                m.version = self.trunk_tag(m, client_context) or \
     445                            cmt_context.eval_head_version(m)
     446#                print >>sys.stderr, 'set version: %s' % m.version
    307447            else:
    308448                m.head = False
     
    312452                m.URL = [posixpath.join(m.url, self.trunk)]
    313453            else:
    314 #                m.url = posixpath.join(m.url, self.tags, m.version)
    315454                m.URL = [posixpath.join(m.url, p, m.version)
    316455                         for p in (self.tags, self.branches)]
    317                 #m.URL = [posixpath.join(m.url, self.tags, m.version),
    318                 #         posixpath.join(m.url, self.branches, m.version)]
    319             #m.url = core.svn_path_canonicalize(m.url)
    320             m.URL = [core.svn_path_canonicalize(url) for url in m.URL]
     456            m.URL = [client_context.svn_path_canonicalize(url) for url in m.URL]
     457#            m.URL = [core.svn_path_canonicalize(url) for url in m.URL]
    321458
    322459            if cmt_context.with_version_directory:
     
    341478            err = []
    342479            for url in m.URL:
    343                 try:
    344                     #print 'client.checkout2:', url, m.path
    345                     result_rev = client.checkout2(url,
    346                                                   m.path,
    347                                                   self.head_revision,
    348                                                   self.head_revision,
    349                                                   True,
    350                                                   True,
    351                                                   client_context())
    352                 except core.SubversionException, e:
     480#                cmd = 'svn checkout -q %s %s 2>/dev/null' % (url, m.path)
     481                cmd = 'svn checkout -q %s %s' % (url, m.path)
     482                sc, e = commands.getstatusoutput(cmd)
     483                #sc = os.system(cmd)
     484                if 0 == sc:
     485#                 try:
     486#                     #print 'client.checkout2:', url, m.path
     487#                     result_rev = client.checkout2(url,
     488#                                                   m.path,
     489#                                                   self.head_revision,
     490#                                                   self.head_revision,
     491#                                                   True,
     492#                                                   True,
     493#                                                   client_context())
     494#                 except core.SubversionException, e:
     495#                     err.append(e)
     496#                     continue
     497                    done = True
     498                    break
     499                else:
    353500                    err.append(e)
    354501                    continue
    355                 done = True
    356                 break
    357502
    358503            if not done:
    359504                for e in err:
    360505                    error(e)
    361                     #print >> sys.stderr, e
    362                     sc += 1
     506#                     #print >> sys.stderr, e
     507#                     sc += 1
     508#                 print >> sys.stderr, 'Failed to checkout %s into %s.' % \
     509#                       (' or '.join(m.URL), m.path)
     510                sc += 1
    363511                continue
    364512
  • CMT/HEAD/mgr/requirements

    r502 r513  
    475475
    476476macro svn_checkout_command "" \
    477       Linux        "/usr/bin/python ${CMTROOT}/mgr/cmt_svn_checkout.py " \
     477      Linux        "python ${CMTROOT}/mgr/cmt_svn_checkout.py " \
    478478      Darwin       "python ${CMTROOT}/mgr/cmt_svn_checkout.py " \
    479479      VisualC      "python %CMTROOT%\mgr\cmt_svn_checkout.py "
Note: See TracChangeset for help on using the changeset viewer.