~inkscape.dev/inkscape-devlibs64/trunk

« back to all changes in this revision

Viewing changes to python/Lib/distutils/archive_util.py

  • Committer: Eduard Braun
  • Date: 2016-10-22 16:51:19 UTC
  • Revision ID: eduard.braun2@gmx.de-20161022165119-9eosgy6lp8j1kzli
Update Python to version 2.7.12

Included modules:
  coverage 4.2
  lxml 3.6.4
  numpy 1.11.2
  scour 0.35
  six 1.10.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""distutils.archive_util
2
 
 
3
 
Utility functions for creating archive files (tarballs, zip files,
4
 
that sort of thing)."""
5
 
 
6
 
__revision__ = "$Id$"
7
 
 
8
 
import os
9
 
from warnings import warn
10
 
import sys
11
 
 
12
 
from distutils.errors import DistutilsExecError
13
 
from distutils.spawn import spawn
14
 
from distutils.dir_util import mkpath
15
 
from distutils import log
16
 
 
17
 
try:
18
 
    from pwd import getpwnam
19
 
except ImportError:
20
 
    getpwnam = None
21
 
 
22
 
try:
23
 
    from grp import getgrnam
24
 
except ImportError:
25
 
    getgrnam = None
26
 
 
27
 
def _get_gid(name):
28
 
    """Returns a gid, given a group name."""
29
 
    if getgrnam is None or name is None:
30
 
        return None
31
 
    try:
32
 
        result = getgrnam(name)
33
 
    except KeyError:
34
 
        result = None
35
 
    if result is not None:
36
 
        return result[2]
37
 
    return None
38
 
 
39
 
def _get_uid(name):
40
 
    """Returns an uid, given a user name."""
41
 
    if getpwnam is None or name is None:
42
 
        return None
43
 
    try:
44
 
        result = getpwnam(name)
45
 
    except KeyError:
46
 
        result = None
47
 
    if result is not None:
48
 
        return result[2]
49
 
    return None
50
 
 
51
 
def make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
52
 
                 owner=None, group=None):
53
 
    """Create a (possibly compressed) tar file from all the files under
54
 
    'base_dir'.
55
 
 
56
 
    'compress' must be "gzip" (the default), "compress", "bzip2", or None.
57
 
    (compress will be deprecated in Python 3.2)
58
 
 
59
 
    'owner' and 'group' can be used to define an owner and a group for the
60
 
    archive that is being built. If not provided, the current owner and group
61
 
    will be used.
62
 
 
63
 
    The output tar file will be named 'base_dir' +  ".tar", possibly plus
64
 
    the appropriate compression extension (".gz", ".bz2" or ".Z").
65
 
 
66
 
    Returns the output filename.
67
 
    """
68
 
    tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: '', 'compress': ''}
69
 
    compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'compress': '.Z'}
70
 
 
71
 
    # flags for compression program, each element of list will be an argument
72
 
    if compress is not None and compress not in compress_ext.keys():
73
 
        raise ValueError, \
74
 
              ("bad value for 'compress': must be None, 'gzip', 'bzip2' "
75
 
               "or 'compress'")
76
 
 
77
 
    archive_name = base_name + '.tar'
78
 
    if compress != 'compress':
79
 
        archive_name += compress_ext.get(compress, '')
80
 
 
81
 
    mkpath(os.path.dirname(archive_name), dry_run=dry_run)
82
 
 
83
 
    # creating the tarball
84
 
    import tarfile  # late import so Python build itself doesn't break
85
 
 
86
 
    log.info('Creating tar archive')
87
 
 
88
 
    uid = _get_uid(owner)
89
 
    gid = _get_gid(group)
90
 
 
91
 
    def _set_uid_gid(tarinfo):
92
 
        if gid is not None:
93
 
            tarinfo.gid = gid
94
 
            tarinfo.gname = group
95
 
        if uid is not None:
96
 
            tarinfo.uid = uid
97
 
            tarinfo.uname = owner
98
 
        return tarinfo
99
 
 
100
 
    if not dry_run:
101
 
        tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress])
102
 
        try:
103
 
            tar.add(base_dir, filter=_set_uid_gid)
104
 
        finally:
105
 
            tar.close()
106
 
 
107
 
    # compression using `compress`
108
 
    if compress == 'compress':
109
 
        warn("'compress' will be deprecated.", PendingDeprecationWarning)
110
 
        # the option varies depending on the platform
111
 
        compressed_name = archive_name + compress_ext[compress]
112
 
        if sys.platform == 'win32':
113
 
            cmd = [compress, archive_name, compressed_name]
114
 
        else:
115
 
            cmd = [compress, '-f', archive_name]
116
 
        spawn(cmd, dry_run=dry_run)
117
 
        return compressed_name
118
 
 
119
 
    return archive_name
120
 
 
121
 
def make_zipfile(base_name, base_dir, verbose=0, dry_run=0):
122
 
    """Create a zip file from all the files under 'base_dir'.
