sdist.py (11400B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\command\sdist.py 2 __revision__ = '$Id: sdist.py 87602 2011-01-01 04:24:26Z richard.tew $' 3 import os 4 import string 5 import sys 6 from glob import glob 7 from warnings import warn 8 from distutils.core import Command 9 from distutils import dir_util, dep_util, file_util, archive_util 10 from distutils.text_file import TextFile 11 from distutils.errors import DistutilsPlatformError, DistutilsOptionError, DistutilsTemplateError 12 from distutils.filelist import FileList 13 from distutils import log 14 from distutils.util import convert_path 15 16 def show_formats(): 17 from distutils.fancy_getopt import FancyGetopt 18 from distutils.archive_util import ARCHIVE_FORMATS 19 formats = [] 20 for format in ARCHIVE_FORMATS.keys(): 21 formats.append(('formats=' + format, None, ARCHIVE_FORMATS[format][2])) 22 23 formats.sort() 24 FancyGetopt(formats).print_help('List of available source distribution formats:') 25 26 27 class sdist(Command): 28 description = 'create a source distribution (tarball, zip file, etc.)' 29 30 def checking_metadata(self): 31 return self.metadata_check 32 33 user_options = [('template=', 't', 'name of manifest template file [default: MANIFEST.in]'), 34 ('manifest=', 'm', 'name of manifest file [default: MANIFEST]'), 35 ('use-defaults', None, 'include the default file set in the manifest [default; disable with --no-defaults]'), 36 ('no-defaults', None, "don't include the default file set"), 37 ('prune', None, 'specifically exclude files/directories that should not be distributed (build tree, RCS/CVS dirs, etc.) [default; disable with --no-prune]'), 38 ('no-prune', None, "don't automatically exclude anything"), 39 ('manifest-only', 'o', 'just regenerate the manifest and then stop (implies --force-manifest)'), 40 ('force-manifest', 'f', 'forcibly regenerate the manifest and carry on as usual. Deprecated: now the manifest is always regenerated.'), 41 ('formats=', None, 'formats for source distribution (comma-separated list)'), 42 ('keep-temp', 'k', 'keep the distribution tree around after creating ' + 'archive file(s)'), 43 ('dist-dir=', 'd', 'directory to put the source distribution archive(s) in [default: dist]'), 44 ('metadata-check', None, 'Ensure that all required elements of meta-data are supplied. Warn if any missing. [default]'), 45 ('owner=', 'u', 'Owner name used when creating a tar file [default: current user]'), 46 ('group=', 'g', 'Group name used when creating a tar file [default: current group]')] 47 boolean_options = ['use-defaults', 48 'prune', 49 'manifest-only', 50 'force-manifest', 51 'keep-temp', 52 'metadata-check'] 53 help_options = [('help-formats', 54 None, 55 'list available distribution formats', 56 show_formats)] 57 negative_opt = {'no-defaults': 'use-defaults', 58 'no-prune': 'prune'} 59 default_format = {'posix': 'gztar', 60 'nt': 'zip'} 61 sub_commands = [('check', checking_metadata)] 62 63 def initialize_options(self): 64 self.template = None 65 self.manifest = None 66 self.use_defaults = 1 67 self.prune = 1 68 self.manifest_only = 0 69 self.force_manifest = 0 70 self.formats = None 71 self.keep_temp = 0 72 self.dist_dir = None 73 self.archive_files = None 74 self.metadata_check = 1 75 self.owner = None 76 self.group = None 77 78 def finalize_options(self): 79 if self.manifest is None: 80 self.manifest = 'MANIFEST' 81 if self.template is None: 82 self.template = 'MANIFEST.in' 83 self.ensure_string_list('formats') 84 if self.formats is None: 85 try: 86 self.formats = [self.default_format[os.name]] 87 except KeyError: 88 raise DistutilsPlatformError, "don't know how to create source distributions " + 'on platform %s' % os.name 89 90 bad_format = archive_util.check_archive_formats(self.formats) 91 if bad_format: 92 raise DistutilsOptionError, "unknown archive format '%s'" % bad_format 93 if self.dist_dir is None: 94 self.dist_dir = 'dist' 95 96 def run(self): 97 self.filelist = FileList() 98 for cmd_name in self.get_sub_commands(): 99 self.run_command(cmd_name) 100 101 self.get_file_list() 102 if self.manifest_only: 103 return 104 self.make_distribution() 105 106 def check_metadata(self): 107 warn('distutils.command.sdist.check_metadata is deprecated, use the check command instead', PendingDeprecationWarning) 108 check = self.distribution.get_command_obj('check') 109 check.ensure_finalized() 110 check.run() 111 112 def get_file_list(self): 113 template_exists = os.path.isfile(self.template) 114 if not template_exists: 115 self.warn(("manifest template '%s' does not exist " + '(using default file list)') % self.template) 116 self.filelist.findall() 117 if self.use_defaults: 118 self.add_defaults() 119 if template_exists: 120 self.read_template() 121 if self.prune: 122 self.prune_file_list() 123 self.filelist.sort() 124 self.filelist.remove_duplicates() 125 self.write_manifest() 126 127 def add_defaults(self): 128 standards = [('README', 'README.txt'), self.distribution.script_name] 129 for fn in standards: 130 if isinstance(fn, tuple): 131 alts = fn 132 got_it = 0 133 for fn in alts: 134 if os.path.exists(fn): 135 got_it = 1 136 self.filelist.append(fn) 137 break 138 139 if not got_it: 140 self.warn('standard file not found: should have one of ' + string.join(alts, ', ')) 141 elif os.path.exists(fn): 142 self.filelist.append(fn) 143 else: 144 self.warn("standard file '%s' not found" % fn) 145 146 optional = ['test/test*.py', 'setup.cfg'] 147 for pattern in optional: 148 files = filter(os.path.isfile, glob(pattern)) 149 if files: 150 self.filelist.extend(files) 151 152 build_py = self.get_finalized_command('build_py') 153 if self.distribution.has_pure_modules(): 154 self.filelist.extend(build_py.get_source_files()) 155 for pkg, src_dir, build_dir, filenames in build_py.data_files: 156 for filename in filenames: 157 self.filelist.append(os.path.join(src_dir, filename)) 158 159 if self.distribution.has_data_files(): 160 for item in self.distribution.data_files: 161 if isinstance(item, str): 162 item = convert_path(item) 163 if os.path.isfile(item): 164 self.filelist.append(item) 165 else: 166 dirname, filenames = item 167 for f in filenames: 168 f = convert_path(f) 169 if os.path.isfile(f): 170 self.filelist.append(f) 171 172 if self.distribution.has_ext_modules(): 173 build_ext = self.get_finalized_command('build_ext') 174 self.filelist.extend(build_ext.get_source_files()) 175 if self.distribution.has_c_libraries(): 176 build_clib = self.get_finalized_command('build_clib') 177 self.filelist.extend(build_clib.get_source_files()) 178 if self.distribution.has_scripts(): 179 build_scripts = self.get_finalized_command('build_scripts') 180 self.filelist.extend(build_scripts.get_source_files()) 181 182 def read_template(self): 183 log.info("reading manifest template '%s'", self.template) 184 template = TextFile(self.template, strip_comments=1, skip_blanks=1, join_lines=1, lstrip_ws=1, rstrip_ws=1, collapse_join=1) 185 while 1: 186 line = template.readline() 187 if line is None: 188 break 189 try: 190 self.filelist.process_template_line(line) 191 except DistutilsTemplateError as msg: 192 self.warn('%s, line %d: %s' % (template.filename, template.current_line, msg)) 193 194 def prune_file_list(self): 195 build = self.get_finalized_command('build') 196 base_dir = self.distribution.get_fullname() 197 self.filelist.exclude_pattern(None, prefix=build.build_base) 198 self.filelist.exclude_pattern(None, prefix=base_dir) 199 if sys.platform == 'win32': 200 seps = '/|\\\\' 201 else: 202 seps = '/' 203 vcs_dirs = ['RCS', 204 'CVS', 205 '\\.svn', 206 '\\.hg', 207 '\\.git', 208 '\\.bzr', 209 '_darcs'] 210 vcs_ptrn = '(^|%s)(%s)(%s).*' % (seps, '|'.join(vcs_dirs), seps) 211 self.filelist.exclude_pattern(vcs_ptrn, is_regex=1) 212 213 def write_manifest(self): 214 if os.path.isfile(self.manifest): 215 fp = open(self.manifest) 216 try: 217 first_line = fp.readline() 218 finally: 219 fp.close() 220 221 if first_line != '# file GENERATED by distutils, do NOT edit\n': 222 log.info("not writing to manually maintained manifest file '%s'" % self.manifest) 223 return 224 content = self.filelist.files[:] 225 content.insert(0, '# file GENERATED by distutils, do NOT edit') 226 self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) 227 228 def read_manifest(self): 229 log.info("reading manifest file '%s'", self.manifest) 230 manifest = open(self.manifest) 231 while 1: 232 line = manifest.readline() 233 if line == '': 234 break 235 if line[-1] == '\n': 236 line = line[0:-1] 237 self.filelist.append(line) 238 239 manifest.close() 240 241 def make_release_tree(self, base_dir, files): 242 self.mkpath(base_dir) 243 dir_util.create_tree(base_dir, files, dry_run=self.dry_run) 244 if hasattr(os, 'link'): 245 link = 'hard' 246 msg = 'making hard links in %s...' % base_dir 247 else: 248 link = None 249 msg = 'copying files to %s...' % base_dir 250 if not files: 251 log.warn('no files to distribute -- empty manifest?') 252 else: 253 log.info(msg) 254 for file in files: 255 if not os.path.isfile(file): 256 log.warn("'%s' not a regular file -- skipping" % file) 257 else: 258 dest = os.path.join(base_dir, file) 259 self.copy_file(file, dest, link=link) 260 261 self.distribution.metadata.write_pkg_info(base_dir) 262 263 def make_distribution(self): 264 base_dir = self.distribution.get_fullname() 265 base_name = os.path.join(self.dist_dir, base_dir) 266 self.make_release_tree(base_dir, self.filelist.files) 267 archive_files = [] 268 if 'tar' in self.formats: 269 self.formats.append(self.formats.pop(self.formats.index('tar'))) 270 for fmt in self.formats: 271 file = self.make_archive(base_name, fmt, base_dir=base_dir, owner=self.owner, group=self.group) 272 archive_files.append(file) 273 self.distribution.dist_files.append(('sdist', '', file)) 274 275 self.archive_files = archive_files 276 if not self.keep_temp: 277 dir_util.remove_tree(base_dir, dry_run=self.dry_run) 278 279 def get_archive_files(self): 280 return self.archive_files