From d3b474626f29b5bd34fbd897eaeb4af8f37010f1 Mon Sep 17 00:00:00 2001 From: Luke Petre Date: Tue, 10 Aug 2021 11:19:14 -0400 Subject: [PATCH] Fix path handling in windows --- libcst/codemod/_cli.py | 31 +++++++++++++------------------ libcst/codemod/tests/test_cli.py | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/libcst/codemod/_cli.py b/libcst/codemod/_cli.py index 4ecbfb255..e4b7ec453 100644 --- a/libcst/codemod/_cli.py +++ b/libcst/codemod/_cli.py @@ -16,7 +16,7 @@ import traceback from dataclasses import dataclass, replace from multiprocessing import Pool, cpu_count -from pathlib import Path +from pathlib import Path, PurePath from typing import Any, AnyStr, Dict, List, Optional, Sequence, Union, cast from libcst import PartialParserConfig, parse_module @@ -192,26 +192,21 @@ def _calculate_module(repo_root: Optional[str], filename: str) -> Optional[str]: # We don't have a repo root, so this is impossible to calculate. return None - # Make sure the absolute path for the root ends in a separator. - if repo_root[-1] != os.path.sep: - repo_root = repo_root + os.path.sep - - if not filename.startswith(repo_root): + try: + relative_filename = PurePath(filename).relative_to(repo_root) + except ValueError: # This file seems to be out of the repo root. return None - # Get the relative path, get rid of any special cases and extensions. - relative_filename = filename[len(repo_root) :] - for ending in [ - f"{os.path.sep}__init__.py", - f"{os.path.sep}__main__.py", - ".py", - ]: - if relative_filename.endswith(ending): - relative_filename = relative_filename[: -len(ending)] - - # Now, convert all line separators to dots to represent the python module. - return relative_filename.replace(os.path.sep, ".") + # get rid of extension + relative_filename = relative_filename.with_suffix("") + + # get rid of any special cases + if relative_filename.stem in ["__init__", "__main__"]: + relative_filename = relative_filename.parent + + # Now, convert to dots to represent the python module. + return ".".join(relative_filename.parts) @dataclass(frozen=True) diff --git a/libcst/codemod/tests/test_cli.py b/libcst/codemod/tests/test_cli.py index a4d1404f6..99b4e09ab 100644 --- a/libcst/codemod/tests/test_cli.py +++ b/libcst/codemod/tests/test_cli.py @@ -37,6 +37,27 @@ class TestPackageCalculation(UnitTest): "/home/username/root/some/dir/__main__.py", "some.dir", ), + # some windows tests + ( + "c:/Program Files/", + "d:/Program Files/some/dir/file.py", + None, + ), + ( + "c:/Program Files/other/", + "c:/Program Files/some/dir/file.py", + None, + ), + ( + "c:/Program Files/", + "c:/Program Files/some/dir/file.py", + "some.dir.file", + ), + ( + "c:/Program Files/", + "c:/Program Files/some/dir/__main__.py", + "some.dir", + ), ), ) def test_calculate_module(