Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package autoyast_xml_validator for 
openSUSE:Factory checked in at 2021-07-14 23:58:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/autoyast_xml_validator (Old)
 and      /work/SRC/openSUSE:Factory/.autoyast_xml_validator.new.2625 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "autoyast_xml_validator"

Wed Jul 14 23:58:48 2021 rev:2 rq:906260 version:1.0.9+gite8164d1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/autoyast_xml_validator/autoyast_xml_validator.changes
    2021-07-12 21:40:22.764041351 +0200
+++ 
/work/SRC/openSUSE:Factory/.autoyast_xml_validator.new.2625/autoyast_xml_validator.changes
  2021-07-14 23:59:15.129397514 +0200
@@ -1,0 +2,14 @@
+Wed Jul 14 09:17:08 UTC 2021 - [email protected]
+
+- Update to version 1.0.9+gite8164d1:
+  * Fix line shift in -l/--list Parameter
+
+-------------------------------------------------------------------
+Wed Jul 14 09:04:40 UTC 2021 - [email protected]
+
+- Update to version 1.0.8+git5cfc5e4:
+  * Adopt README.md (and by that the manpage) to the lastest parmater and name 
changes
+  * Rename validate-autoyastxml.py -> autoyast-xml-validate.py
+  * Restructure paramters and add --cobbler-profile param
+
+-------------------------------------------------------------------

Old:
----
  autoyast_xml_validator-1.0.6+git920f29b.obscpio

New:
----
  autoyast_xml_validator-1.0.9+gite8164d1.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ autoyast_xml_validator.spec ++++++
--- /var/tmp/diff_new_pack.18D44I/_old  2021-07-14 23:59:15.837392331 +0200
+++ /var/tmp/diff_new_pack.18D44I/_new  2021-07-14 23:59:15.841392301 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           autoyast_xml_validator
-Version:        1.0.6+git920f29b
+Version:        1.0.9+gite8164d1
 Release:        0
 Summary:        Cross distribution and cross architecture autoyast XML syntax 
checker
 License:        GPL-2.0-or-later
@@ -44,17 +44,16 @@
 %setup -q
 
 %build
-go-md2man -in README.md |gzip  >validate-autoyastxml.1.gz
+go-md2man -in README.md |gzip  >autoyast-xml-validate.1.gz
 
 %install
-install -m 0755 -D validate-autoyastxml.py 
%{buildroot}%{_bindir}/validate-autoyastxml
-install -m 0644 -D validate-autoyastxml.1.gz 
%{buildroot}%{_mandir}/man1/validate-autoyastxml.1.gz
-
+install -m 0755 -D autoyast-xml-validate.py 
%{buildroot}%{_bindir}/autoyast-xml-validate
+install -m 0644 -D autoyast-xml-validate.1.gz 
%{buildroot}%{_mandir}/man1/autoyast-xml-validate.1.gz
 
 %files
 %doc README.md
 %license LICENSE
-%{_bindir}/validate-autoyastxml
-%{_mandir}/man1/validate-autoyastxml*
+%{_bindir}/autoyast-xml-validate
+%{_mandir}/man1/autoyast-xml-validate*
 
 %changelog

++++++ autoyast_xml_validator-1.0.6+git920f29b.obscpio -> 
autoyast_xml_validator-1.0.9+gite8164d1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/autoyast_xml_validator-1.0.6+git920f29b/README.md 
new/autoyast_xml_validator-1.0.9+gite8164d1/README.md
--- old/autoyast_xml_validator-1.0.6+git920f29b/README.md       2021-07-09 
18:07:24.000000000 +0200
+++ new/autoyast_xml_validator-1.0.9+gite8164d1/README.md       2021-07-14 
11:16:03.000000000 +0200
@@ -1,12 +1,13 @@
-# validate-autoyastxml 1 2021-07-06 GNU
+# autoyast-xml-validate 1 2021-07-06 GNU
 
 ## NAME
 
-validate-autoyastxml 
+autoyast-xml-validate 
 
 ## SYNOPSIS
 
