| OLD | NEW |
| 1 """Create the PEP 376-compliant .dist-info directory.""" | 1 """Create the PEP 376-compliant .dist-info directory.""" |
| 2 | 2 |
| 3 # Forked from the former install_egg_info command by Josip Djolonga | 3 # Forked from the former install_egg_info command by Josip Djolonga |
| 4 | 4 |
| 5 import os | 5 import os |
| 6 import csv | 6 import csv |
| 7 import hashlib | 7 import hashlib |
| 8 from shutil import rmtree | 8 from shutil import rmtree |
| 9 | 9 |
| 10 from packaging import logger | 10 from packaging import logger |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 ('no-resources', None, | 29 ('no-resources', None, |
| 30 "do not generate a RESOURCES file"), | 30 "do not generate a RESOURCES file"), |
| 31 ] | 31 ] |
| 32 | 32 |
| 33 boolean_options = ['requested', 'no-record', 'no-resources'] | 33 boolean_options = ['requested', 'no-record', 'no-resources'] |
| 34 | 34 |
| 35 negative_opt = {'no-requested': 'requested'} | 35 negative_opt = {'no-requested': 'requested'} |
| 36 | 36 |
| 37 def initialize_options(self): | 37 def initialize_options(self): |
| 38 self.install_dir = None | 38 self.install_dir = None |
| 39 self.install_base = None |
| 39 self.installer = None | 40 self.installer = None |
| 40 self.requested = None | 41 self.requested = None |
| 41 self.no_record = None | 42 self.no_record = None |
| 42 self.no_resources = None | 43 self.no_resources = None |
| 43 self.outfiles = [] | 44 self.outfiles = [] |
| 44 | 45 |
| 45 def finalize_options(self): | 46 def finalize_options(self): |
| 46 self.set_undefined_options('install_dist', | 47 self.set_undefined_options('install_dist', |
| 47 'installer', 'requested', 'no_record') | 48 'installer', 'requested', 'no_record', 'insta
ll_base') |
| 48 | 49 |
| 49 self.set_undefined_options('install_lib', 'install_dir') | 50 self.set_undefined_options('install_lib', 'install_dir') |
| 50 | 51 |
| 51 if self.installer is None: | 52 if self.installer is None: |
| 52 # FIXME distutils or packaging? | 53 # FIXME distutils or packaging? |
| 53 # + document default in the option help text above and in install | 54 # + document default in the option help text above and in install |
| 54 self.installer = 'distutils' | 55 self.installer = 'distutils' |
| 55 if self.requested is None: | 56 if self.requested is None: |
| 56 self.requested = True | 57 self.requested = True |
| 57 if self.no_record is None: | 58 if self.no_record is None: |
| 58 self.no_record = False | 59 self.no_record = False |
| 59 if self.no_resources is None: | 60 if self.no_resources is None: |
| 60 self.no_resources = False | 61 self.no_resources = False |
| 61 | 62 |
| 62 metadata = self.distribution.metadata | 63 metadata = self.distribution.metadata |
| 63 | 64 |
| 64 basename = metadata.get_fullname(filesafe=True) + ".dist-info" | 65 basename = metadata.get_fullname(filesafe=True) + ".dist-info" |
| 65 | 66 |
| 66 self.install_dir = os.path.join(self.install_dir, basename) | 67 self.distinfo_dir = os.path.join(self.install_dir, basename) |
| 67 | 68 |
| 69 @staticmethod |
| 70 def pep376path(fpath, install_base, install_dir): |
| 71 """Return PEP-376 path (but always with platform path separators)"""
|
| 72 if install_base is None: # needed for unit tests |
| 73 return install_dir |
| 74 # install_base is 'prefix' from PEP-376 |
| 75 install_base = install_base.rstrip(os.path.sep) + os.path.sep |
| 76 # install_dir is 'base location' from PEP-376 |
| 77 install_dir = install_dir.rstrip(os.path.sep) + os.path.sep
|
| 78 install_dir_in_base = install_dir.startswith(install_base) |
| 79 if fpath.startswith(install_dir) or \ |
| 80 fpath.startswith(install_base) and install_dir_in_base: |
| 81 rpath = os.path.relpath(fpath, install_dir) |
| 82 else: |
| 83 rpath = os.path.abspath(fpath) |
| 84 return rpath |
| 85 |
| 68 def run(self): | 86 def run(self): |
| 69 target = self.install_dir | 87 target = self.distinfo_dir |
| 70 | 88 |
| 71 if os.path.isdir(target) and not os.path.islink(target): | 89 if os.path.isdir(target) and not os.path.islink(target): |
| 72 if not self.dry_run: | 90 if not self.dry_run: |
| 73 rmtree(target) | 91 rmtree(target) |
| 74 elif os.path.exists(target): | 92 elif os.path.exists(target): |
| 75 self.execute(os.unlink, (self.install_dir,), | 93 self.execute(os.unlink, (self.distinfo_dir,), |
| 76 "removing " + target) | 94 "removing " + target) |
| 77 | 95 |
| 78 self.execute(os.makedirs, (target,), "creating " + target) | 96 self.execute(os.makedirs, (target,), "creating " + target) |
| 97 |
| 98 if not self.dry_run: |
| 99 install_data = self.get_finalized_command('install_data') |
| 100 while install_data.extra_dist_info: |
| 101 install_data.extra_dist_info.pop()() |
| 79 | 102 |
| 80 metadata_path = os.path.join(self.install_dir, 'METADATA') | 103 metadata_path = os.path.join(self.distinfo_dir, 'METADATA') |
| 81 self.execute(self.distribution.metadata.write, (metadata_path,), | 104 self.execute(self.distribution.metadata.write, (metadata_path,), |
| 82 "creating " + metadata_path) | 105 "creating " + metadata_path) |
| 83 self.outfiles.append(metadata_path) | 106 self.outfiles.append(metadata_path) |
| 84 | 107 |
| 85 installer_path = os.path.join(self.install_dir, 'INSTALLER') | 108 installer_path = os.path.join(self.distinfo_dir, 'INSTALLER') |
| 86 logger.info('creating %s', installer_path) | 109 logger.info('creating %s', installer_path) |
| 87 if not self.dry_run: | 110 if not self.dry_run: |
| 88 with open(installer_path, 'w') as f: | 111 with open(installer_path, 'w') as f: |
| 89 f.write(self.installer) | 112 f.write(self.installer) |
| 90 self.outfiles.append(installer_path) | 113 self.outfiles.append(installer_path) |
| 91 | 114 |
| 92 if self.requested: | 115 if self.requested: |
| 93 requested_path = os.path.join(self.install_dir, 'REQUESTED') | 116 requested_path = os.path.join(self.distinfo_dir, 'REQUESTED') |
| 94 logger.info('creating %s', requested_path) | 117 logger.info('creating %s', requested_path) |
| 95 if not self.dry_run: | 118 if not self.dry_run: |
| 96 open(requested_path, 'wb').close() | 119 open(requested_path, 'wb').close() |
| 97 self.outfiles.append(requested_path) | 120 self.outfiles.append(requested_path) |
| 98 | 121 |
| 99 if not self.no_resources: | 122 if not self.no_resources: |
| 100 install_data = self.get_finalized_command('install_data') | 123 install_data = self.get_finalized_command('install_data') |
| 101 if install_data.get_resources_out() != []: | 124 if install_data.get_resources_out() != []: |
| 102 resources_path = os.path.join(self.install_dir, | 125 resources_path = os.path.join(self.distinfo_dir, |
| 103 'RESOURCES') | 126 'RESOURCES') |
| 104 logger.info('creating %s', resources_path) | 127 logger.info('creating %s', resources_path) |
| 105 if not self.dry_run: | 128 if not self.dry_run: |
| 106 with open(resources_path, 'w') as f: | 129 with open(resources_path, 'w') as f: |
| 107 writer = csv.writer(f, delimiter=',', | 130 writer = csv.writer(f, delimiter=',', |
| 108 lineterminator='\n', | 131 lineterminator='\n', |
| 109 quotechar='"') | 132 quotechar='"') |
| 110 for row in install_data.get_resources_out(): | 133 for row in install_data.get_resources_out(): |
| 111 writer.writerow(row) | 134 writer.writerow(row) |
| 112 | 135 |
| 113 self.outfiles.append(resources_path) | 136 self.outfiles.append(resources_path) |
| 114 | 137 |
| 115 if not self.no_record: | 138 if not self.no_record: |
| 116 record_path = os.path.join(self.install_dir, 'RECORD') | 139 record_path = os.path.join(self.distinfo_dir, 'RECORD') |
| 117 logger.info('creating %s', record_path) | 140 logger.info('creating %s', record_path) |
| 118 if not self.dry_run: | 141 if not self.dry_run: |
| 119 with open(record_path, 'w', encoding='utf-8') as f: | 142 with open(record_path, 'w', encoding='utf-8') as f: |
| 120 writer = csv.writer(f, delimiter=',', | 143 writer = csv.writer(f, delimiter=',', |
| 121 lineterminator='\n', | 144 lineterminator='\n', |
| 122 quotechar='"') | 145 quotechar='"') |
| 123 | 146 |
| 124 install = self.get_finalized_command('install_dist') | 147 install = self.get_finalized_command('install_dist')
|
| 125 | 148 |
| 126 for fpath in install.get_outputs(): | 149 for fpath in install.get_outputs(): |
| 150 rpath = self.pep376path(fpath, self.install_base, self.i
nstall_dir) |
| 127 if fpath.endswith('.pyc') or fpath.endswith('.pyo'): | 151 if fpath.endswith('.pyc') or fpath.endswith('.pyo'): |
| 128 # do not put size and md5 hash, as in PEP-376 | 152 # do not put size and md5 hash, as in PEP-376 |
| 129 writer.writerow((fpath, '', '')) | 153 writer.writerow((rpath, '', '')) |
| 130 else: | 154 else: |
| 131 size = os.path.getsize(fpath) | 155 size = os.path.getsize(fpath) |
| 132 with open(fpath, 'rb') as fp: | 156 with open(fpath, 'rb') as fp: |
| 133 hash = hashlib.md5() | 157 hash = hashlib.md5() |
| 134 hash.update(fp.read()) | 158 hash.update(fp.read()) |
| 135 md5sum = hash.hexdigest() | 159 md5sum = hash.hexdigest() |
| 136 writer.writerow((fpath, md5sum, size)) | 160 writer.writerow((rpath, md5sum, size)) |
| 137 | 161 |
| 138 # add the RECORD file itself | 162 # add the RECORD file itself |
| 139 writer.writerow((record_path, '', '')) | 163 writer.writerow((self.pep376path(record_path, self.install_b
ase, self.install_dir), '', '')) |
| 140 self.outfiles.append(record_path) | 164 self.outfiles.append(record_path) |
| 141 | 165 |
| 142 def get_outputs(self): | 166 def get_outputs(self): |
| 143 return self.outfiles | 167 return self.outfiles |
| OLD | NEW |