From 1df849f5233df418b23a9c015d3c0184f8a8710c Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Thu, 30 Sep 2021 01:34:45 -0500 Subject: [PATCH 01/12] test: list actual files in test dir --- tests/test_build.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 59dd90e7..aa799a0c 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -13,10 +13,14 @@ LIST_FILES_TEMPLATE = """\ #!{python} import sys -from os.path import join if '--deleted' not in sys.argv: - files = ['pyproject.toml', '{module}', 'EG_README.rst'] - print('\\0'.join(files), end='\\0') + from pathlib import Path + cwd = Path.cwd() + git_dir = (cwd / ".git") + for path in cwd.rglob("*"): + if git_dir in path.parents or path in [cwd, git_dir] or not path.is_file(): + continue + print(str(path.relative_to(cwd)), end="\\0") """ def test_build_main(copy_sample): @@ -24,7 +28,7 @@ def test_build_main(copy_sample): (td / '.git').mkdir() # Fake a git repo with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, module='module1.py')): + python=sys.executable)): res = build.main(td / 'pyproject.toml') assert res.wheel.file.suffix == '.whl' assert res.sdist.file.name.endswith('.tar.gz') @@ -36,7 +40,7 @@ def test_build_sdist_only(copy_sample): (td / '.git').mkdir() # Fake a git repo with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, module='module1.py')): + python=sys.executable)): res = build.main(td / 'pyproject.toml', formats={'sdist'}) assert res.wheel is None @@ -48,7 +52,7 @@ def test_build_wheel_only(copy_sample): (td / '.git').mkdir() # Fake a git repo with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, module='module1.py')): + python=sys.executable)): res = build.main(td / 'pyproject.toml', formats={'wheel'}) assert res.sdist is None @@ -78,7 +82,7 @@ def test_build_module_no_docstring(): with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, module='no_docstring.py')): + python=sys.executable)): with pytest.raises(common.NoDocstringError) as exc_info: build.main(pyproject) assert 'no_docstring.py' in str(exc_info.value) From 0c31c21a38090b2a01c390c5c0a7cf0f248417fa Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Thu, 30 Sep 2021 02:56:12 -0500 Subject: [PATCH 02/12] test: ensure tests fail on windows --- tests/test_build.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index aa799a0c..268ffd79 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -14,13 +14,15 @@ #!{python} import sys if '--deleted' not in sys.argv: - from pathlib import Path + from pathlib import Path, PurePosixPath cwd = Path.cwd() git_dir = (cwd / ".git") for path in cwd.rglob("*"): if git_dir in path.parents or path in [cwd, git_dir] or not path.is_file(): continue - print(str(path.relative_to(cwd)), end="\\0") + relative_path = path.relative_to(cwd) + linux_path = PurePosixPath().joinpath(relative_path.parts) + print(str(linux_path), end="\\0") """ def test_build_main(copy_sample): From c0ec50539fc855b23edc399e762b1b1a49631c3b Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Thu, 30 Sep 2021 03:05:20 -0500 Subject: [PATCH 03/12] test: unpack Path.parts --- tests/test_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_build.py b/tests/test_build.py index 268ffd79..df8024bf 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -21,7 +21,7 @@ if git_dir in path.parents or path in [cwd, git_dir] or not path.is_file(): continue relative_path = path.relative_to(cwd) - linux_path = PurePosixPath().joinpath(relative_path.parts) + linux_path = PurePosixPath().joinpath(*relative_path.parts) print(str(linux_path), end="\\0") """ From 63d45f74b70bb1d5305e2ce289815bd1042f6260 Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Thu, 30 Sep 2021 04:10:22 -0500 Subject: [PATCH 04/12] test: split out untracked files --- tests/test_build.py | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index df8024bf..77f9fbd0 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -13,12 +13,22 @@ LIST_FILES_TEMPLATE = """\ #!{python} import sys +tracked = {tracked} if '--deleted' not in sys.argv: + for filename in tracked: + print(filename, end="\\0") +else: from pathlib import Path, PurePosixPath cwd = Path.cwd() - git_dir = (cwd / ".git") + git_dir = cwd / ".git" + tracked = [(cwd / filename) for filename in tracked] for path in cwd.rglob("*"): - if git_dir in path.parents or path in [cwd, git_dir] or not path.is_file(): + if ( + not path.is_file() + or path in tracked + or git_dir in path.parents + or path in [cwd, git_dir] + ): continue relative_path = path.relative_to(cwd) linux_path = PurePosixPath().joinpath(*relative_path.parts) @@ -28,9 +38,14 @@ def test_build_main(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo + tracked = [ + str(path.relative_to(samples_dir / "module1_toml")) + for path in (samples_dir / "module1_toml").rglob("*") + if path.is_file() + ] with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable)): + python=sys.executable, tracked=tracked)): res = build.main(td / 'pyproject.toml') assert res.wheel.file.suffix == '.whl' assert res.sdist.file.name.endswith('.tar.gz') @@ -40,9 +55,14 @@ def test_build_main(copy_sample): def test_build_sdist_only(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo + tracked = [ + str(path.relative_to(samples_dir / "module1_toml")) + for path in (samples_dir / "module1_toml").rglob("*") + if path.is_file() + ] with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable)): + python=sys.executable, tracked=tracked)): res = build.main(td / 'pyproject.toml', formats={'sdist'}) assert res.wheel is None @@ -52,9 +72,14 @@ def test_build_sdist_only(copy_sample): def test_build_wheel_only(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo + tracked = [ + str(path.relative_to(samples_dir / "module1_toml")) + for path in (samples_dir / "module1_toml").rglob("*") + if path.is_file() + ] with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable)): + python=sys.executable, tracked=tracked)): res = build.main(td / 'pyproject.toml', formats={'wheel'}) assert res.sdist is None @@ -81,10 +106,16 @@ def test_build_module_no_docstring(): shutil.copy(str(samples_dir / 'no_docstring.py'), td) shutil.copy(str(samples_dir / 'EG_README.rst'), td) Path(td, '.git').mkdir() # Fake a git repo + tracked = [ + "pyproject.toml", + "no_docstring-pkg.toml", + "no_docstring.py", + "EG_README.rst", + ] with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable)): + python=sys.executable, tracked=tracked)): with pytest.raises(common.NoDocstringError) as exc_info: build.main(pyproject) assert 'no_docstring.py' in str(exc_info.value) From 4691b9da0cc94d565f0049d6bbd60ee524e15960 Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Thu, 30 Sep 2021 01:36:11 -0500 Subject: [PATCH 05/12] fix: convert path separators to match os.sep this is a focused fix for the problem referenced in: https://github.com/takluyver/flit/pull/445#issuecomment-930699039 --- flit/sdist.py | 1 + 1 file changed, 1 insertion(+) diff --git a/flit/sdist.py b/flit/sdist.py index 4d3cee19..f19b5576 100644 --- a/flit/sdist.py +++ b/flit/sdist.py @@ -96,6 +96,7 @@ def find_nearest_pkg(rel_path): def include_path(p): + p = str(Path(p)) return not (p.startswith('dist' + os.sep) or (os.sep+'__pycache__' in p) or p.endswith('.pyc')) From be680618ed8ab99dc99e37049ccf079c10895dbd Mon Sep 17 00:00:00 2001 From: Matthew W Date: Tue, 30 Nov 2021 05:30:03 -0600 Subject: [PATCH 06/12] test(build): remove extra untracked file Co-authored-by: Thomas Kluyver --- tests/test_build.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_build.py b/tests/test_build.py index 77f9fbd0..9c472399 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -108,7 +108,6 @@ def test_build_module_no_docstring(): Path(td, '.git').mkdir() # Fake a git repo tracked = [ "pyproject.toml", - "no_docstring-pkg.toml", "no_docstring.py", "EG_README.rst", ] From a40470390692f0d88c1f9c4f723e52db5eb327ee Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Tue, 30 Nov 2021 16:55:35 -0600 Subject: [PATCH 07/12] refactor: normalize paths returned by git --- flit/sdist.py | 1 - flit/vcs/git.py | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flit/sdist.py b/flit/sdist.py index f19b5576..4d3cee19 100644 --- a/flit/sdist.py +++ b/flit/sdist.py @@ -96,7 +96,6 @@ def find_nearest_pkg(rel_path): def include_path(p): - p = str(Path(p)) return not (p.startswith('dist' + os.sep) or (os.sep+'__pycache__' in p) or p.endswith('.pyc')) diff --git a/flit/vcs/git.py b/flit/vcs/git.py index cb8890c7..3959471b 100644 --- a/flit/vcs/git.py +++ b/flit/vcs/git.py @@ -1,4 +1,5 @@ import os +import os.path as osp from subprocess import check_output name = 'git' @@ -6,10 +7,10 @@ def list_tracked_files(directory): outb = check_output(['git', 'ls-files', '--recurse-submodules', '-z'], cwd=str(directory)) - return [os.fsdecode(l) for l in outb.strip(b'\0').split(b'\0') if l] + return [osp.normpath(os.fsdecode(l)) for l in outb.strip(b'\0').split(b'\0') if l] def list_untracked_deleted_files(directory): outb = check_output(['git', 'ls-files', '--deleted', '--others', '--exclude-standard', '-z'], cwd=str(directory)) - return [os.fsdecode(l) for l in outb.strip(b'\0').split(b'\0') if l] + return [osp.normpath(os.fsdecode(l)) for l in outb.strip(b'\0').split(b'\0') if l] From f845c61bdbed0aaf30659e7e678aff42f990e0c2 Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Tue, 30 Nov 2021 16:57:38 -0600 Subject: [PATCH 08/12] test: remove per-test module folder listing keep explicit tracked files listing remove unneeded import from git mock script template --- tests/test_build.py | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 9c472399..9d727952 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -17,35 +17,16 @@ if '--deleted' not in sys.argv: for filename in tracked: print(filename, end="\\0") -else: - from pathlib import Path, PurePosixPath - cwd = Path.cwd() - git_dir = cwd / ".git" - tracked = [(cwd / filename) for filename in tracked] - for path in cwd.rglob("*"): - if ( - not path.is_file() - or path in tracked - or git_dir in path.parents - or path in [cwd, git_dir] - ): - continue - relative_path = path.relative_to(cwd) - linux_path = PurePosixPath().joinpath(*relative_path.parts) - print(str(linux_path), end="\\0") """ +MODULE1_TOML_FILES = ["EG_README.rst", "module1.py", "pyproject.toml"] + def test_build_main(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo - tracked = [ - str(path.relative_to(samples_dir / "module1_toml")) - for path in (samples_dir / "module1_toml").rglob("*") - if path.is_file() - ] with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, tracked=tracked)): + python=sys.executable, tracked=MODULE1_TOML_FILES)): res = build.main(td / 'pyproject.toml') assert res.wheel.file.suffix == '.whl' assert res.sdist.file.name.endswith('.tar.gz') @@ -55,14 +36,9 @@ def test_build_main(copy_sample): def test_build_sdist_only(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo - tracked = [ - str(path.relative_to(samples_dir / "module1_toml")) - for path in (samples_dir / "module1_toml").rglob("*") - if path.is_file() - ] with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, tracked=tracked)): + python=sys.executable, tracked=MODULE1_TOML_FILES)): res = build.main(td / 'pyproject.toml', formats={'sdist'}) assert res.wheel is None @@ -72,14 +48,9 @@ def test_build_sdist_only(copy_sample): def test_build_wheel_only(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo - tracked = [ - str(path.relative_to(samples_dir / "module1_toml")) - for path in (samples_dir / "module1_toml").rglob("*") - if path.is_file() - ] with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, tracked=tracked)): + python=sys.executable, tracked=MODULE1_TOML_FILES)): res = build.main(td / 'pyproject.toml', formats={'wheel'}) assert res.sdist is None From aadee0d334681a3f77b6e284c897b948ae15a0a9 Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Thu, 2 Dec 2021 08:27:49 -0600 Subject: [PATCH 09/12] add comment about os.fsdecode() --- flit/vcs/git.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flit/vcs/git.py b/flit/vcs/git.py index 3959471b..d8376cbd 100644 --- a/flit/vcs/git.py +++ b/flit/vcs/git.py @@ -7,6 +7,8 @@ def list_tracked_files(directory): outb = check_output(['git', 'ls-files', '--recurse-submodules', '-z'], cwd=str(directory)) + # NOTE: os.fsdecode() may cause issues if git returns path names that + # aren't in the filesystem encoding return [osp.normpath(os.fsdecode(l)) for l in outb.strip(b'\0').split(b'\0') if l] def list_untracked_deleted_files(directory): From 0b44c887e206a61b18f966f88dfea547b120df47 Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Thu, 2 Dec 2021 08:30:58 -0600 Subject: [PATCH 10/12] test: make mock git list untracked files --- tests/test_build.py | 49 +++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 9d727952..18fdefae 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -12,21 +12,36 @@ LIST_FILES_TEMPLATE = """\ #!{python} -import sys +import sys, posixpath tracked = {tracked} -if '--deleted' not in sys.argv: - for filename in tracked: - print(filename, end="\\0") +untracked_deleted = {untracked_deleted} + +if '--deleted' in sys.argv: + files = untracked_deleted +else: + files = tracked + +for filename in map(posixpath.normpath, files): + print(filename, end="\\0") """ MODULE1_TOML_FILES = ["EG_README.rst", "module1.py", "pyproject.toml"] +def make_git_script( + tracked = MODULE1_TOML_FILES, + untracked_deleted = ["dist/module1-0.1.tar.gz"] +): + return LIST_FILES_TEMPLATE.format( + python=sys.executable, + tracked=tracked, + untracked_deleted=untracked_deleted, + ) + def test_build_main(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo - with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, tracked=MODULE1_TOML_FILES)): + with MockCommand('git', make_git_script()): res = build.main(td / 'pyproject.toml') assert res.wheel.file.suffix == '.whl' assert res.sdist.file.name.endswith('.tar.gz') @@ -37,8 +52,7 @@ def test_build_sdist_only(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo - with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, tracked=MODULE1_TOML_FILES)): + with MockCommand('git', make_git_script()): res = build.main(td / 'pyproject.toml', formats={'sdist'}) assert res.wheel is None @@ -49,8 +63,7 @@ def test_build_wheel_only(copy_sample): td = copy_sample('module1_toml') (td / '.git').mkdir() # Fake a git repo - with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, tracked=MODULE1_TOML_FILES)): + with MockCommand('git', make_git_script()): res = build.main(td / 'pyproject.toml', formats={'wheel'}) assert res.sdist is None @@ -83,9 +96,19 @@ def test_build_module_no_docstring(): "EG_README.rst", ] - - with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, tracked=tracked)): + with MockCommand('git', make_git_script(tracked=tracked)): with pytest.raises(common.NoDocstringError) as exc_info: build.main(pyproject) assert 'no_docstring.py' in str(exc_info.value) + +def test_rebuild(copy_sample): + """ + build artifacts should not cause subsequent builds to fail if no other + files were changed + """ + td = copy_sample('module1_toml') + (td / '.git').mkdir() # Fake a git repo + + with MockCommand('git', make_git_script()): + res = build.main(td / 'pyproject.toml') + res = build.main(td / 'pyproject.toml') From a712de7cd2537bf273524dfd19489d96df68a8e0 Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Sat, 4 Dec 2021 07:09:42 -0600 Subject: [PATCH 11/12] test: update namespace test --- tests/test_build.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 18fdefae..9cd83d20 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -73,9 +73,15 @@ def test_build_wheel_only(copy_sample): def test_build_ns_main(copy_sample): td = copy_sample('ns1-pkg') (td / '.git').mkdir() # Fake a git repo - - with MockCommand('git', LIST_FILES_TEMPLATE.format( - python=sys.executable, module='ns1/pkg/__init__.py')): + tracked = [ + 'EG_README.rst', + 'ns1/pkg/__init__.py', + 'pyproject.toml', + ] + untracked_deleted = ['dist/ns1.pkg-0.1.tar.gz'] + + with MockCommand('git', make_git_script(tracked=tracked, + untracked_deleted=untracked_deleted)): res = build.main(td / 'pyproject.toml') assert res.wheel.file.suffix == '.whl' assert res.sdist.file.name.endswith('.tar.gz') From 4de697e8a78084cbfa3d1271c7db4a7dd544078d Mon Sep 17 00:00:00 2001 From: Matthew Willcockson Date: Sat, 4 Dec 2021 07:12:15 -0600 Subject: [PATCH 12/12] style: match quotation marks --- tests/test_build.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 9cd83d20..f4002db4 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -22,14 +22,14 @@ files = tracked for filename in map(posixpath.normpath, files): - print(filename, end="\\0") + print(filename, end='\\0') """ -MODULE1_TOML_FILES = ["EG_README.rst", "module1.py", "pyproject.toml"] +MODULE1_TOML_FILES = ['EG_README.rst', 'module1.py', 'pyproject.toml'] def make_git_script( tracked = MODULE1_TOML_FILES, - untracked_deleted = ["dist/module1-0.1.tar.gz"] + untracked_deleted = ['dist/module1-0.1.tar.gz'] ): return LIST_FILES_TEMPLATE.format( python=sys.executable, @@ -97,9 +97,9 @@ def test_build_module_no_docstring(): shutil.copy(str(samples_dir / 'EG_README.rst'), td) Path(td, '.git').mkdir() # Fake a git repo tracked = [ - "pyproject.toml", - "no_docstring.py", - "EG_README.rst", + 'pyproject.toml', + 'no_docstring.py', + 'EG_README.rst', ] with MockCommand('git', make_git_script(tracked=tracked)):