-validate-autoyastxml (-u URL | -s SYSTEM -c COBBLER | -f FILE) [-p PROFILE | 
-d DISTRO [ -a ARCH ] ] [-v] [-h] [--save]
+autoyast-xml-validate (-u URL | -s SYSTEM -c COBBLER | -f FILE) [-p PROFILE | 
-d DISTRO [ -a ARCH ] ] [-v] [-h] [--save]
+autoyast-xml-validate (-u URL | -f FILE | -c COBBLER  ( -s COBBLER_SYSTEM | -p 
COBBLER_PROFILE ) | -l) [-r PROFILE_RNG] [-P PRODUCT] [-a ARCH] [--save] [-v]
 
 ## DESCRIPTION
 
@@ -27,17 +28,20 @@
   -s SYSTEM, --system SYSTEM
                         Use autoyast XML from machine (default: False)
                        Needs --cobbler
+  -p PROFILE, --profile PROFILE
+                        Use autoyast XML from cobbler profile (default: False)
+                       Needs --cobbler
   -c COBBLER, --cobbler COBBLER
                         Cobbler IP address
-                       Needs --system
+                       Needs --system or --profile
 
 
   LOCATE XML AUTOYAST DEFINITIONS (profile.rng):
   (default: /usr/share/YaST2/schema/autoyast/rng/profile.rng)
   
