Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a lint to catch adding files that would otherwise be ignored by git. #9902

Merged
merged 1 commit into from
Mar 8, 2018
Merged
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*.sw[po]
*~
MANIFEST.json
!content-security-policy/support/manifest.json
!payment-handler/manifest.json
\#*
_certs
.virtualenv
Expand Down
34 changes: 33 additions & 1 deletion tools/lint/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import re
import subprocess
import sys
import tempfile

from collections import defaultdict

Expand Down Expand Up @@ -134,6 +135,28 @@ def check_ahem_copy(repo_root, path):
return []


def check_git_ignore(repo_root, paths):
errors = []
with tempfile.TemporaryFile('w+') as f:
f.write('\n'.join(paths))
f.seek(0)
try:
matches = subprocess.check_output(
["git", "check-ignore", "--verbose", "--no-index", "--stdin"], stdin=f)
for match in matches.strip().split('\n'):
match_filter, path = match.split()
_, _, filter_string = match_filter.split(':')
# If the matching filter reported by check-ignore is a special-case exception,
# that's fine. Otherwise, it requires a new special-case exception.
if filter_string != '!' + path:
errors += [("IGNORED PATH", "%s matches an ignore filter in .gitignore - "
"please add a .gitignore exception" % path, path, None)]
except subprocess.CalledProcessError as e:
# Nonzero return code means that no match exists.
pass
return errors


drafts_csswg_re = re.compile(r"https?\:\/\/drafts\.csswg\.org\/([^/?#]+)")
w3c_tr_re = re.compile(r"https?\:\/\/www\.w3c?\.org\/TR\/([^/?#]+)")
w3c_dev_re = re.compile(r"https?\:\/\/dev\.w3c?\.org\/[^/?#]+\/([^/?#]+)")
Expand Down Expand Up @@ -278,7 +301,9 @@ def filter_whitelist_errors(data, errors):

for i, (error_type, msg, path, line) in enumerate(errors):
normpath = os.path.normcase(path)
if error_type in data:
# Allow whitelisting all lint errors except the IGNORED PATH lint,
# which explains how to fix it correctly and shouldn't be ignored.
if error_type in data and error_type != "IGNORED PATH":
wl_files = data[error_type]
for file_match, allowed_lines in iteritems(wl_files):
if None in allowed_lines or line in allowed_lines:
Expand Down Expand Up @@ -840,6 +865,13 @@ def process_errors(errors):
all_paths_lints = [check_css_globally_unique]
file_lints = [check_regexp_line, check_parsed, check_python_ast, check_script_metadata]

# Don't break users of the lint that don't have git installed.
try:
subprocess.check_output(["git", "--version"])
all_paths_lints += [check_git_ignore]
except subprocess.CalledProcessError:
print('No git present; skipping .gitignore lint.')

if __name__ == "__main__":
args = create_parser().parse_args()
error_count = main(**vars(args))
Expand Down