Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion flit_core/flit_core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def prep_toml_config(d, path):
)
exclude = [
"**/__pycache__",
"**.pyc",
"**/*.pyc",
] + dtool['sdist'].get('exclude', [])
loaded_cfg.sdist_exclude_patterns = _check_glob_patterns(
exclude, 'exclude'
Expand Down
13 changes: 11 additions & 2 deletions flit_core/flit_core/sdist.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from collections import defaultdict
from copy import copy
from glob import glob
from gzip import GzipFile
import io
import logging
import os
import os.path as osp
from pathlib import Path
from posixpath import join as pjoin
import re
import tarfile

from . import common
Expand Down Expand Up @@ -42,8 +42,17 @@ def __init__(self, patterns, basedir):
self.dirs = set()
self.files = set()

base_path = Path(basedir)
for pattern in patterns:
for path in sorted(glob(osp.join(basedir, pattern), recursive=True)):
norm_pattern = pattern.lstrip('/\\')
norm_pattern = re.sub(r'(^|[/\\])\*\*([a-zA-Z0-9_.*]+)', r'\g<1>**/*\2', norm_pattern)
parts = []
for part in norm_pattern.replace('\\', '/').split('/'):
if '**' in part and part != '**':
part = part.replace('**', '*')
parts.append(part)
norm_pattern = '/'.join(parts)
for path in sorted(base_path.glob(norm_pattern)):
rel = osp.relpath(path, basedir)
if osp.isdir(path):
self.dirs.add(rel)
Expand Down
46 changes: 46 additions & 0 deletions flit_core/tests_core/test_sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,49 @@ def test_license_inside_src(tmp_path):
)

assert lic_count == 1


def test_recursive_glob_dotfiles(tmp_path):
(tmp_path / 'pkg').mkdir()
(tmp_path / 'pkg' / '__init__.py').write_text('"""A sample package"""\n__version__ = "0.1"\n')
(tmp_path / 'pkg' / 'sub').mkdir()
(tmp_path / 'pkg' / 'sub' / '.hidden.swp').write_text('swap')
(tmp_path / 'pkg' / '.root.swp').write_text('swap')
(tmp_path / 'pkg' / 'normal.txt').write_text('normal')

patterns = sdist.FilePatterns(['**/*.swp'], str(tmp_path))
assert patterns.match_file(osp.join('pkg', '.root.swp'))
assert patterns.match_file(osp.join('pkg', 'sub', '.hidden.swp'))
assert not patterns.match_file(osp.join('pkg', 'normal.txt'))


def test_sdist_exclude_dotfiles(tmp_path):
pkg_dir = tmp_path / 'pkg'
pkg_dir.mkdir()
(pkg_dir / '__init__.py').write_text('"""A sample package"""\n__version__ = "0.1"\n')
(pkg_dir / 'sub').mkdir()
(pkg_dir / 'sub' / '.editor.swp').write_text('swap')
(pkg_dir / '.main.swp').write_text('swap')
(pkg_dir / 'module.py').write_text('x = 1\n')

pyproject = tmp_path / 'pyproject.toml'
pyproject.write_text("""
[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"

[project]
name = "pkg"
authors = [{name = "Test"}]
dynamic = ["version", "description"]

[tool.flit.sdist]
exclude = ["**/*.swp"]
""")

builder = sdist.SdistBuilder.from_ini_path(pyproject)
files = builder.apply_includes_excludes(builder.select_files())

assert osp.join('pkg', '.main.swp') not in files
assert osp.join('pkg', 'sub', '.editor.swp') not in files
assert osp.join('pkg', 'module.py') in files