mercurial/archival.py
author Thomas Arendsen Hein <thomas@intevation.de>
Thu, 21 Jun 2007 19:24:27 +0200
changeset 4668 e241598e956f
parent 4652 06de65673ec2
child 4688 8f91264f154a
permissions -rw-r--r--
Remove useless variable assignments in util.opener. The original idea might have been to prevent circular references, but as this assignment would have created another reference, this makes no difference.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     1
# archival.py - revision archival for mercurial
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     2
#
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     3
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     4
#
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     6
# the GNU General Public License, incorporated herein by reference.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     7
3893
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3886
diff changeset
     8
from i18n import _
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     9
from node import *
3886
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3615
diff changeset
    10
import cStringIO, os, stat, tarfile, time, util, zipfile
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    11
import zlib, gzip
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    12
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    13
def tidyprefix(dest, prefix, suffixes):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    14
    '''choose prefix to use for names in archive.  make sure prefix is
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    15
    safe for consumers.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    16
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    17
    if prefix:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    18
        prefix = prefix.replace('\\', '/')
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    19
    else:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    20
        if not isinstance(dest, str):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    21
            raise ValueError('dest must be string if no prefix')
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    22
        prefix = os.path.basename(dest)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    23
        lower = prefix.lower()
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    24
        for sfx in suffixes:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    25
            if lower.endswith(sfx):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    26
                prefix = prefix[:-len(sfx)]
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    27
                break
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    28
    lpfx = os.path.normpath(util.localpath(prefix))
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    29
    prefix = util.pconvert(lpfx)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    30
    if not prefix.endswith('/'):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    31
        prefix += '/'
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    32
    if prefix.startswith('../') or os.path.isabs(lpfx) or '/../' in prefix:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    33
        raise util.Abort(_('archive prefix contains illegal components'))
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    34
    return prefix
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    35
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    36
class tarit:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    37
    '''write archive to tar file or stream.  can write uncompressed,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    38
    or compress with gzip or bzip2.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    39
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    40
    class GzipFileWithTime(gzip.GzipFile):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    41
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    42
        def __init__(self, *args, **kw):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    43
            timestamp = None
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    44
            if 'timestamp' in kw:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    45
                timestamp = kw.pop('timestamp')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    46
            if timestamp == None:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    47
                self.timestamp = time.time()
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    48
            else:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    49
                self.timestamp = timestamp
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    50
            gzip.GzipFile.__init__(self, *args, **kw)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    51
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    52
        def _write_gzip_header(self):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    53
            self.fileobj.write('\037\213')             # magic header
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    54
            self.fileobj.write('\010')                 # compression method
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    55
            fname = self.filename[:-3]
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    56
            flags = 0
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    57
            if fname:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    58
                flags = gzip.FNAME
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    59
            self.fileobj.write(chr(flags))
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    60
            gzip.write32u(self.fileobj, long(self.timestamp))
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    61
            self.fileobj.write('\002')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    62
            self.fileobj.write('\377')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    63
            if fname:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    64
                self.fileobj.write(fname + '\000')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    65
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
    66
    def __init__(self, dest, prefix, mtime, kind=''):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    67
        self.prefix = tidyprefix(dest, prefix, ['.tar', '.tar.bz2', '.tar.gz',
3615
1d2fdea875bc Fixed directory name having an extra dot on "hg archive -t tbz2 foo.tbz2".
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2856
diff changeset
    68
                                                '.tgz', '.tbz2'])
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
    69
        self.mtime = mtime
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    70
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    71
        def taropen(name, mode, fileobj=None):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    72
            if kind == 'gz':
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    73
                mode = mode[0]
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    74
                if not fileobj:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    75
                    fileobj = open(name, mode)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    76
                gzfileobj = self.GzipFileWithTime(name, mode + 'b',
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    77
                                                  zlib.Z_BEST_COMPRESSION,
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    78
                                                  fileobj, timestamp=mtime)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    79
                return tarfile.TarFile.taropen(name, mode, gzfileobj)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    80
            else:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    81
                return tarfile.open(name, mode + kind, fileobj)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    82
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    83
        if isinstance(dest, str):
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    84
            self.z = taropen(dest, mode='w:')
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    85
        else:
4367
3f1b0c0fb4fd Work around python 2.5.1 tarfile regression
Brendan Cully <brendan@kublai.com>
parents: 3615
diff changeset
    86
            # Python 2.5-2.5.1 have a regression that requires a name arg
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4368
diff changeset
    87
            self.z = taropen(name='', mode='w|', fileobj=dest)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    88
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    89
    def addfile(self, name, mode, data):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    90
        i = tarfile.TarInfo(self.prefix + name)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    91
        i.mtime = self.mtime
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    92
        i.size = len(data)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    93
        i.mode = mode
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    94
        self.z.addfile(i, cStringIO.StringIO(data))
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    95
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    96
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    97
        self.z.close()
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    98
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    99
class tellable:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   100
    '''provide tell method for zipfile.ZipFile when writing to http
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   101
    response file object.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   102
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   103
    def __init__(self, fp):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   104
        self.fp = fp
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   105
        self.offset = 0
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   106
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   107
    def __getattr__(self, key):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   108
        return getattr(self.fp, key)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   109
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   110
    def write(self, s):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   111
        self.fp.write(s)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   112
        self.offset += len(s)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   113
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   114
    def tell(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   115
        return self.offset
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   116
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   117
class zipit:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   118
    '''write archive to zip file or stream.  can write uncompressed,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   119
    or compressed with deflate.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   120
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   121
    def __init__(self, dest, prefix, mtime, compress=True):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   122
        self.prefix = tidyprefix(dest, prefix, ('.zip',))
