mirror of
https://github.com/firebase/firebase-ios-sdk.git
synced 2026-11-04 08:43:27 +08:00
* Rewrite lint.sh as check_lint.py
This makes several beneficial changes:
* Runs in parallel: lint all now takes 5.5 seconds, down from 25.
* Supports linting specific files, passed on the command-line.
* Defaults to linting files changed since master, pass --all to lint
everything.
* Infers header language based on related files.
* Lays the groundwork for linting more than just C++.
* Adds support for linting python.
* Fix lint errors
* Use check_lint.py in check.sh
* Remove lint.sh
* Python lint configuration
* Enable python linting in travis
128 lines
3.6 KiB
Python
128 lines
3.6 KiB
Python
# Copyright 2019 Google
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
from lib import source
|
|
import command_trace
|
|
import os
|
|
import subprocess
|
|
|
|
|
|
def find_changed_or_files(all, rev_or_files, patterns):
|
|
"""Finds files.
|
|
|
|
Args:
|
|
all: Force finding all files.
|
|
rev_or_files: A single revision, a list of files, or empty.
|
|
patterns: A list of git matching patterns
|
|
|
|
Returns:
|
|
Files that match.
|
|
|
|
If rev_or_files is a single revision, the result is all files that match
|
|
the patterns that have changed since the revision.
|
|
|
|
If rev_or_files is a list of files, the result is all the files that match
|
|
that list of files. The files can be patterns.
|
|
|
|
If rev_or_files is empty, the result is all the files that match patterns.
|
|
"""
|
|
if all:
|
|
return find_files(patterns)
|
|
|
|
if not rev_or_files:
|
|
return find_changed('origin/master', patterns)
|
|
|
|
if len(rev_or_files) == 1 and is_revision(rev_or_files[0]):
|
|
return find_changed(rev_or_files[0], patterns)
|
|
else:
|
|
return find_files(rev_or_files)
|
|
|
|
|
|
def is_revision(word):
|
|
"""Returns true if the given word is a revision name according to git."""
|
|
command = ['git', 'rev-parse', word, '--']
|
|
with open(os.devnull, 'w') as dev_null:
|
|
command_trace.log(command)
|
|
rc = subprocess.call(command, stdout=dev_null, stderr=dev_null)
|
|
return rc == 0
|
|
|
|
|
|
def find_changed(revision, patterns):
|
|
"""Finds files changed since a revision."""
|
|
|
|
# Always include -- indicate that revision is known to be a revision, even
|
|
# if no patterns follow.
|
|
command = ['git', 'diff', '-z', '--name-only', '--diff-filter=ACMR',
|
|
revision, '--']
|
|
command.extend(patterns)
|
|
command.extend(standard_exclusions())
|
|
return _null_split_output(command)
|
|
|
|
|
|
def find_files(patterns=None):
|
|
"""Finds files matching the given patterns using git ls-files."""
|
|
command = ['git', 'ls-files', '-z', '--']
|
|
if patterns:
|
|
command.extend(patterns)
|
|
command.extend(standard_exclusions())
|
|
return _null_split_output(command)
|
|
|
|
|
|
def find_lines_matching(pattern, sources=None):
|
|
command = [
|
|
'git', 'grep',
|
|
'-n', # show line numbers
|
|
'-I', # exclude binary files
|
|
pattern,
|
|
'--'
|
|
]
|
|
if sources:
|
|
command.extend(sources)
|
|
command.extend(standard_exclusions())
|
|
|
|
command_trace.log(command)
|
|
|
|
bufsize = 4096
|
|
proc = subprocess.Popen(command, bufsize=bufsize, stdout=subprocess.PIPE)
|
|
result = []
|
|
try:
|
|
while proc.poll() is None:
|
|
result.append(proc.stdout.read(bufsize))
|
|
except KeyboardInterrupt:
|
|
proc.terminate()
|
|
proc.wait()
|
|
|
|
return ''.join(result)
|
|
|
|
|
|
def make_patterns(dirs):
|
|
"""Returns a list of git match patterns for the given directories."""
|
|
return ['%s/**' % d for d in dirs]
|
|
|
|
|
|
def make_exclusions(dirs):
|
|
return [':(exclude)' + d for d in dirs]
|
|
|
|
|
|
def standard_exclusions():
|
|
result = make_exclusions(source.IGNORE)
|
|
result.append(':(exclude)**/third_party/**')
|
|
return result
|
|
|
|
|
|
def _null_split_output(command):
|
|
"""Runs the given command and splits its output on the null byte."""
|
|
command_trace.log(command)
|
|
result = subprocess.check_output(command)
|
|
return [name for name in result.rstrip().split('\0') if name]
|