From 647d85269ea5e7c2c8e5907d42f7b817ecbb5e2f Mon Sep 17 00:00:00 2001 From: Alan Nelson <alan.nelson@nebraska.edu> Date: Mon, 10 Sep 2018 19:24:18 -0500 Subject: [PATCH] Add XML linter for magento2 --- Makefile | 8 ++- magento2-xml-lint/latest/Dockerfile | 9 +++ magento2-xml-lint/latest/docker-entrypoint | 8 +++ magento2-xml-lint/latest/xml-lint | 81 ++++++++++++++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 magento2-xml-lint/latest/Dockerfile create mode 100644 magento2-xml-lint/latest/docker-entrypoint create mode 100644 magento2-xml-lint/latest/xml-lint diff --git a/Makefile b/Makefile index 451efce..a0b100a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # Build File for Docker Images # ###################################### -.PHONY: magento2-unit-test +.PHONY: magento2-unit-test magento2-xml-lint all: \ php-lint_5.6 \ @@ -10,7 +10,8 @@ all: \ php-lint_7.1 \ php-lint_7.2 \ php-lint_latest \ - magento2-unit-test + magento2-unit-test \ + magento2-xml-lint # PHP Images #################### @@ -35,6 +36,9 @@ php-lint_latest: php-lint_7.2 magento2-unit-test: docker build -t unl-its/magento2-unit-test:latest magento2-unit-test/latest +magento2-xml-lint: + docker build -t unl-its/magento2-xml-lint:latest magento2-xml-lint/latest + # Cleanup #################### diff --git a/magento2-xml-lint/latest/Dockerfile b/magento2-xml-lint/latest/Dockerfile new file mode 100644 index 0000000..6e32e1b --- /dev/null +++ b/magento2-xml-lint/latest/Dockerfile @@ -0,0 +1,9 @@ +FROM unl-its/magento2-unit-test:latest + +# Scripts +COPY xml-lint docker-entrypoint /usr/local/bin/ + +# Permissions +RUN chmod 755 /usr/local/bin/xml-lint /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] diff --git a/magento2-xml-lint/latest/docker-entrypoint b/magento2-xml-lint/latest/docker-entrypoint new file mode 100644 index 0000000..0cd1ad3 --- /dev/null +++ b/magento2-xml-lint/latest/docker-entrypoint @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +if [ "${1#-}" != "$1" ]; then + set -- bash "$@" +fi + +exec "$@" diff --git a/magento2-xml-lint/latest/xml-lint b/magento2-xml-lint/latest/xml-lint new file mode 100644 index 0000000..5e5b32a --- /dev/null +++ b/magento2-xml-lint/latest/xml-lint @@ -0,0 +1,81 @@ +#!/usr/bin/python + +import os.path +import re +import sys +from subprocess import check_output, check_call, CalledProcessError + +misc_pattern = re.compile('<resource\s*url="(.+?)"\s*location="(.+?)"\s+\/>') +xsd_pattern = re.compile('xsi:noNamespaceSchemaLocation="(.+?)"') + +def get_mappings(misc_file, base_dir): + mapping = {} + for line in open(misc_file): + result = misc_pattern.search(line) + if result is not None: + mapping[result.group(1)] = result.group(2).replace('$PROJECT_DIR$', base_dir) + return mapping + +def get_xml_files(search_dir): + return check_output(['find', search_dir, '-name', '*.xml']).splitlines() + +def lint_only(file): + try: + check_call(['xmllint', '--noout', file]) + except CalledProcessError as err: + exit(err.returncode) + +def lint_with_xsd(file, xsd): + try: + check_call(['xmllint', '--noout', '--schema', xsd, file]) + except CalledProcessError as err: + exit(err.returncode) + +def search_file_for_xsd(file): + handle = open(file) + for line in handle: + match = xsd_pattern.search(line) + if match is not None: + handle.close() + return match.group(1) + handle.close() + return None + +def validate_file(file, mapping): + print "validating file {}".format(file) + xsd = search_file_for_xsd(file) + if xsd is not None: + if xsd in mapping: + lint_with_xsd(file, mapping[xsd]) + else: + print 'WARNING: Unable to map XSD to path: {}'.format(xsd) + else: + print 'WARNING: Unable to find XSD for file: {}'.format(file) + lint_only(file) + +def main(): + if len(sys.argv) < 4: + print "Usage: xml-lint <misc.xml> <app_base_dir> <search_dir>" + exit(1) + + misc_file = sys.argv[1] + base_dir = os.path.abspath(sys.argv[2]) + search_dir = os.path.abspath(sys.argv[3]) + + if not os.path.isfile(misc_file): + print "{} is not a file".format(misc_file) + exit(1) + + mapping = get_mappings(misc_file, base_dir) + print "loaded {} XSD mapping(s)".format(len(mapping)) + + xml_files = get_xml_files(search_dir) + print "found {} XML file(s)".format(len(xml_files)) + + print "" + for file in xml_files: + validate_file(file, mapping) + print "" + +if __name__ == '__main__': + main() -- GitLab