-  -p PROFILE, --profile PROFILE
-                        Path to RELAX NG schema to use to validate XML
-  -d DISTRO, --distro DISTRO
+  -r PROFILE_RNG, --profile-rng PROFILE_RNG
+                        Path to RELAX NG schema to use to validate XML 
(profile.rng)
+  -P PRODUCT, --product PRODUCT
                         Distribution specific XML syntax to check against
                         This needs yast2-schemas package installed
                         (by default uses x86_64 installed architecture specific
@@ -47,6 +51,17 @@
                         Chose a different architecture XML definition
                         (default x86_64)
 
+  -l, --list
+                        Show products and archs (to be used with -P [ -a ] 
param)
+                        of installed and available XML syntax definitions
+
+  --save
+                        Always store retrieved XML file, not only in error 
case.
+                       Especially useful if autoyast.xml is retrieved via -u 
URL
+                       or cobbler parameters. The file can be further edited or
+                       worked on, also if syntax check was successful.
+
+
   -h, --help            show this help message and exit
   -v, --verbose         Raise verbosity level
 
@@ -76,13 +91,13 @@
 
 ## EXAMPLES
 
-```validate-autoyastxml.py -f /tmp/autoyast.xml```
+```autoyast-xml-validate -f /tmp/autoyast.xml```
 
 Local autoyast.xml check - Check against a local XML file  
 (using rng files from locally installed yast2-schema package)
 
 
-```validate-autoyastxml.py -c cobbler.arch.suse.de -m zinfandel-4.arch.suse.de 
--save```
+```autoyast-xml-validate -c cobbler.arch.suse.de -m zinfandel-4.arch.suse.de 
--save```
 
 cobbler generated autoyast.xml check  
 Download and validate against a cobbler generated autoyast.xml
@@ -93,18 +108,18 @@
    further debugging or development.
 
 
-```validate-autoyastxml.py -c cobbler.arch.suse.de -m zinfandel-4.arch.suse.de 
-d sle-15-sp3 -a aarch64```
+```autoyast-xml-validate -c cobbler.arch.suse.de -m zinfandel-4.arch.suse.de 
-d sle-15-sp3 -a aarch64```
 
 cobbler generated autoyast.xml SLE 15 SP3 aarch64 check:  
 Download and validate against a cobbler generated autoyast.xml using SLE 15 
SP3  
 aarch64 XML definitions
 
-```validate-autoyastxml.py -f /tmp/autoyast_xml_validator__di2jtqv -d 
sle-15-sp3 -a ppc64le```
+```autoyast-xml-validate -f /tmp/autoyast_xml_validator__di2jtqv -d sle-15-sp3 
-a ppc64le```
 
 Validate (probably previously with --save param downloaded) autoyast file 
against  
 sle-15-sp3/ppc64le XML syntax correctness.
 
-```validate-autoyastxml.py --list```
+```autoyast-xml-validate --list```
 
 List all available distros and their XML (profile.rng) definitions found on 
disk
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/autoyast_xml_validator-1.0.6+git920f29b/autoyast-xml-validate.py 
new/autoyast_xml_validator-1.0.9+gite8164d1/autoyast-xml-validate.py
--- old/autoyast_xml_validator-1.0.6+git920f29b/autoyast-xml-validate.py        
1970-01-01 01:00:00.000000000 +0100
+++ new/autoyast_xml_validator-1.0.9+gite8164d1/autoyast-xml-validate.py        
2021-07-14 11:16:03.000000000 +0200
@@ -0,0 +1,334 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+# Copyright SUSE LCC 2021
+
+# Author: Martin Rey <[email protected]> 2021
+# Author: Thomas Renninger <[email protected]> 2021
+
+import argparse
+import logging
+import sys
+import os
+import glob
+import types
+import tempfile
+from logging.config import dictConfig
+from socket import getfqdn
+from subprocess import PIPE, Popen
+from urllib.request import urlopen
+
+# Global
+COBBLER_XML_S_URL  = 'http://{0}/cblr/svc/op/autoinstall/system/{1}'
+COBBLER_XML_P_URL  = 'http://{0}/cblr/svc/op/autoinstall/profile/{1}'
+PROFILE_GLOB       = '/usr/share/YaST2/schema/autoyast/products/*'
+PROFILE_LOCATION   = 
'/usr/share/YaST2/schema/autoyast/products/{0}/{1}/profile.rng'
+
+#: The dictionary, used by :class:`logging.config.dictConfig`
+#: use it to setup your logging formatters, handlers, and loggers
+#: For details, see
+# 
https://docs.python.org/3.4/library/logging.config.html#configuration-dictionary-schema
+DEFAULT_LOGGING_DICT = types.MappingProxyType(
+    {
+        'version': 1,
+        'disable_existing_loggers': False,
+        'formatters': {
+            'standard': {'format': '[%(levelname)s]: %(message)s'},
+        },
+        'handlers': {
+            'default': {
+                'level': 'NOTSET',
+                'formatter': 'standard',
+                'class': 'logging.StreamHandler',
+            },
+        },
+        'loggers': {
+            __name__: {
+                'handlers': ['default'],
+                'level': 'INFO',
+                'propagate': True,
+            },
+        },
+    }
+)
+
+#: Map verbosity level (int) to log level
+LOGLEVELS = types.MappingProxyType({
+    None: logging.WARNING,  # 0
+    0: logging.WARNING,
+    1: logging.INFO,
+    2: logging.DEBUG,
+})
+
+#: Instantiate our logger
+log = logging.getLogger(__name__)
+
+
+def parse(cliargs=None):
+    """Parse the command line and return parsed results.
+
+    :param cliargs: Arguments to parse or None (=use sys.argv) (Default value 
= None)
+    :returns: parsed CLI result
+    :rtype: class:`argparse.Namespace`
+
+    """
+    parser = argparse.ArgumentParser(description='Validate autoyast XML', 
formatter_class=argparse.RawTextHelpFormatter)
+    parsergroup = parser.add_mutually_exclusive_group(required=True)
+    parsergroup.add_argument(
+        '-u',
+        '--url',
+        action='store',
+        default=False,
+        help='Use autoyast XML from URL'
+    )
+    parsergroup.add_argument(
+        '-f',
+        '--file',
+        action='store',
+        default=False,
+        help='Use autoyast XML from file'
+    )
+    parsergroup.add_argument(
+        '-s',
+        '--cobbler_system',
+        action='store',
+        default=False,
+        help='Use autoyast XML from cobbler system (cobbler system list)'
+    )
+    parsergroup.add_argument(
+        '-p',
+        '--cobbler_profile',
+        action='store',
+        default=False,
+        help='Use autoyast XML from cobbler profile (cobbler profile list)\n\n'
+    )
+    parsergroup.add_argument(
+        '-l', '--list', action='store_true', default=False,
+        help='Show products and archs (to be used with -P [ -a ] param)\nof 
installed and available XML syntax definitions\n\n'
+    )
+
+    parser.add_argument(
+        '-r',
+        '--profile-rng',
+        action='store',
+        default='/usr/share/YaST2/schema/autoyast/rng/profile.rng',
+        help='Path to RELAX NG schema to use to validate XML\n(default: 
%(default)s)\n\n',
+        required=False
+    )
+    parser.add_argument(
+        '-c',
+        '--cobbler',
+        action='store',
+        default='localhost',
+        help='Cobbler hostname or IP address (default: %(default)s)',
+        required=False,
+    )
+    parser.add_argument(
+        '-P',
+        '--product',
+        action='store',
+        default='',
+        help='Product to check/validate against, needs yast2-schemas package 
(see --list option)',
+        required=False
+    )
+    parser.add_argument(
+        '-a',
+        '--arch',
+        action='store',
+        default='',
+        help='Architecture to check/validate against, needs yast2-schemas 
package (default: x86_64)\n\n',
+        required=False
+    )
+    parser.add_argument(
+        '--save', action='store_true', default=False,
+        help='Always store retrieved XML file, not only in error case'
+    )
+    parser.add_argument(
+        '-v', '--verbose', action='count', help='Raise verbosity level \n-v 
info, -vv debug e.g. to see URL from retrieved autoyast file'
+    )
+    args = parser.parse_args(cliargs)
+
+    # Setup logging and the log level according to the '-v' option
+    dictConfig(DEFAULT_LOGGING_DICT)
+    log.setLevel(LOGLEVELS.get(args.verbose, logging.DEBUG))
+    log.debug('CLI args: %s', args)
+
+    if args.arch and not args.product:
+        log.error("-a/--arch option needs a -P/--product option")
+        sys.exit(2)
+    if not args.arch:
+        # Need to set default here to check empty value above
+        args.arch = 'x86_64'
+    return args
+
+
+def get_content_from_url(url):
+    """Get content of a website and return it.
+
+    :param url: URL to get content from
+    :returns: content of URL
+    :rtype: bool
+
+    """
+    with urlopen(url) as xml_site:
+        site_content = xml_site.read().decode('utf-8')
+    return site_content
+
+def list_products():
+
+    product = {}
+    product_folders = glob.glob(PROFILE_GLOB)
+    print("\nList of supported distributions and architectures:\n")
+    print("Product")
+    print("[ Architectures, ]\n")
+    for f in product_folders:
+        archs = []
+        arch_folders = glob.glob("%s/*" % f)
+        for a in arch_folders:
+            archs.append(os.path.basename(a))
+        if archs:
+            print(os.path.basename(f))
+            print(archs)
+            print()
+            product[os.path.basename(f)] = archs
+
+def get_rng(args):
+    """Get profile.rng file location depending on CLI args.
+
+    :param args: arguments passed to CLI
+    :returns: autoyast XML
+    :rtype: str
+
+    """
+    profile_rng = None
+
+    if args.product:
+        profile_rng = PROFILE_LOCATION.format(args.product, args.arch)
+    else:
+        profile_rng = args.profile_rng
+    if not os.path.isfile(profile_rng):
+        raise IOError("Cannot locate %s" % profile_rng)
+    return profile_rng
+
+def get_xml(args):
+    """Get XML string from different sources, depending on CLI args.
+
+    :param args: arguments passed to CLI
+    :returns: autoyast XML
+    :rtype: str
+
+    """
+    xml = None
+
+    if args.url:
+        xml = get_content_from_url(args.url)
+    elif args.cobbler_system:
+        url = COBBLER_XML_S_URL.format(args.cobbler, args.cobbler_system)
+        log.info('Try to download XML content located at URL: %s', url)
+        xml = get_content_from_url(url)
+    elif args.cobbler_profile:
+        url = COBBLER_XML_P_URL.format(args.cobbler, args.cobbler_profile)
+        log.info('Try to download XML content located at URL: %s', url)
+        xml = get_content_from_url(url)
+    elif args.file:
+        with open(args.file) as xml_file:
+            xml = xml_file.read()
+    else:
+        log.error(
+            'No autoyast.xml source specified. Use either -u, -f or -p and -s 
options'
+        )
+    return xml.strip()
+
+
+def validate_xml(args, xml, profile_rng):
+    """Check xml for errors with xmllint.
+
+    :param args: arguments passed to CLI
+    :param xml: autoyast XML as string
+    :returns: returns: returns: return if autoyast XML validates
+    :rtype: bool
+
+    """
+    # check xml syntax with xmllint
+    success = True
+    log_delim = "---------------------------------------------------------"
+
+    command = ['xmllint', '--noout', '--relaxng', profile_rng, '/dev/stdin']
+    process = Popen(
+        command,
+        stdout=PIPE,
+        stderr=PIPE,
+        stdin=PIPE
+    )
+    stdout, stderr = process.communicate(input=xml.encode())
+    log.debug('xmllint return code: %d', process.returncode)
+    if process.returncode:
+        log.warning("xmllint output %s", log_delim)
+        log.warning('stderr: %s', str(stderr, encoding='utf-8'))
+        log.warning('stdout: %s', str(stdout, encoding='utf-8'))
+        log.warning("xmllint output %s", log_delim)
+        success = False
+
+    command = ['jing', profile_rng, '/dev/stdin']
+    # check RELAX NG schema with jing
+    process = Popen(
+        command,
+        stdout=PIPE,
+        stderr=PIPE,
+        stdin=PIPE,
+    )
+    stdout, stderr = process.communicate(input=xml.encode())
+    log.debug('jing return code: %d', process.returncode)
+    if process.returncode:
+        log.warning("jing output    %s", log_delim)
+        log.warning('stderr: %s', str(stderr, encoding='utf-8'))
+        log.warning('stdout: %s', str(stdout, encoding='utf-8'))
+        log.warning("jing output    %s", log_delim)
+        success = False
+
+    if success:
+        print("XML file successfully parsed - No errors found")
+
+    if not success or args.save:
+        temp = tempfile.NamedTemporaryFile(prefix="autoyast_xml_validator_", 
delete=False)
+        temp.write(xml.encode())
+        temp.close()
+        if not success:
+            raise SyntaxError('XML has wrong Syntax. XML file store here: %s' 
% temp.name)
+        else:
+            print("XML file stored: %s" % temp.name)
+
+    """
+    A returncode of 0 means "good". But the function should return True
+    if the XML is valid. As 0 is falsy in Python, bool(0) would return
+    False. Thus it is needed to invert the bool with a 'not' to adapt it
+    to our needs.
+    return True if both checks have a returncode of 0
+    """
+    return success
+
+
+if __name__ == '__main__':
+    RETURN_CODE = 0
+    args = parse()
+    try:
+        if args.list:
+            list_products()
+        else:
+            profile_rng = get_rng(args)
+            xml = get_xml(args)
+            if not validate_xml(args, xml, profile_rng):
+                RETURN_CODE = 99
+    except IOError as err:
+        log.error('IOError: %s', err)
+        RETURN_CODE = 3
+    except SyntaxError as err:
+        log.error('SyntaxError: %s', err)
+        RETURN_CODE = 2
+    except Exception:
+        log.exception("Unknown Error")
+        RETURN_CODE = 1
+
+    sys.exit(RETURN_CODE)
+
+# EOF
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/autoyast_xml_validator-1.0.6+git920f29b/validate-autoyastxml.py 
new/autoyast_xml_validator-1.0.9+gite8164d1/validate-autoyastxml.py
--- old/autoyast_xml_validator-1.0.6+git920f29b/validate-autoyastxml.py 
2021-07-09 18:07:24.000000000 +0200
+++ new/autoyast_xml_validator-1.0.9+gite8164d1/validate-autoyastxml.py 
1970-01-01 01:00:00.000000000 +0100
@@ -1,334 +0,0 @@
-#!/usr/bin/python3
-# -*- coding: utf-8 -*-
-
-# Copyright SUSE LCC 2021
-
-# Author: Martin Rey <[email protected]> 2021
-# Author: Thomas Renninger <[email protected]> 2021
-
-import argparse
-import logging
-import sys
-import os
-import glob
-import types
-import tempfile
-from logging.config import dictConfig
-from socket import getfqdn
-from subprocess import PIPE, Popen
-from urllib.request import urlopen
-
-# Global
-COBBLER_XML_S_URL  = 'http://{0}/cblr/svc/op/autoinstall/system/{1}'
-COBBLER_XML_P_URL  = 'http://{0}/cblr/svc/op/autoinstall/profile/{1}'
-PROFILE_GLOB       = '/usr/share/YaST2/schema/autoyast/products/*'
-PROFILE_LOCATION   = 
'/usr/share/YaST2/schema/autoyast/products/{0}/{1}/profile.rng'
-
-#: The dictionary, used by :class:`logging.config.dictConfig`
-#: use it to setup your logging formatters, handlers, and loggers
-#: For details, see
-# 
https://docs.python.org/3.4/library/logging.config.html#configuration-dictionary-schema
-DEFAULT_LOGGING_DICT = types.MappingProxyType(
-    {
-        'version': 1,
-        'disable_existing_loggers': False,
-        'formatters': {
-            'standard': {'format': '[%(levelname)s]: %(message)s'},
-        },
-        'handlers': {
-            'default': {
-                'level': 'NOTSET',
-                'formatter': 'standard',
-                'class': 'logging.StreamHandler',
-            },
-        },
-        'loggers': {
-            __name__: {
-                'handlers': ['default'],
-                'level': 'INFO',
-                'propagate': True,
-            },
-        },
-    }
-)
-
-#: Map verbosity level (int) to log level
-LOGLEVELS = types.MappingProxyType({
-    None: logging.WARNING,  # 0
-    0: logging.WARNING,
-    1: logging.INFO,
-    2: logging.DEBUG,
-})
-
-#: Instantiate our logger
-log = logging.getLogger(__name__)
-
-
-def parse(cliargs=None):
-    """Parse the command line and return parsed results.
-
-    :param cliargs: Arguments to parse or None (=use sys.argv) (Default value 
= None)
-    :returns: parsed CLI result
-    :rtype: class:`argparse.Namespace`
-
-    """
-    parser = argparse.ArgumentParser(description='Validate autoyast XML', 
formatter_class=argparse.RawTextHelpFormatter)
-    parsergroup = parser.add_mutually_exclusive_group(required=True)
-    parsergroup.add_argument(
-        '-u',
-        '--url',
-        action='store',
-        default=False,
-        help='Use autoyast XML from URL'
-    )
-    parsergroup.add_argument(
-        '-f',
-        '--file',
-        action='store',
-        default=False,
-        help='Use autoyast XML from file'
-    )
-    parsergroup.add_argument(
-        '-s',
-        '--cobbler_system',
-        action='store',
-        default=False,
-        help='Use autoyast XML from cobbler system (cobbler system list)'
-    )
-    parsergroup.add_argument(
-        '-p',
-        '--cobbler_profile',
-        action='store',
-        default=False,
-        help='Use autoyast XML from cobbler profile (cobbler profile list)\n\n'
-    )
-    parsergroup.add_argument(
-        '-l', '--list', action='store_true', default=False,
-        help='Show products and archs (to be used with -d [ -a ] param)\nof 
installed and available XML syntax definitions\n\n'
-    )
-
-    parser.add_argument(
-        '-r',
-        '--profile-rng',
-        action='store',
-        default='/usr/share/YaST2/schema/autoyast/rng/profile.rng',
-        help='Path to RELAX NG schema to use to validate XML\n(default: 
%(default)s)\n\n',
-        required=False,
-    )
-    parser.add_argument(
-        '-c',
-        '--cobbler',
-        action='store',
-        default='localhost',
-        help='Cobbler hostname or IP address (default: %(default)s)',
-        required=False,
-    )
-    parser.add_argument(
-        '-P',
-        '--product',
-        action='store',
-        default='',
-        help='Product to check/validate against, needs yast2-schemas package 
(see --list option)',
-        required=False
-    )
-    parser.add_argument(
-        '-a',
-        '--arch',
-        action='store',
-        default='',
-        help='Architecture to check/validate against, needs yast2-schemas 
package (default: x86_64)\n\n',
-        required=False
-    )
-    parser.add_argument(
-        '--save', action='store_true', default=False,
-        help='Always store retrieved XML file, not only in error case'
-    )
-    parser.add_argument(
-        '-v', '--verbose', action='count', help='Raise verbosity level \n-v 
info, -vv debug e.g. to see URL from retrieved autoyast file'
-    )
-    args = parser.parse_args(cliargs)
-
-    # Setup logging and the log level according to the '-v' option
-    dictConfig(DEFAULT_LOGGING_DICT)
-    log.setLevel(LOGLEVELS.get(args.verbose, logging.DEBUG))
-    log.debug('CLI args: %s', args)
-
-    if args.arch and not args.product:
-        log.error("-a/--arch option needs a -P/--product option")
-        sys.exit(2)
-    if not args.arch:
-        # Need to set default here to check empty value above
-        args.arch = 'x86_64'
-    return args
-
-
-def get_content_from_url(url):
-    """Get content of a website and return it.
-
-    :param url: URL to get content from
-    :returns: content of URL
-    :rtype: bool
-
-    """
-    with urlopen(url) as xml_site:
-        site_content = xml_site.read().decode('utf-8')
-    return site_content
-
-def list_products():
-
-    product = {}
-    product_folders = glob.glob(PROFILE_GLOB)
-    print("\nList of supported distributions and architectures:\n")
-    print("Product")
-    print("[ Architectures, ]\n")
-    for f in product_folders:
-        archs = []
-        arch_folders = glob.glob("%s/*" % f)
-        for a in arch_folders:
-            archs.append(os.path.basename(a))
-        if archs:
-            print(os.path.basename(f))
-            print(archs)
-            print()
-            product[os.path.basename(f)] = archs
-
-def get_rng(args):
-    """Get profile.rng file location depending on CLI args.
-
-    :param args: arguments passed to CLI
-    :returns: autoyast XML
-    :rtype: str
-
-    """
-    profile_rng = None
-
-    if args.product:
-        profile_rng = PROFILE_LOCATION.format(args.product, args.arch)
-    else:
-        profile_rng = args.profile_rng
-    if not os.path.isfile(profile_rng):
-        raise IOError("Cannot locate %s" % profile_rng)
-    return profile_rng
-
-def get_xml(args):
-    """Get XML string from different sources, depending on CLI args.
-
-    :param args: arguments passed to CLI
-    :returns: autoyast XML
-    :rtype: str
-
-    """
-    xml = None
-
-    if args.url:
-        xml = get_content_from_url(args.url)
-    elif args.cobbler_system:
-        url = COBBLER_XML_S_URL.format(args.cobbler, args.cobbler_system)
-        log.info('Try to download XML content located at URL: %s', url)
-        xml = get_content_from_url(url)
-    elif args.cobbler_profile:
-        url = COBBLER_XML_P_URL.format(args.cobbler, args.cobbler_profile)
-        log.info('Try to download XML content located at URL: %s', url)
-        xml = get_content_from_url(url)
-    elif args.file:
-        with open(args.file) as xml_file:
-            xml = xml_file.read()
-    else:
-        log.error(
-            'No autoyast.xml source specified. Use either -u, -f or -p and -s 
options'
-        )
-    return xml.strip()
-
-
-def validate_xml(args, xml, profile_rng):
-    """Check xml for errors with xmllint.
-
-    :param args: arguments passed to CLI
-    :param xml: autoyast XML as string
-    :returns: returns: returns: return if autoyast XML validates
-    :rtype: bool
-
-    """
-    # check xml syntax with xmllint
-    success = True
-    log_delim = "---------------------------------------------------------"
-
-    command = ['xmllint', '--noout', '--relaxng', profile_rng, '/dev/stdin']
-    process = Popen(
-        command,
-        stdout=PIPE,
-        stderr=PIPE,
-        stdin=PIPE
-    )
-    stdout, stderr = process.communicate(input=xml.encode())
-    log.debug('xmllint return code: %d', process.returncode)
-    if process.returncode:
-        log.warning("xmllint output %s", log_delim)
-        log.warning('stderr: %s', str(stderr, encoding='utf-8'))
-        log.warning('stdout: %s', str(stdout, encoding='utf-8'))
-        log.warning("xmllint output %s", log_delim)
-        success = False
-
-    command = ['jing', profile_rng, '/dev/stdin']
-    # check RELAX NG schema with jing
-    process = Popen(
-        command,
-        stdout=PIPE,
-        stderr=PIPE,
-        stdin=PIPE,
-    )
-    stdout, stderr = process.communicate(input=xml.encode())
-    log.debug('jing return code: %d', process.returncode)
-    if process.returncode:
-        log.warning("jing output    %s", log_delim)
-        log.warning('stderr: %s', str(stderr, encoding='utf-8'))
-        log.warning('stdout: %s', str(stdout, encoding='utf-8'))
-        log.warning("jing output    %s", log_delim)
-        success = False
-
-    if success:
-        print("XML file successfully parsed - No errors found")
-
-    if not success or args.save:
-        temp = tempfile.NamedTemporaryFile(prefix="autoyast_xml_validator_", 
delete=False)
-        temp.write(xml.encode())
-        temp.close()
-        if not success:
-            raise SyntaxError('XML has wrong Syntax. XML file store here: %s' 
% temp.name)
-        else:
-            print("XML file stored: %s" % temp.name)
-
-    """
-    A returncode of 0 means "good". But the function should return True
-    if the XML is valid. As 0 is falsy in Python, bool(0) would return
-    False. Thus it is needed to invert the bool with a 'not' to adapt it
-    to our needs.
-    return True if both checks have a returncode of 0
-    """
-    return success
-
-
-if __name__ == '__main__':
-    RETURN_CODE = 0
-    args = parse()
-    try:
-        if args.list:
-            list_products()
-        else:
-            profile_rng = get_rng(args)
-            xml = get_xml(args)
-            if not validate_xml(args, xml, profile_rng):
-                RETURN_CODE = 99
-    except IOError as err:
-        log.error('IOError: %s', err)
-        RETURN_CODE = 3
-    except SyntaxError as err:
-        log.error('SyntaxError: %s', err)
-        RETURN_CODE = 2
-    except Exception:
-        log.exception("Unknown Error")
-        RETURN_CODE = 1
-
-    sys.exit(RETURN_CODE)
-
-# EOF

++++++ autoyast_xml_validator.obsinfo ++++++
--- /var/tmp/diff_new_pack.18D44I/_old  2021-07-14 23:59:15.965391394 +0200
+++ /var/tmp/diff_new_pack.18D44I/_new  2021-07-14 23:59:15.965391394 +0200
@@ -1,5 +1,5 @@
 name: autoyast_xml_validator
-version: 1.0.6+git920f29b
-mtime: 1625846844
-commit: 920f29bd0e29481de94fd5e007777e564a1bb3c7
+version: 1.0.9+gite8164d1
+mtime: 1626254163
+commit: e8164d1ca540dbe046eb06c803cc3ff5b71de85d
 

Reply via email to