123
 
 
124
 
    The output zip file will be named 'base_name' + ".zip".  Uses either the
125
 
    "zipfile" Python module (if available) or the InfoZIP "zip" utility
126
 
    (if installed and found on the default search path).  If neither tool is
127
 
    available, raises DistutilsExecError.  Returns the name of the output zip
128
 
    file.
129
 
    """
130
 
    try:
131
 
        import zipfile
132
 
    except ImportError:
133
 
        zipfile = None
134
 
 
135
 
    zip_filename = base_name + ".zip"
136
 
    mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
137
 
 
138
 
    # If zipfile module is not available, try spawning an external
139
 
    # 'zip' command.
140
 
    if zipfile is None:
141
 
        if verbose:
142
 
            zipoptions = "-r"
143
 
        else:
144
 
            zipoptions = "-rq"
145
 
 
146
 
        try:
147
 
            spawn(["zip", zipoptions, zip_filename, base_dir],
148
 
                  dry_run=dry_run)
149
 
        except DistutilsExecError:
150
 
            # XXX really should distinguish between "couldn't find
151
 
            # external 'zip' command" and "zip failed".
152
 
            raise DistutilsExecError, \
153
 
                  ("unable to create zip file '%s': "
154
 
                   "could neither import the 'zipfile' module nor "
155
 
                   "find a standalone zip utility") % zip_filename
156
 
 
157
 
    else:
158
 
        log.info("creating '%s' and adding '%s' to it",
159
 
                 zip_filename, base_dir)
160
 
 
161
 
        if not dry_run:
162
 
            zip = zipfile.ZipFile(zip_filename, "w",
163
 
                                  compression=zipfile.ZIP_DEFLATED)
164
 
 
165
 
            for dirpath, dirnames, filenames in os.walk(base_dir):
166
 
                for name in filenames:
167
 
                    path = os.path.normpath(os.path.join(dirpath, name))
168
 
                    if os.path.isfile(path):
169
 
                        zip.write(path, path)
170
 
                        log.info("adding '%s'" % path)
171
 
            zip.close()
172
 
 
173
 
    return zip_filename
174
 
 
175
 
ARCHIVE_FORMATS = {
176
 
    'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
177
 
    'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"),
178
 
    'ztar':  (make_tarball, [('compress', 'compress')], "compressed tar file"),
179
 
    'tar':   (make_tarball, [('compress', None)], "uncompressed tar file"),
180
 
    'zip':   (make_zipfile, [],"ZIP file")
181
 
    }
182
 
 
183
 
def check_archive_formats(formats):
184
 
    """Returns the first format from the 'format' list that is unknown.
185
 
 
186
 
    If all formats are known, returns None
