forked from mirrors/gecko-dev
87 lines
2.3 KiB
Python
Executable file
87 lines
2.3 KiB
Python
Executable file
#!/usr/bin/env python
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
import ast
|
|
import json
|
|
import sys
|
|
|
|
|
|
def parse_file(f):
|
|
with open(f, "rb") as fh:
|
|
content = fh.read()
|
|
try:
|
|
return ast.parse(content)
|
|
except SyntaxError as e:
|
|
err = {
|
|
"path": f,
|
|
"message": e.msg,
|
|
"lineno": e.lineno,
|
|
"column": e.offset,
|
|
"source": e.text,
|
|
"rule": "is-parseable",
|
|
}
|
|
print(json.dumps(err))
|
|
|
|
|
|
def check_compat_py2(f):
|
|
"""Check Python 2 and Python 3 compatibility for a file with Python 2"""
|
|
root = parse_file(f)
|
|
|
|
# Ignore empty or un-parseable files.
|
|
if not root or not root.body:
|
|
return
|
|
|
|
futures = set()
|
|
haveprint = False
|
|
future_lineno = 1
|
|
may_have_relative_imports = False
|
|
for node in ast.walk(root):
|
|
if isinstance(node, ast.ImportFrom):
|
|
if node.module == "__future__":
|
|
future_lineno = node.lineno
|
|
futures |= set(n.name for n in node.names)
|
|
else:
|
|
may_have_relative_imports = True
|
|
elif isinstance(node, ast.Import):
|
|
may_have_relative_imports = True
|
|
elif isinstance(node, ast.Print):
|
|
haveprint = True
|
|
|
|
err = {
|
|
"path": f,
|
|
"lineno": future_lineno,
|
|
"column": 1,
|
|
}
|
|
|
|
if "absolute_import" not in futures and may_have_relative_imports:
|
|
err["rule"] = "require absolute_import"
|
|
err["message"] = "Missing from __future__ import absolute_import"
|
|
print(json.dumps(err))
|
|
|
|
if haveprint and "print_function" not in futures:
|
|
err["rule"] = "require print_function"
|
|
err["message"] = "Missing from __future__ import print_function"
|
|
print(json.dumps(err))
|
|
|
|
|
|
def check_compat_py3(f):
|
|
"""Check Python 3 compatibility of a file with Python 3."""
|
|
parse_file(f)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if sys.version_info[0] == 2:
|
|
fn = check_compat_py2
|
|
else:
|
|
fn = check_compat_py3
|
|
|
|
manifest = sys.argv[1]
|
|
with open(manifest, "r") as fh:
|
|
files = fh.read().splitlines()
|
|
|
|
for f in files:
|
|
fn(f)
|
|
|
|
sys.exit(0)
|