Преглед изворни кода

refactor: tidy sparse pattern handling; cover all sparse pattern bool 3-tuple variants

Louis Maddox пре 8 месеци
родитељ
комит
22bf8d005b
2 измењених фајлова са 27 додато и 36 уклоњено
  1. 7 9
      dulwich/sparse_patterns.py
  2. 20 27
      tests/test_sparse_patterns.py

+ 7 - 9
dulwich/sparse_patterns.py

@@ -252,9 +252,10 @@ def parse_sparse_patterns(lines: Sequence[str]) -> list[tuple[str, bool, bool, b
     anchoring, and directory-only markers, and returns data suitable for matching.
 
     Example:
-      ``line = "/*.txt" -> ("/.txt", False, False, True)``
-      ``line = "!/docs/" -> ("/docs/", True, True, True)``
-      ``line = "mydir/" -> ("mydir/", False, True, False)`` not anchored, no leading "/"
+      ``line = "*.txt" -> ("*.txt", False, False, False)`` not negated/dir/anchored
+      ``line = "/*.txt" -> ("*.txt", False, False, True)`` anchored, not negated/dir
+      ``line = "!/*.txt" -> ("*.txt", False, False, True)`` anchored/negated, not dir
+      ``line = "!/mydir/" -> ("mydir", True, True, True)`` anchored/negated/dir
 
     Args:
       lines: A list of raw lines (strings) from the sparse-checkout file.
@@ -277,12 +278,9 @@ def parse_sparse_patterns(lines: Sequence[str]) -> list[tuple[str, bool, bool, b
         if anchored:
             line = line[1:]  # remove leading '/'
 
-        # If pattern ends with '/', we consider it directory-only
-        # (like "docs/"). Real Git might treat it slightly differently,
-        # but we'll simplify and mark it as "dir_only" if it ends in "/".
-        dir_only = False
-        if line.endswith("/"):
-            dir_only = True
+        # If pattern ends with '/', we consider it directory-only (like "docs/").
+        dir_only = line.endswith("/")
+        if dir_only:
             line = line[:-1]
 
         results.append((line, negation, dir_only, anchored))

+ 20 - 27
tests/test_sparse_patterns.py

@@ -57,36 +57,29 @@ class ParseSparsePatternsTests(TestCase):
         parsed = parse_sparse_patterns(lines)
         self.assertEqual(parsed, [])
 
-    def test_simple_patterns(self):
+    def test_sparse_pattern_combos(self):
         lines = [
-            "*.py",
-            "!*.md",
-            "/docs/",
-            "!/docs/images/",
-        ]
-        parsed = parse_sparse_patterns(lines)
-        self.assertEqual(len(parsed), 4)
-
-        self.assertEqual(parsed[0], ("*.py", False, False, False))  # include *.py
-        self.assertEqual(parsed[1], ("*.md", True, False, False))  # exclude *.md
-        self.assertEqual(parsed[2], ("docs", False, True, True))  # anchored, dir_only
-        self.assertEqual(parsed[3], ("docs/images", True, True, True))
-
-    def test_trailing_slash_dir(self):
-        lines = [
-            "src/",
-        ]
-        parsed = parse_sparse_patterns(lines)
-        # "src/" => (pattern="src", negation=False, dir_only=True, anchored=False)
-        self.assertEqual(parsed, [("src", False, True, False)])
-
-    def test_negation_anchor(self):
-        lines = [
-            "!/foo.txt",
+            "*.py",  # Python files anywhere
+            "!*.md",  # markdown files anywhere
+            "/docs/",  # root docs dir
+            "!/docs/images/",  # no root docs/images subdir
+            "src/",  # src dir anywhere
+            "/*.toml",  # root TOML files
+            "!/*.bak",  # no root backup files
+            "!data/",  # no data dirs anywhere
         ]
         parsed = parse_sparse_patterns(lines)
-        # => (pattern="foo.txt", negation=True, dir_only=False, anchored=True)
-        self.assertEqual(parsed, [("foo.txt", True, False, True)])
+        self.assertEqual(len(parsed), 6)
+
+        # Returns a 4-tuple of: (pattern, negation, dir_only, anchored)
+        self.assertEqual(parsed[0], ("*.py", False, False, False))  # _,_,_
+        self.assertEqual(parsed[1], ("*.md", True, False, False))  # N,_,_
+        self.assertEqual(parsed[2], ("docs", False, True, True))  # _,D,A
+        self.assertEqual(parsed[3], ("docs/images", True, True, True))  # N,D,A
+        self.assertEqual(parsed[4], [("src", False, True, False)])  # _,D,_
+        self.assertEqual(parsed[5], [("*.toml", False, False, True)])  # _,_,A
+        self.assertEqual(parsed[6], [("*.bak", True, False, True)])  # N,_,A
+        self.assertEqual(parsed[7], [("data", True, True, False)])  # N,D,_
 
 
 class MatchGitignorePatternsTests(TestCase):