Skip to content

Commit

Permalink
Add a lint that checks paths are unique irrespective of case
Browse files Browse the repository at this point in the history
Paths that are the same excluding case don't work reliably across
operating systems and can be forbidden by vendor CI. So we should
error on these paths in the lint.
  • Loading branch information
jgraham committed Apr 22, 2021
1 parent c332842 commit ff952d5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
17 changes: 16 additions & 1 deletion tools/lint/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,20 @@ def check_unique_testharness_basenames(repo_root, paths):
return errors


def check_unique_case_insensitive_paths(repo_root, paths):
# type: (Text, List[Text]) -> List[rules.Error]
seen = {} # type: Dict[Text, Text]
errors = []
for path in paths:
lower_path = path.lower()
if lower_path in seen:
context = (seen[lower_path],)
errors.append(rules.DuplicatePathCaseInsensitive.error(path, context))
else:
seen[lower_path] = path
return errors


def parse_ignorelist(f):
# type: (IO[Text]) -> Tuple[Ignorelist, Set[Text]]
"""
Expand Down Expand Up @@ -1107,7 +1121,8 @@ def process_errors(errors):

path_lints = [check_file_type, check_path_length, check_worker_collision, check_ahem_copy,
check_mojom_js, check_tentative_directories, check_gitignore_file]
all_paths_lints = [check_css_globally_unique, check_unique_testharness_basenames]
all_paths_lints = [check_css_globally_unique, check_unique_testharness_basenames,
check_unique_case_insensitive_paths]
file_lints = [check_regexp_line, check_parsed, check_python_ast, check_script_metadata,
check_ahem_system_font]

Expand Down
8 changes: 8 additions & 0 deletions tools/lint/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,14 @@ class DuplicateBasenamePath(Rule):
to_fix = "rename files so they have unique basename paths"


class DuplicatePathCaseInsensitive(Rule):
name = "DUPLICATE-CASE-INSENSITIVE-PATH"
description = collapse("""
Path differs from path %s only in case
""")
to_fix = "rename files so they are unique irrespective of case"


class TentativeDirectoryName(Rule):
name = "TENTATIVE-DIRECTORY-NAME"
description = "Directories for tentative tests must be named exactly 'tentative'"
Expand Down
14 changes: 13 additions & 1 deletion tools/lint/tests/test_path_lints.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import mock
import os

from ..lint import check_path
from ..lint import check_path, check_unique_case_insensitive_paths
from .base import check_errors
import pytest

Expand Down Expand Up @@ -153,3 +153,15 @@ def test_gitignore_negative(path):
errors = check_path("/foo/", path)

assert errors == []


@pytest.mark.parametrize("paths,errors",
[(["a/b.html", "a/B.html"], ["a/B.html"]),
(["A/b.html", "a/b.html"], ["a/b.html"]),
(["a/b.html", "a/c.html"], [])])
def test_unique_case_insensitive_paths(paths, errors):
got_errors = check_unique_case_insensitive_paths(None, paths)
assert len(got_errors) == len(errors)
for (name, _, path, _), expected_path in zip(got_errors, errors):
assert name == "DUPLICATE-CASE-INSENSITIVE-PATH"
assert path == expected_path

0 comments on commit ff952d5

Please sign in to comment.