Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
sdist.py219 linesDownload Raw Back to command
1from __future__ import annotations2 3import contextlib4import os5import re6from collections.abc import Iterator7from itertools import chain8from typing import ClassVar9 10from .._importlib import metadata11from ..dist import Distribution12from .build import _ORIGINAL_SUBCOMMANDS13 14import distutils.command.sdist as orig15from distutils import log16 17_default_revctrl = list18 19 20def walk_revctrl(dirname='') -> Iterator:21    """Find all files under revision control"""22    for ep in metadata.entry_points(group='setuptools.file_finders'):23        yield from ep.load()(dirname)24 25 26class sdist(orig.sdist):27    """Smart sdist that finds anything supported by revision control"""28 29    user_options = [30        ('formats=', None, "formats for source distribution (comma-separated list)"),31        (32            'keep-temp',33            'k',34            "keep the distribution tree around after creating archive file(s)",35        ),36        (37            'dist-dir=',38            'd',39            "directory to put the source distribution archive(s) in [default: dist]",40        ),41        (42            'owner=',43            'u',44            "Owner name used when creating a tar file [default: current user]",45        ),46        (47            'group=',48            'g',49            "Group name used when creating a tar file [default: current group]",50        ),51    ]52 53    distribution: Distribution  # override distutils.dist.Distribution with setuptools.dist.Distribution54    negative_opt: ClassVar[dict[str, str]] = {}55 56    README_EXTENSIONS = ['', '.rst', '.txt', '.md']57    READMES = tuple(f'README{ext}' for ext in README_EXTENSIONS)58 59    def run(self) -> None:60        self.run_command('egg_info')61        ei_cmd = self.get_finalized_command('egg_info')62        self.filelist = ei_cmd.filelist63        self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))64        self.check_readme()65 66        # Run sub commands67        for cmd_name in self.get_sub_commands():68            self.run_command(cmd_name)69 70        self.make_distribution()71 72        dist_files = getattr(self.distribution, 'dist_files', [])73        for file in self.archive_files:74            data = ('sdist', '', file)75            if data not in dist_files:76                dist_files.append(data)77 78    def initialize_options(self) -> None:79        orig.sdist.initialize_options(self)80 81    def make_distribution(self) -> None:82        """83        Workaround for #51684        """85        with self._remove_os_link():86            orig.sdist.make_distribution(self)87 88    @staticmethod89    @contextlib.contextmanager90    def _remove_os_link():91        """92        In a context, remove and restore os.link if it exists93        """94 95        class NoValue:96            pass97 98        orig_val = getattr(os, 'link', NoValue)99        try:100            del os.link101        except Exception:102            pass103        try:104            yield105        finally:106            if orig_val is not NoValue:107                os.link = orig_val108 109    def add_defaults(self) -> None:110        super().add_defaults()111        self._add_defaults_build_sub_commands()112 113    def _add_defaults_optional(self):114        super()._add_defaults_optional()115        if os.path.isfile('pyproject.toml'):116            self.filelist.append('pyproject.toml')117 118    def _add_defaults_python(self):119        """getting python files"""120        if self.distribution.has_pure_modules():121            build_py = self.get_finalized_command('build_py')122            self.filelist.extend(build_py.get_source_files())123            self._add_data_files(self._safe_data_files(build_py))124 125    def _add_defaults_build_sub_commands(self):126        build = self.get_finalized_command("build")127        missing_cmds = set(build.get_sub_commands()) - _ORIGINAL_SUBCOMMANDS128        # ^-- the original built-in sub-commands are already handled by default.129        cmds = (self.get_finalized_command(c) for c in missing_cmds)130        files = (c.get_source_files() for c in cmds if hasattr(c, "get_source_files"))131        self.filelist.extend(chain.from_iterable(files))132 133    def _safe_data_files(self, build_py):134        """135        Since the ``sdist`` class is also used to compute the MANIFEST136        (via :obj:`setuptools.command.egg_info.manifest_maker`),137        there might be recursion problems when trying to obtain the list of138        data_files and ``include_package_data=True`` (which in turn depends on139        the files included in the MANIFEST).140 141        To avoid that, ``manifest_maker`` should be able to overwrite this142        method and avoid recursive attempts to build/analyze the MANIFEST.143        """144        return build_py.data_files145 146    def _add_data_files(self, data_files):147        """148        Add data files as found in build_py.data_files.149        """150        self.filelist.extend(151            os.path.join(src_dir, name)152            for _, src_dir, _, filenames in data_files153            for name in filenames154        )155 156    def _add_defaults_data_files(self):157        try:158            super()._add_defaults_data_files()159        except TypeError:160            log.warn("data_files contains unexpected objects")161 162    def prune_file_list(self) -> None:163        super().prune_file_list()164        # Prevent accidental inclusion of test-related cache dirs at the project root165        sep = re.escape(os.sep)166        self.filelist.exclude_pattern(r"^(\.tox|\.nox|\.venv)" + sep, is_regex=True)167 168    def check_readme(self) -> None:169        for f in self.READMES:170            if os.path.exists(f):171                return172        else:173            self.warn(174                "standard file not found: should have one of " + ', '.join(self.READMES)175            )176 177    def make_release_tree(self, base_dir, files) -> None:178        orig.sdist.make_release_tree(self, base_dir, files)179 180        # Save any egg_info command line options used to create this sdist181        dest = os.path.join(base_dir, 'setup.cfg')182        if hasattr(os, 'link') and os.path.exists(dest):183            # unlink and re-copy, since it might be hard-linked, and184            # we don't want to change the source version185            os.unlink(dest)186            self.copy_file('setup.cfg', dest)187 188        self.get_finalized_command('egg_info').save_version_info(dest)189 190    def _manifest_is_not_generated(self):191        # check for special comment used in 2.7.1 and higher192        if not os.path.isfile(self.manifest):193            return False194 195        with open(self.manifest, 'rb') as fp:196            first_line = fp.readline()197        return first_line != b'# file GENERATED by distutils, do NOT edit\n'198 199    def read_manifest(self) -> None:200        """Read the manifest file (named by 'self.manifest') and use it to201        fill in 'self.filelist', the list of files to include in the source202        distribution.203        """204        log.info("reading manifest file '%s'", self.manifest)205        manifest = open(self.manifest, 'rb')206        for bytes_line in manifest:207            # The manifest must contain UTF-8. See #303.208            try:209                line = bytes_line.decode('UTF-8')210            except UnicodeDecodeError:211                log.warn(f"{line!r} not UTF-8 decodable -- skipping")212                continue213            # ignore comments and blank lines214            line = line.strip()215            if line.startswith('#') or not line:216                continue217            self.filelist.append(line)218        manifest.close()219 
codekingpro/portable-devtools · Team Ai