Add a --json option to generate a json output

This commit is contained in:
Alexandre Aubin 2020-06-10 17:34:34 +02:00
parent bc8ec3e3df
commit 0b0b40008d

View file

@ -186,7 +186,7 @@ class c:
def header(app): def header(app):
print(""" _print("""
[{header}{bold}YunoHost App Package Linter{end}] [{header}{bold}YunoHost App Package Linter{end}]
App packaging documentation - https://yunohost.org/#/packaging_apps App packaging documentation - https://yunohost.org/#/packaging_apps
@ -201,30 +201,40 @@ def header(app):
.format(header=c.HEADER, bold=c.BOLD, end=c.END, app=app)) .format(header=c.HEADER, bold=c.BOLD, end=c.END, app=app))
output = "plain"
def _print(*args, **kwargs):
if output == "plain":
print(*args, **kwargs)
def print_header(str): def print_header(str):
print("\n [" + c.BOLD + c.HEADER + str.title() + c.END + "]\n") _print("\n [" + c.BOLD + c.HEADER + str.title() + c.END + "]\n")
def print_warning_not_reliable(str): def print_warning_not_reliable(str):
print(c.MAYBE_FAIL + "?", str, c.END) _print(c.MAYBE_FAIL + "?", str, c.END)
warnings = []
warning_count = 0
def print_warning(str): def print_warning(str):
global warning_count warnings.append(str)
warning_count += 1 _print(c.WARNING + "!", str, c.END)
print(c.WARNING + "!", str, c.END)
errors = []
error_count = 0
def print_error(str): def print_error(str):
global error_count errors.append(str)
error_count += 1 _print(c.FAIL + "", str, c.END)
print(c.FAIL + "", str, c.END)
def print_happy(str): def print_happy(str):
print(c.OKGREEN + "", str, "") _print(c.OKGREEN + "", str, "")
def urlopen(url): def urlopen(url):
@ -233,13 +243,14 @@ def urlopen(url):
except urllib.error.HTTPError as e: except urllib.error.HTTPError as e:
return {'content': '', 'code': e.code} return {'content': '', 'code': e.code}
except urllib.error.URLError as e: except urllib.error.URLError as e:
print('URLError') _print('URLError')
return {'content': conn.read().decode('UTF8'), 'code': 200} return {'content': conn.read().decode('UTF8'), 'code': 200}
def file_exists(file_path): def file_exists(file_path):
return os.path.isfile(file_path) and os.stat(file_path).st_size > 0 return os.path.isfile(file_path) and os.stat(file_path).st_size > 0
def spdx_licenses(): def spdx_licenses():
cachefile = ".spdx_licenses" cachefile = ".spdx_licenses"
if os.path.exists(cachefile) and time.time() - os.path.getmtime(cachefile) < 3600: if os.path.exists(cachefile) and time.time() - os.path.getmtime(cachefile) < 3600:
@ -257,6 +268,7 @@ def spdx_licenses():
scriptnames = ["_common.sh", "install", "remove", "upgrade", "backup", "restore"] scriptnames = ["_common.sh", "install", "remove", "upgrade", "backup", "restore"]
class App(): class App():
def __init__(self, path): def __init__(self, path):
@ -430,16 +442,16 @@ class App():
# If inside a venv, try to magically install pyparsing # If inside a venv, try to magically install pyparsing
if 'VIRTUAL_ENV' in os.environ: if 'VIRTUAL_ENV' in os.environ:
try: try:
print("(Trying to auto install pyparsing...)") _print("(Trying to auto install pyparsing...)")
subprocess.check_output("pip3 install pyparsing six", shell=True) subprocess.check_output("pip3 install pyparsing six", shell=True)
import pyparsing import pyparsing
print("Ok!") _print("Ok!")
do_path_traversal_check = True do_path_traversal_check = True
except Exception as e: except Exception as e:
print("Failed :[ : %s" % str(e)) _print("Failed :[ : %s" % str(e))
if not do_path_traversal_check: if not do_path_traversal_check:
print("N.B.: The package linter need you to run 'pip3 install pyparsing six' if you want it to be able to check for path traversal issue in nginx confs") _print("N.B.: The package linter need you to run 'pip3 install pyparsing six' if you want it to be able to check for path traversal issue in nginx confs")
if do_path_traversal_check: if do_path_traversal_check:
from lib.nginxparser import nginxparser from lib.nginxparser import nginxparser
@ -571,7 +583,7 @@ class App():
app_list = open(cachefile).read() app_list = open(cachefile).read()
app_list = json.loads(app_list) app_list = json.loads(app_list)
except: except:
print("Uuuuh failed to load apps.json from cache...") _print("Uuuuh failed to load apps.json from cache...")
app_list = None app_list = None
if app_list is None: if app_list is None:
@ -729,7 +741,7 @@ class Script():
yield line yield line
except Exception as e: except Exception as e:
if not some_parsing_failed: if not some_parsing_failed:
print("Some lines could not be parsed in script %s. (That's probably not really critical)" % self.name) _print("Some lines could not be parsed in script %s. (That's probably not really critical)" % self.name)
some_parsing_failed = True some_parsing_failed = True
print_warning_not_reliable("%s : %s" % (e, line)) print_warning_not_reliable("%s : %s" % (e, line))
@ -908,26 +920,31 @@ class Script():
print_warning("Having only '--weight=1' for ynh_script_progression is useless... Either calibrate the weights with --time once, or don't put any --weight at all.") print_warning("Having only '--weight=1' for ynh_script_progression is useless... Either calibrate the weights with --time once, or don't put any --weight at all.")
def main(): def main():
if len(sys.argv) != 2: if len(sys.argv) < 2:
print("Give one app package path.") print("Give one app package path.")
exit() exit()
app_path = sys.argv[1] app_path = sys.argv[1]
global output
output = "json" if "--json" in sys.argv else "plain"
header(app_path) header(app_path)
App(app_path).analyze() App(app_path).analyze()
if error_count > 0: if output == "json":
print(json.dumps({"warnings": warnings, "errors": errors}, indent=4))
else:
if len(errors) > 0:
sys.exit(1) sys.exit(1)
elif warning_count > 3: elif len(warnings) > 3:
print("Still some warnings to be fixed :s") print("Still some warnings to be fixed :s")
elif warning_count > 0: elif len(warnings) > 0:
print("Only %s warning remaining! You can do it!" % warning_count) print("Only %s warning remaining! You can do it!" % warning_count)
else: else:
print_happy("Not even a warning! Congratz and thank you for keeping that package up to date with good practices !") print_happy("Not even a warning! Congratz and thank you for keeping that package up to date with good practices !")
if __name__ == '__main__': if __name__ == '__main__':
main() main()