187
 
    """
188
 
    for format in formats:
189
 
        if format not in ARCHIVE_FORMATS:
190
 
            return format
191
 
    return None
192
 
 
193
 
def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,
194
 
                 dry_run=0, owner=None, group=None):
195
 
    """Create an archive file (eg. zip or tar).
196
 
 
197
 
    'base_name' is the name of the file to create, minus any format-specific
198
 
    extension; 'format' is the archive format: one of "zip", "tar", "ztar",
199
 
    or "gztar".
200
 
 
201
 
    'root_dir' is a directory that will be the root directory of the
202
 
    archive; ie. we typically chdir into 'root_dir' before creating the
203
 
    archive.  'base_dir' is the directory where we start archiving from;
204
 
    ie. 'base_dir' will be the common prefix of all files and
205
 
    directories in the archive.  'root_dir' and 'base_dir' both default
206
 
    to the current directory.  Returns the name of the archive file.
207
 
 
208
 
    'owner' and 'group' are used when creating a tar archive. By default,
209
 
    uses the current owner and group.
210
 
    """
211
 
    save_cwd = os.getcwd()
212
 
    if root_dir is not None:
213
 
        log.debug("changing into '%s'", root_dir)
214
 
        base_name = os.path.abspath(base_name)
215
 
        if not dry_run:
216
 
            os.chdir(root_dir)
217
 
 
218
 
    if base_dir is None:
219
 
        base_dir = os.curdir
220
 
 
221
 
    kwargs = {'dry_run': dry_run}
222
 
 
223
 
    try:
224
 
        format_info = ARCHIVE_FORMATS[format]
225
 
    except KeyError:
226
 
        raise ValueError, "unknown archive format '%s'" % format
227
 
 
228
 
    func = format_info[0]
229
 
    for arg, val in format_info[1]:
230
 
        kwargs[arg] = val
231
 
 
232
 
    if format != 'zip':
233
 
        kwargs['owner'] = owner
234
 
        kwargs['group'] = group
235
 
 
236
 
    try:
237
 
        filename = func(base_name, base_dir, **kwargs)
238
 
    finally:
239
 
        if root_dir is not None:
240
 
            log.debug("changing back to '%s'", save_cwd)
241
 
            os.chdir(save_cwd)
242
 
 
243
 
    return filename
 
1
"""distutils.archive_util
 
2
 
 
3
Utility functions for creating archive files (tarballs, zip files,
 
4
that sort of thing)."""
 
5
 
 
6
__revision__ = "$Id$"
 
7
 
 
8
import os
 
9
from warnings import warn
 
10
import sys
 
11
 
 
12
from distutils.errors import DistutilsExecError
 
13
from distutils.spawn import spawn
 
14
from distutils.dir_util import mkpath
 
15
from distutils import log
 
16
 
 
17
try:
 
18
    from pwd import getpwnam
 
19
except ImportError:
 
20
    getpwnam = None
 
21
 
 
22
try:
 
23
    from grp import getgrnam
 
24
except ImportError:
 
25
    getgrnam = None
 
26
 
 
27
def _get_gid(name):
 
28
    """Returns a gid, given a group name."""
 
29
    if getgrnam is None or name is None:
 
30
        return None
 
31
    try:
 
32
        result = getgrnam(name)
 
33
    except KeyError:
 
34
        result = None
 
35
    if result is not None:
 
36
        return result[2]
 
37
    return None
 
38
 
 
39
def _get_uid(name):
 
40
    """Returns an uid, given a user name."""
 
41
    if getpwnam is None or name is None:
 
42
        return None
 
43
    try:
 
44
        result = getpwnam(name)
 
45
    except KeyError:
 
46
        result = None
 
47
    if result is not None:
 
48
        return result[2]
 
49
    return None
 
50
 
 
51
def make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
 
52
                 owner=None, group=None):
 
53
    """Create a (possibly compressed) tar file from all the files under
 
54
    'base_dir'.
 
