Mercurial > hgrepos > Python > apps > py-cutils
view _postprocess-sdist.py @ 384:f66afecac253
treesum: add a generated .treesum file
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 17 May 2025 15:14:30 +0200 |
| parents | c19a21180a8f |
| children |
line wrap: on
line source
# -*- coding: utf-8 -*- # :- # SPDX-FileCopyrightText: © 2025 Franz Glasner # SPDX-License-Identifier: BSD-3-Clause # :- """Postprocress a .tar-sdist to include tests/data with symlinks as symlinks. Produce an sdist with all the data in :file:`tests/data/`:: rm -rf dist py_cutils.egg-info python setup.py sdist python _postprocess-sdist.py gzip dist/*.tar """ from __future__ import print_function, absolute_import try: from configparser import ConfigParser except ImportError: from ConfigParser import SafeConfigParser as ConfigParser import importlib import io import os import tarfile def main(): with io.open("setup.cfg", "rt", encoding="utf-8") as cfgfile: cp = ConfigParser() if hasattr(cp, "read_file"): cp.read_file(cfgfile, "setup.cfg") else: cp.readfp(cfgfile, "setup.cfg") project_name = cp.get("metadata", "name") project_version = cp.get("metadata", "version") if project_version.startswith("attr:"): vermodname, dummy, vermodattr = (project_version[5:] .strip() .rpartition('.')) assert dummy is not None and vermodattr is not None vermod = importlib.import_module(vermodname) project_version = getattr(vermod, vermodattr) elif project_version.startswith("file:"): assert False # # Compressed tar files cannot be modified by Python: make sure the # originally generated archive is uncompressed. # assert cp.get("sdist", "formats") == "tar" archive_name = "{}-{}.tar".format(project_name, project_version) archive_path = "dist/" + archive_name assert os.path.isfile(archive_path) # the directory within the archive archive_path_prefix = "{}-{}".format(project_name, project_version) egg_directory = "{}.egg-info".format(project_name.replace("-", "_")) assert os.path.isdir(egg_directory) sources_txt_path = "{}/SOURCES.txt".format(egg_directory) sources_txt_arcname = "{}/{}/SOURCES.txt".format( archive_path_prefix, egg_directory) with tarfile.TarFile(archive_path, "r") as tf: sf = tf.extractfile(sources_txt_arcname) try: sources_txt = sf.read() finally: sf.close() with tarfile.TarFile(archive_path, "a") as tf: arcname = "{}/tests/data".format(archive_path_prefix) try: info = tf.getmember(arcname) except KeyError: pass else: raise RuntimeError("already postprocessed") pre_names = set(tf.getnames()) tf.add("tests/data", arcname=arcname, recursive=True) # # Determine the new files and symlinks that are to be added # to SOURCES.txt. Skip directories. # post_names = set(tf.getnames()) new_names = list(post_names - pre_names) new_names.sort() new_sources = [] for np in new_names: nn = np[len(archive_path_prefix)+1:] info = tf.getmember(np) if not info.isdir(): new_sources.append(nn) # Augment SOURCES.txt and add it to the archive sources_info = tf.gettarinfo( sources_txt_path, arcname=sources_txt_arcname) sf = io.BytesIO() sf.write(sources_txt) if not sources_txt.endswith(b'\n'): sf.write(b'\n') sf.write(b('\n'.join(new_sources))) sources_info.size = len(sf.getvalue()) sf.seek(0) # # This adds SOURCES.txt a 2nd time: this effectively overwrites # the "earlier" one. # tf.addfile(sources_info, sf) def b(buf, encoding="ascii"): if isinstance(buf, bytes): return buf else: return buf.encode(encoding) if __name__ == "__main__": main()