2168
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   123
        if not isinstance(dest, str):
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   124
            try:
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   125
                dest.tell()
2169
4564794b6f55 Combine catching exceptions added in dd4ec4576cc8 in one except statement.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2168
diff changeset
   126
            except (AttributeError, IOError):
2168
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   127
                dest = tellable(dest)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   128
        self.z = zipfile.ZipFile(dest, 'w',
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   129
                                 compress and zipfile.ZIP_DEFLATED or
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   130
                                 zipfile.ZIP_STORED)
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   131
        self.date_time = time.gmtime(mtime)[:6]
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   132
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   133
    def addfile(self, name, mode, data):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   134
        i = zipfile.ZipInfo(self.prefix + name, self.date_time)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   135
        i.compress_type = self.z.compression
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   136
        i.flag_bits = 0x08
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   137
        # unzip will not honor unix file modes unless file creator is
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   138
        # set to unix (id 3).
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   139
        i.create_system = 3
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   140
        i.external_attr = (mode | stat.S_IFREG) << 16L
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   141
        self.z.writestr(i, data)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   142
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   143
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   144
        self.z.close()
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   145
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   146
class fileit:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   147
    '''write archive as files in directory.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   148
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   149
    def __init__(self, name, prefix, mtime):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   150
        if prefix:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   151
            raise util.Abort(_('cannot give prefix when archiving to files'))
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   152
        self.basedir = name
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   153
        self.dirs = {}
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   154
        self.oflags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY |
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   155
                       getattr(os, 'O_BINARY', 0) |
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   156
                       getattr(os, 'O_NOFOLLOW', 0))
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   157
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   158
    def addfile(self, name, mode, data):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   159
        destfile = os.path.join(self.basedir, name)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   160
        destdir = os.path.dirname(destfile)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   161
        if destdir not in self.dirs:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   162
            if not os.path.isdir(destdir):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   163
                os.makedirs(destdir)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   164
            self.dirs[destdir] = 1
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   165
        os.fdopen(os.open(destfile, self.oflags, mode), 'wb').write(data)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   166
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   167
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   168
        pass
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   169
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   170
archivers = {
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   171
    'files': fileit,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   172
    'tar': tarit,
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   173
    'tbz2': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'bz2'),
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   174
    'tgz': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'gz'),
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   175
    'uzip': lambda name, prefix, mtime: zipit(name, prefix, mtime, False),
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   176
    'zip': zipit,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   177
    }
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   178
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   179
def archive(repo, dest, node, kind, decode=True, matchfn=None,
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   180
            prefix=None, mtime=None):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   181
    '''create archive of repo as it was at node.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   182
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   183
    dest can be name of directory, name of archive file, or file
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   184
    object to write archive to.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   185
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   186
    kind is type of archive to create.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   187
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   188
    decode tells whether to put files through decode filters from
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   189
    hgrc.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   190
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   191
    matchfn is function to filter names of files to write to archive.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   192
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   193
    prefix is name of path to put before every archive member.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   194
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   195
    def write(name, mode, data):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   196
        if matchfn and not matchfn(name): return
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   197
        if decode:
4005
656e06eebda7 replace filehandle version of wwrite with wwritedata
Matt Mackall <mpm@selenic.com>
parents: 3968
diff changeset
   198
            data = repo.wwritedata(name, data)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   199
        archiver.addfile(name, mode, data)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   200
3968
033082ba1d1a archival.py: use contexts
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3893
diff changeset
   201
    ctx = repo.changectx(node)
033082ba1d1a archival.py: use contexts
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3893
diff changeset
   202
    archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0])
033082ba1d1a archival.py: use contexts
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3893
diff changeset
   203
    m = ctx.manifest()
2856
18cf5349a361 Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2852
diff changeset
   204
    items = m.items()
18cf5349a361 Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2852
diff changeset
   205
    items.sort()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   206
    write('.hg_archival.txt', 0644,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   207
          'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node)))
2856
18cf5349a361 Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2852
diff changeset
   208
    for filename, filenode in items:
18cf5349a361 Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2852
diff changeset
   209
        write(filename, m.execf(filename) and 0755 or 0644,
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   210
              repo.file(filename).read(filenode))
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   211
    archiver.done()