55
 
 
56
    'compress' must be "gzip" (the default), "compress", "bzip2", or None.
 
57
    (compress will be deprecated in Python 3.2)
 
58
 
 
59
    'owner' and 'group' can be used to define an owner and a group for the
 
60
    archive that is being built. If not provided, the current owner and group
 
61
    will be used.
 
62
 
 
63
    The output tar file will be named 'base_dir' +  ".tar", possibly plus
 
64
    the appropriate compression extension (".gz", ".bz2" or ".Z").
 
65
 
 
66
    Returns the output filename.
 
67
    """
 
68
    tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: '', 'compress': ''}
 
69
    compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'compress': '.Z'}
 
70
 
 
71
    # flags for compression program, each element of list will be an argument
 
72
    if compress is not None and compress not in compress_ext.keys():
 
73
        raise ValueError, \
 
74
              ("bad value for 'compress': must be None, 'gzip', 'bzip2' "
 
75
               "or 'compress'")
 
76
 
 
77
    archive_name = base_name + '.tar'
 
78
    if compress != 'compress':
 
79
        archive_name += compress_ext.get(compress, '')
 
80
 
 
81
    mkpath(os.path.dirname(archive_name), dry_run=dry_run)
 
82
 
 
83
    # creating the tarball
 
84
    import tarfile  # late import so Python build itself doesn't break
 
85
 
 
86
    log.info('Creating tar archive')
 
87
 
 
88
    uid = _get_uid(owner)
 
89
    gid = _get_gid(group)
 
90
 
 
91
    def _set_uid_gid(tarinfo):
 
92
        if gid is not None:
 
93
            tarinfo.gid = gid
 
94
            tarinfo.gname = group
 
95
        if uid is not None:
 
96
            tarinfo.uid = uid
 
97
            tarinfo.uname = owner
 
98
        return tarinfo
 
99
 
 
100
    if not dry_run:
 
101
        tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress])
 
102
        try:
 
103
            tar.add(base_dir, filter=_set_uid_gid)
 
104
        finally:
 
105
            tar.close()
 
106
 
 
107
    # compression using `compress`
 
108
    if compress == 'compress':
 
109
        warn("'compress' will be deprecated.", PendingDeprecationWarning)
 
110
        # the option varies depending on the platform
 
111
        compressed_name = archive_name + compress_ext[compress]
 
112
        if sys.platform == 'win32':
 
113
            cmd = [compress, archive_name, compressed_name]
 
114
        else:
 
115
            cmd = [compress, '-f', archive_name]
 
116
        spawn(cmd, dry_run=dry_run)
 
117
        return compressed_name
 
118
 
 
119
    return archive_name
 
120
 
 
121
def make_zipfile(base_name, base_dir, verbose=0, dry_run=0):
 
122
    """Create a zip file from all the files under 'base_dir'.
 
123
 
 
124
    The output zip file will be named 'base_name' + ".zip".  Uses either the
 
125
    "zipfile" Python module (if available) or the InfoZIP "zip" utility
 
126
    (if installed and found on the default search path).  If neither tool is
 
127
    available, raises DistutilsExecError.  Returns the name of the output zip
 
128
    file.
 
