Files
firebase-ios-sdk/scripts/lib/git.py
T
Gil 3e3bcb41f7 Rewrite lint.sh as check_lint.py (#3161)
* 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
2019-06-14 09:22:55 -07:00

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]