129
    """
 
130
    try:
 
131
        import zipfile
 
132
    except ImportError:
 
133
        zipfile = None
 
134
 
 
135
    zip_filename = base_name + ".zip"
 
136
    mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
 
137
 
 
138
    # If zipfile module is not available, try spawning an external
 
139
    # 'zip' command.
 
140
    if zipfile is None:
 
141
        if verbose:
 
142
            zipoptions = "-r"
 
143
        else:
 
144
            zipoptions = "-rq"
 
145
 
 
146
        try:
 
147
            spawn(["zip", zipoptions, zip_filename, base_dir],
 
148
                  dry_run=dry_run)
 
149
        except DistutilsExecError:
 
150
            # XXX really should distinguish between "couldn't find
 
151
            # external 'zip' command" and "zip failed".
 
152
            raise DistutilsExecError, \
 
153
                  ("unable to create zip file '%s': "
 
154
                   "could neither import the 'zipfile' module nor "
 
155
                   "find a standalone zip utility") % zip_filename
 
156
 
 
157
    else:
 
158
        log.info("creating '%s' and adding '%s' to it",
 
159
                 zip_filename, base_dir)
 
160
 
 
161
        if not dry_run:
 
162
            zip = zipfile.ZipFile(zip_filename, "w",
 
163
                                  compression=zipfile.ZIP_DEFLATED)
 
164
 
 
165
            for dirpath, dirnames, filenames in os.walk(base_dir):
 
166
                for name in filenames:
 
167
                    path = os.path.normpath(os.path.join(dirpath, name))
 
168
                    if os.path.isfile(path):
 
169
                        zip.write(path, path)
 
170
                        log.info("adding '%s'" % path)
 
171
            zip.close()
 
172
 
 
173
    return zip_filename
 
174
 
 
175
ARCHIVE_FORMATS = {
 
176
    'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
 
177
    'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"),
 
178
    'ztar':  (make_tarball, [('compress', 'compress')], "compressed tar file"),
 
179
    'tar':   (make_tarball, [('compress', None)], "uncompressed tar file"),
 
180
    'zip':   (make_zipfile, [],"ZIP file")
 
181
    }
 
182
 
 
183
def check_archive_formats(formats):
 
184
    """Returns the first format from the 'format' list that is unknown.
 
185
 
 
186
    If all formats are known, returns None
 
187
    """
 
188
    for format in formats:
 
189
        if format not in ARCHIVE_FORMATS:
 
190
            return format
 
191
    return None
 
192
 
 
193
def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,
 
194
                 dry_run=0, owner=None, group=None):
 
195
    """Create an archive file (eg. zip or tar).
 
196
 
 
197
    'base_name' is the name of the file to create, minus any format-specific
 
198
    extension; 'format' is the archive format: one of "zip", "tar", "ztar",
 
199
    or "gztar".
 
200
 
 
201
    'root_dir' is a directory that will be the root directory of the
 
202
    archive; ie. we typically chdir into 'root_dir' before creating the
 
203
    archive.  'base_dir' is the directory where we start archiving from;
 
204
    ie. 'base_dir' will be the common prefix of all files and
 
205
    directories in the archive.  'root_dir' and 'base_dir' both default
 
206
    to the current directory.  Returns the name of the archive file.
 
207
 
 
208
    'owner' and 'group' are used when creating a tar archive. By default,
 
209
    uses the current owner and group.
 
210
    """
 
211
    save_cwd = os.getcwd()
 
212
    if root_dir is not None:
 
213
        log.debug("changing into '%s'", root_dir)
 
214
        base_name = os.path.abspath(base_name)
 
215
        if not dry_run:
 
216
            os.chdir(root_dir)
 
217
 
 
218
    if base_dir is None:
 
219
        base_dir = os.curdir
 
220
 
 
221
    kwargs = {'dry_run': dry_run}
 
222
 
 
223
    try:
 
224
        format_info = ARCHIVE_FORMATS[format]
 
225
    except KeyError:
 
226
        raise ValueError, "unknown archive format '%s'" % format
 
227
 
 
228
    func = format_info[0]
 
229
    for arg, val in format_info[1]:
 
230
        kwargs[arg] = val
 
231
 
 
232
    if format != 'zip':
 
233
        kwargs['owner'] = owner
 
234
        kwargs['group'] = group
 
235
 
 
236
    try:
 
237
        filename = func(base_name, base_dir, **kwargs)
 
238
    finally:
 
239
        if root_dir is not None:
 
240
            log.debug("changing back to '%s'", save_cwd)
 
241
            os.chdir(save_cwd)
 
242
 
 
243
    return filename