From 9f2eef4b0d6ec926a84f881b879e69978f604dc8 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 21:23:02 +0100 Subject: Be explicit about Python 3 in shebang lines and docs Signed-off-by: Sebastian Pipping --- docs/README | 2 +- metagen/main.py | 2 +- metagen/meta_unittest.py | 2 +- metagen/metagenerator.py | 2 +- setup.py | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/README b/docs/README index 3a40768..81bb6d2 100644 --- a/docs/README +++ b/docs/README @@ -7,7 +7,7 @@ metagen is a command line tool that writes a Gentoo metadata.xml file in the current working directory. The metagen package also has a metagenerator class that can be used -from Python to create metadata.xml files easily: +from Python 3 to create metadata.xml files easily: from metagen.metagenerator import MyMetadata diff --git a/metagen/main.py b/metagen/main.py index c642b12..973822d 100755 --- a/metagen/main.py +++ b/metagen/main.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 """ diff --git a/metagen/meta_unittest.py b/metagen/meta_unittest.py index 73b5072..15caf8b 100644 --- a/metagen/meta_unittest.py +++ b/metagen/meta_unittest.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 from metagenerator import MyMetadata diff --git a/metagen/metagenerator.py b/metagen/metagenerator.py index b08839b..caecf87 100755 --- a/metagen/metagenerator.py +++ b/metagen/metagenerator.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import sys diff --git a/setup.py b/setup.py index 5149fe2..5bd0e09 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ NAME: setup.py SYNOPSIS: - python setup.py [options] [command] + python3 setup.py [options] [command] DESCRIPTION: Using distutils "setup", build, install, or make tarball of the package. @@ -24,9 +24,9 @@ EXAMPLES: (cp myfile-0.1.tar.gz here) gzip -cd myfile-0.1.tar.gz | tar xvf - cd myfile-0.1 - python setup.py build - python setup.py install - python setup.py sdist + python3 setup.py build + python3 setup.py install + python3 setup.py sdist """ import os,sys,re,string,getopt,shutil,commands,glob -- cgit v1.2.3-65-gdbad From 66814e2e759b106350fbe3d8ee16eaf42dc83382 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 21:25:16 +0100 Subject: Mass-apply 2to3 Signed-off-by: Sebastian Pipping --- metagen/main.py | 38 +++++++++++++++++++------------------- metagen/meta_unittest.py | 2 +- metagen/metagenerator.py | 20 ++++++++++---------- setup.py | 8 ++++---- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/metagen/main.py b/metagen/main.py index 973822d..987f7a0 100755 --- a/metagen/main.py +++ b/metagen/main.py @@ -16,7 +16,7 @@ import os import sys import tempfile from argparse import ArgumentParser -from commands import getstatusoutput +from subprocess import getstatusoutput from textwrap import dedent from portage import config @@ -39,18 +39,18 @@ def parse_echangelog_variable(name, email): try: e = os.environ["ECHANGELOG_USER"] except KeyError: - print red("!!! Environmental variable ECHANGELOG_USER not set.") - print red("!!! Set ECHANGELOG_USER or use -e and -n") + print(red("!!! Environmental variable ECHANGELOG_USER not set.")) + print(red("!!! Set ECHANGELOG_USER or use -e and -n")) sys.exit(1) try: my_email = e[e.find("<") +1:e.find(">")] except: - print red("!!! ECHANGELOG_USER not set properly") + print(red("!!! ECHANGELOG_USER not set properly")) sys.exit(1) try: my_name = e[0:e.find("<")-1] except: - print red("!!! ECHANGELOG_USER not set properly") + print(red("!!! ECHANGELOG_USER not set properly")) sys.exit(1) if email: email = "%s,%s" % (my_email, email) @@ -151,43 +151,43 @@ if __name__ == '__main__': if options.desc or options.name: if not options.email and not options.echangelog: - print red("!!! No maintainer's email address specified.") - print red("!!! Options -d and -n are only valid with -e or -m") + print(red("!!! No maintainer's email address specified.")) + print(red("!!! Options -d and -n are only valid with -e or -m")) sys.exit(1) if not options.email and not options.echangelog: - print red("!!! You must specify --echangelog|-m " + - "or maintainer's email address (-e)\n") + print(red("!!! You must specify --echangelog|-m " + + "or maintainer's email address (-e)\n")) sys.exit(1) if (options.email or options.echangelog) and not options.maintainer_type: - print red("!!! No maintainer type specified. Please pass one of the following, in addition:") + print(red("!!! No maintainer type specified. Please pass one of the following, in addition:")) for candidate in _VALID_MAINTAINER_TYPES: - print red("!!! --type %s" % candidate) + print(red("!!! --type %s" % candidate)) sys.exit(1) txt = generate_xml(options) error_status = validate_xml(txt) if error_status < 0: - print red("!!! Error - Invalid XML") - print red("!!! Please report this bug with the options you used and the output:") - print error_status - print txt + print(red("!!! Error - Invalid XML")) + print(red("!!! Please report this bug with the options you used and the output:")) + print(error_status) + print(txt) sys.exit(1) if options.verbose: - print "\n%s" % txt + print("\n%s" % txt) out_file = "./metadata.xml" if options.output: out_file = options.output if not options.no_write and os.path.exists(out_file): if not options.force: - print red("!!! File %s exists." % out_file) - print red("!!! Use -f to force overwrite.") + print(red("!!! File %s exists." % out_file)) + print(red("!!! Use -f to force overwrite.")) sys.exit(1) if not options.no_write: open("%s" % out_file, "w").writelines(txt) - print blue("%s written") % out_file + print(blue("%s written") % out_file) diff --git a/metagen/meta_unittest.py b/metagen/meta_unittest.py index 15caf8b..d54236a 100644 --- a/metagen/meta_unittest.py +++ b/metagen/meta_unittest.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -from metagenerator import MyMetadata +from .metagenerator import MyMetadata def test1(): diff --git a/metagen/metagenerator.py b/metagen/metagenerator.py index caecf87..87bd0f6 100755 --- a/metagen/metagenerator.py +++ b/metagen/metagenerator.py @@ -21,7 +21,7 @@ class MyMetadata(jaxml.XML_document): """Set maintainer(s)'s email, name, desc""" if len(types) != len(emails): if len(types) != 1: - print red("!!! Nbr maintainer types != nbr emails") + print(red("!!! Nbr maintainer types != nbr emails")) sys.exit(1) types = [types[0] for _ in emails] @@ -31,13 +31,13 @@ class MyMetadata(jaxml.XML_document): self.maintainer(type=types[i]).email(e) if names: if len(names) > len(emails): - print red("!!! Nbr names > nbr emails") + print(red("!!! Nbr names > nbr emails")) sys.exit(1) if i <= len(names) -1: self.name(names[i]) if descs: if len(descs) > len(emails): - print red("!!! Nbr descs > nbr emails") + print(red("!!! Nbr descs > nbr emails")) sys.exit(1) if i <= len(descs) -1: self.description(descs[i]) @@ -49,19 +49,19 @@ class MyMetadata(jaxml.XML_document): self.longdescription(longdesc) def do_tests(): - import meta_unittest + from . import meta_unittest fails = 0 for func in dir(meta_unittest): if func[0:4] == "test": try: - exec "print meta_unittest.%s.__name__ + ':'," % func - exec "print meta_unittest.%s.__doc__" % func - exec "print meta_unittest.%s()" % func + exec("print meta_unittest.%s.__name__ + ':'," % func) + exec("print meta_unittest.%s.__doc__" % func) + exec("print meta_unittest.%s()" % func) except: fails += 1 - print "Test %s failed:" % func - print sys.exc_type, sys.exc_value - print "%s tests failed." % fails + print("Test %s failed:" % func) + print(sys.exc_info()[0], sys.exc_info()[1]) + print("%s tests failed." % fails) if __name__ == "__main__": do_tests() diff --git a/setup.py b/setup.py index 5bd0e09..797a83a 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ EXAMPLES: python3 setup.py sdist """ -import os,sys,re,string,getopt,shutil,commands,glob +import os,sys,re,string,getopt,shutil,subprocess,glob from distutils.core import setup,Extension from metagen.version import __version__ @@ -58,10 +58,10 @@ def debug(ftn,txt): def fatal(ftn,txt): msg="%s.%s:FATAL:%s\n" % (modname,ftn,txt) - raise SystemExit, msg + raise SystemExit(msg) def usage(): - print __doc__ + print(__doc__) #============================= def main(): @@ -87,7 +87,7 @@ if __name__ == '__main__': usage() sys.exit(0) elif opt[0]=='-v' or opt[0]=='--version': - print modname+": version="+version + print(modname+": version="+version) elif opt[0]=='--exec-prefix': exec_prefix=opt[1] -- cgit v1.2.3-65-gdbad From 072f84374cad2ff4347474d1edf05a5dff44970e Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 22:18:16 +0100 Subject: metagenerator.py: Fix execution of tests for Python 3 Signed-off-by: Sebastian Pipping --- metagen/metagenerator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/metagen/metagenerator.py b/metagen/metagenerator.py index 87bd0f6..fd00caa 100755 --- a/metagen/metagenerator.py +++ b/metagen/metagenerator.py @@ -49,14 +49,14 @@ class MyMetadata(jaxml.XML_document): self.longdescription(longdesc) def do_tests(): - from . import meta_unittest + from metagen import meta_unittest fails = 0 for func in dir(meta_unittest): if func[0:4] == "test": try: - exec("print meta_unittest.%s.__name__ + ':'," % func) - exec("print meta_unittest.%s.__doc__" % func) - exec("print meta_unittest.%s()" % func) + exec("print(meta_unittest.%s.__name__ + ':', end='')" % func) + exec("print(meta_unittest.%s.__doc__)" % func) + exec("print(meta_unittest.%s())" % func) except: fails += 1 print("Test %s failed:" % func) -- cgit v1.2.3-65-gdbad From 4efc69a52365dd5fbb5dad9dee6ee68c86b333e7 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 23:09:24 +0100 Subject: setup.py: Get some cruft out, use setuptools Signed-off-by: Sebastian Pipping --- setup.py | 71 +++++++++++++++------------------------------------------------- 1 file changed, 16 insertions(+), 55 deletions(-) mode change 100644 => 100755 setup.py diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 797a83a..4c546e9 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ SYNOPSIS: python3 setup.py [options] [command] DESCRIPTION: - Using distutils "setup", build, install, or make tarball of the package. + Using setuptools "setup", build, install, or make tarball of the package. OPTIONS: See Distutils documentation for details on options and commands. @@ -29,17 +29,12 @@ EXAMPLES: python3 setup.py sdist """ -import os,sys,re,string,getopt,shutil,subprocess,glob -from distutils.core import setup,Extension +import glob +from setuptools import setup from metagen.version import __version__ -modname='setup' -debug_p=0 - pkgname='metagen' -#version=string.strip(open("VERSION").readline()) version = __version__ -exec_prefix=sys.exec_prefix description = "Metadata.xml Generator for Ebuilds" author = "Rob Cakebread" author_email = "pythonhead@gentoo.org" @@ -50,56 +45,22 @@ packages=['metagen'] package_data={"metagen" : ["test_cli"]} data_files=[("share/doc/%s-%s" % ("metagen", version), glob.glob("docs/*"))] -#===utilities========================== -def debug(ftn,txt): - if debug_p: - sys.stdout.write("%s.%s:%s\n" % (modname,ftn,txt)) - sys.stdout.flush() - -def fatal(ftn,txt): - msg="%s.%s:FATAL:%s\n" % (modname,ftn,txt) - raise SystemExit(msg) - -def usage(): - print(__doc__) -#============================= def main(): - setup (#---meta-data--- - name = pkgname, - version = version, - description = description, - author = author, - author_email = author_email, - url=url, - license = license, + setup( + name = pkgname, + version = version, + description = description, + author = author, + author_email = author_email, + url=url, + license = license, - #---scripts,modules and packages--- - packages = packages, - data_files = data_files, - ) -#============================== -if __name__ == '__main__': - opts,pargs=getopt.getopt(sys.argv[1:],'hv', - ['help','version','exec-prefix']) - for opt in opts: - if opt[0]=='-h' or opt[0]=='--help': - usage() - sys.exit(0) - elif opt[0]=='-v' or opt[0]=='--version': - print(modname+": version="+version) - elif opt[0]=='--exec-prefix': - exec_prefix=opt[1] + packages = packages, + data_files = data_files, + package_data = package_data, + ) - for arg in pargs: - if arg=='test': - do_test() - sys.exit(0) - elif arg=='doc': - do_doc() - sys.exit(0) - else: - pass +if __name__ == '__main__': main() - -- cgit v1.2.3-65-gdbad From 6064d4f06db32ffe8fa0a6e09f186102c4f1ff9f Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 23:01:18 +0100 Subject: Migrate XML writer from dead jaxml to lxml.etree Needed for migration to Python 3 Signed-off-by: Sebastian Pipping --- metagen/metagenerator.py | 58 ++++++++++++++++++++++++++++++++++++------------ setup.py | 4 ++++ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/metagen/metagenerator.py b/metagen/metagenerator.py index fd00caa..e733997 100755 --- a/metagen/metagenerator.py +++ b/metagen/metagenerator.py @@ -1,21 +1,26 @@ #!/usr/bin/python3 - import sys +from xml.dom import minidom -import jaxml +from lxml import etree +from lxml.etree import Element, SubElement from portage.output import red -class MyMetadata(jaxml.XML_document): +class MyMetadata: """Create Gentoo Linux metadata.xml""" + class _Maintainer: + def __init__(self, type_=None, email=None, name=None, description=None): + self.type_ = type_ + self.email = email + self.name = name + self.description = description + def __init__(self): - jaxml.XML_document.__init__(self, "1.0", "UTF-8") - self._indentstring("\t") - self._text('') - self.pkgmetadata() + self._maintainers = [] + self._long_description = None def set_maintainer(self, emails, names, descs, types): """Set maintainer(s)'s email, name, desc""" @@ -27,26 +32,51 @@ class MyMetadata(jaxml.XML_document): i = 0 for e in emails: - self._push("maintainer_level") - self.maintainer(type=types[i]).email(e) + maintainer = self._Maintainer(type_=types[i], email=e) if names: if len(names) > len(emails): print(red("!!! Nbr names > nbr emails")) sys.exit(1) if i <= len(names) -1: - self.name(names[i]) + maintainer.name = names[i] if descs: if len(descs) > len(emails): print(red("!!! Nbr descs > nbr emails")) sys.exit(1) if i <= len(descs) -1: - self.description(descs[i]) - self._pop("maintainer_level") + maintainer.description = descs[i] i += 1 + self._maintainers.append(maintainer) def set_longdescription(self, longdesc): """Set package's long description.""" - self.longdescription(longdesc) + self._long_description = longdesc + + def __str__(self): + doctype = '' + root = Element('pkgmetadata') + + for maintainer_data in self._maintainers: + maintainer_element = SubElement(root, 'maintainer') + maintainer_element.set('type', maintainer_data.type_) + if maintainer_data.email: + SubElement(maintainer_element, 'email').text = maintainer_data.email + if maintainer_data.name: + SubElement(maintainer_element, 'name').text = maintainer_data.name + if maintainer_data.description: + SubElement(maintainer_element, 'description').text = maintainer_data.description + + if self._long_description: + long_description = SubElement(root, 'longdescription') + long_description.text = self._long_description + + xml_text = etree.tostring(root, xml_declaration=True, doctype=doctype) + + # Re-write indentation to tabulators + # (for backwards compatibility and smaller diffs with existing files) + reparsed = minidom.parseString(xml_text) + return reparsed.toprettyxml(indent='\t', encoding='UTF-8').decode() + def do_tests(): from metagen import meta_unittest diff --git a/setup.py b/setup.py index 4c546e9..ff39677 100755 --- a/setup.py +++ b/setup.py @@ -56,6 +56,10 @@ def main(): url=url, license = license, + install_requires = [ + 'lxml', + ], + packages = packages, data_files = data_files, package_data = package_data, -- cgit v1.2.3-65-gdbad From 25b318fdf24cc7493e662c8755275c4ade8eecb2 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 23:16:30 +0100 Subject: Bump version to 0.7.0 Signed-off-by: Sebastian Pipping --- metagen/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metagen/version.py b/metagen/version.py index 074d83e..2426eb8 100644 --- a/metagen/version.py +++ b/metagen/version.py @@ -1 +1 @@ -__version__="0.6.6" +__version__="0.7.0" -- cgit v1.2.3-65-gdbad From 4435eb6300d1901a48b72b2cb380e63220c578fa Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 23:28:12 +0100 Subject: Support "python -m metagen" Signed-off-by: Sebastian Pipping --- metagen/__main__.py | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++ metagen/main.py | 193 --------------------------------------------------- metagen/test_cli | 2 +- 3 files changed, 197 insertions(+), 194 deletions(-) create mode 100755 metagen/__main__.py delete mode 100755 metagen/main.py diff --git a/metagen/__main__.py b/metagen/__main__.py new file mode 100755 index 0000000..0452771 --- /dev/null +++ b/metagen/__main__.py @@ -0,0 +1,196 @@ +#!/usr/bin/python3 + +""" + +NAME - metagen +SYNOPSIS - Adds metadata.xml to current directory +AUTHOR - Rob Cakebread +AUTHOR - Jesus Rivero +USE - metagen --help +EXAMPLES - man metagen + +""" + +import re +import os +import sys +import tempfile +from argparse import ArgumentParser +from subprocess import getstatusoutput +from textwrap import dedent + +from portage import config +from portage.exception import FileNotFound +from portage.output import red, blue, yellow + +from metagen.version import __version__ +from metagen import metagenerator + +PORTDIR = config(local_config=False)["PORTDIR"] + +# GLEP 67 +_MAINTAINER_TYPE_PERSON = 'person' +_MAINTAINER_TYPE_PROJECT = 'project' +_MAINTAINER_TYPE_UNKNOWN = 'unknown' +_VALID_MAINTAINER_TYPES = (_MAINTAINER_TYPE_PERSON, _MAINTAINER_TYPE_PROJECT, _MAINTAINER_TYPE_UNKNOWN) + +def parse_echangelog_variable(name, email): + """Extract developer name and email from ECHANGELOG_USER variable""" + try: + e = os.environ["ECHANGELOG_USER"] + except KeyError: + print(red("!!! Environmental variable ECHANGELOG_USER not set.")) + print(red("!!! Set ECHANGELOG_USER or use -e and -n")) + sys.exit(1) + try: + my_email = e[e.find("<") +1:e.find(">")] + except: + print(red("!!! ECHANGELOG_USER not set properly")) + sys.exit(1) + try: + my_name = e[0:e.find("<")-1] + except: + print(red("!!! ECHANGELOG_USER not set properly")) + sys.exit(1) + if email: + email = "%s,%s" % (my_email, email) + else: + email = my_email + if name: + name = "%s,%s" % (my_name, name) + else: + name = my_name + return name, email + +def generate_xml(options): + """Returns metadata.xml text""" + + metadata = metagenerator.MyMetadata() + + if options.echangelog: + (options.name, options.email) = \ + parse_echangelog_variable(options.name, options.email) + + if options.email: + names, descs = [], [] + if options.name: + names = options.name.split(",") + if options.desc: + descs = options.desc.split(",") + maintainer_types = options.maintainer_type.split(",") + metadata.set_maintainer(options.email.split(","), + names, + descs, + maintainer_types, + ) + + if options.long: + metadata.set_longdescription(options.long) + + return "%s" % metadata + +def validate_xml(my_xml): + """Test for valid XML""" + #TODO validate against DTD + #This just makes sure its valid XML of some sort. + #Probably not necessary since repoman validates against DTD? + re_escape_quotes = re.compile('"') + s = re_escape_quotes.sub('\\"', my_xml) + cmd = "echo \"%s\" | xmllint --valid - 2>&1 > /dev/null" % s + return getstatusoutput(cmd)[0] + + +def _check_maintainer_type_list(text): + for candidate in text.split(','): + if candidate not in _VALID_MAINTAINER_TYPES: + raise ValueError('"%s" not a valid maintainer type' % candidate) + return text + +_check_maintainer_type_list.__name__ = 'maintainer type' + + +def main(): + parser = ArgumentParser(prog='metagen') + parser.add_argument('--version', action='version', version='%(prog)s ' + __version__) + + maintainer = parser.add_argument_group(title='maintainer arguments') + maintainer.add_argument("--email", "-e", action="store", + help="Maintainer's email address") + maintainer.add_argument("--name", "-n", action="store", + help="Maintainer's name") + maintainer.add_argument("--echangelog", "-m", action="store_true", + default=False, + help="Use name and email address from ECHANGELOG_USER "+ + "environmental variable. "+ + "This is a shortcut for -e -n ") + maintainer.add_argument("--desc", "-d", action="store", + help="Description of maintainership") + maintainer.add_argument("--type", "-t", dest='maintainer_type', metavar='TYPE', + type=_check_maintainer_type_list, + help="Maintainer type as of GLEP 67; valid values are: %s" \ + % ', '.join('"%s"' % e for e in _VALID_MAINTAINER_TYPES)) + + package = parser.add_argument_group(title='package arguments', description=None) + package.add_argument("--long", "-l", action="store", + help="Long description of package.") + + operation = parser.add_argument_group(title='operation arguments', description=None) + operation.add_argument("--output", "-o", action="store", + help="Specify location of output file.") + operation.add_argument("--force", "-f", action="store_true", default=False, + help="Force overwrite of existing metadata.") + operation.add_argument("--verbose", "-v", action="store_true", default=True, + help="Verbose. Output of file to stdout. (default)") + operation.add_argument("--quiet", "-q", action="store_false", dest="verbose", + help="Squelch output of file to stdout.") + operation.add_argument("-Q", action="store_true", dest="no_write", + default=False, + help="Do not write file to disk.") + + options = parser.parse_args() + + if options.desc or options.name: + if not options.email and not options.echangelog: + print(red("!!! No maintainer's email address specified.")) + print(red("!!! Options -d and -n are only valid with -e or -m")) + sys.exit(1) + + if not options.email and not options.echangelog: + print(red("!!! You must specify --echangelog|-m " + + "or maintainer's email address (-e)\n")) + sys.exit(1) + + if (options.email or options.echangelog) and not options.maintainer_type: + print(red("!!! No maintainer type specified. Please pass one of the following, in addition:")) + for candidate in _VALID_MAINTAINER_TYPES: + print(red("!!! --type %s" % candidate)) + sys.exit(1) + + txt = generate_xml(options) + + error_status = validate_xml(txt) + if error_status < 0: + print(red("!!! Error - Invalid XML")) + print(red("!!! Please report this bug with the options you used and the output:")) + print(error_status) + print(txt) + sys.exit(1) + + if options.verbose: + print("\n%s" % txt) + + out_file = "./metadata.xml" + if options.output: + out_file = options.output + if not options.no_write and os.path.exists(out_file): + if not options.force: + print(red("!!! File %s exists." % out_file)) + print(red("!!! Use -f to force overwrite.")) + sys.exit(1) + if not options.no_write: + open("%s" % out_file, "w").writelines(txt) + print(blue("%s written") % out_file) + + +if __name__ == '__main__': + main() diff --git a/metagen/main.py b/metagen/main.py deleted file mode 100755 index 987f7a0..0000000 --- a/metagen/main.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/python3 - -""" - -NAME - metagen -SYNOPSIS - Adds metadata.xml to current directory -AUTHOR - Rob Cakebread -AUTHOR - Jesus Rivero -USE - metagen --help -EXAMPLES - man metagen - -""" - -import re -import os -import sys -import tempfile -from argparse import ArgumentParser -from subprocess import getstatusoutput -from textwrap import dedent - -from portage import config -from portage.exception import FileNotFound -from portage.output import red, blue, yellow - -from metagen.version import __version__ -from metagen import metagenerator - -PORTDIR = config(local_config=False)["PORTDIR"] - -# GLEP 67 -_MAINTAINER_TYPE_PERSON = 'person' -_MAINTAINER_TYPE_PROJECT = 'project' -_MAINTAINER_TYPE_UNKNOWN = 'unknown' -_VALID_MAINTAINER_TYPES = (_MAINTAINER_TYPE_PERSON, _MAINTAINER_TYPE_PROJECT, _MAINTAINER_TYPE_UNKNOWN) - -def parse_echangelog_variable(name, email): - """Extract developer name and email from ECHANGELOG_USER variable""" - try: - e = os.environ["ECHANGELOG_USER"] - except KeyError: - print(red("!!! Environmental variable ECHANGELOG_USER not set.")) - print(red("!!! Set ECHANGELOG_USER or use -e and -n")) - sys.exit(1) - try: - my_email = e[e.find("<") +1:e.find(">")] - except: - print(red("!!! ECHANGELOG_USER not set properly")) - sys.exit(1) - try: - my_name = e[0:e.find("<")-1] - except: - print(red("!!! ECHANGELOG_USER not set properly")) - sys.exit(1) - if email: - email = "%s,%s" % (my_email, email) - else: - email = my_email - if name: - name = "%s,%s" % (my_name, name) - else: - name = my_name - return name, email - -def generate_xml(options): - """Returns metadata.xml text""" - - metadata = metagenerator.MyMetadata() - - if options.echangelog: - (options.name, options.email) = \ - parse_echangelog_variable(options.name, options.email) - - if options.email: - names, descs = [], [] - if options.name: - names = options.name.split(",") - if options.desc: - descs = options.desc.split(",") - maintainer_types = options.maintainer_type.split(",") - metadata.set_maintainer(options.email.split(","), - names, - descs, - maintainer_types, - ) - - if options.long: - metadata.set_longdescription(options.long) - - return "%s" % metadata - -def validate_xml(my_xml): - """Test for valid XML""" - #TODO validate against DTD - #This just makes sure its valid XML of some sort. - #Probably not necessary since repoman validates against DTD? - re_escape_quotes = re.compile('"') - s = re_escape_quotes.sub('\\"', my_xml) - cmd = "echo \"%s\" | xmllint --valid - 2>&1 > /dev/null" % s - return getstatusoutput(cmd)[0] - - -def _check_maintainer_type_list(text): - for candidate in text.split(','): - if candidate not in _VALID_MAINTAINER_TYPES: - raise ValueError('"%s" not a valid maintainer type' % candidate) - return text - -_check_maintainer_type_list.__name__ = 'maintainer type' - - -if __name__ == '__main__': - parser = ArgumentParser(prog='metagen') - parser.add_argument('--version', action='version', version='%(prog)s ' + __version__) - - maintainer = parser.add_argument_group(title='maintainer arguments') - maintainer.add_argument("--email", "-e", action="store", - help="Maintainer's email address") - maintainer.add_argument("--name", "-n", action="store", - help="Maintainer's name") - maintainer.add_argument("--echangelog", "-m", action="store_true", - default=False, - help="Use name and email address from ECHANGELOG_USER "+ - "environmental variable. "+ - "This is a shortcut for -e -n ") - maintainer.add_argument("--desc", "-d", action="store", - help="Description of maintainership") - maintainer.add_argument("--type", "-t", dest='maintainer_type', metavar='TYPE', - type=_check_maintainer_type_list, - help="Maintainer type as of GLEP 67; valid values are: %s" \ - % ', '.join('"%s"' % e for e in _VALID_MAINTAINER_TYPES)) - - package = parser.add_argument_group(title='package arguments', description=None) - package.add_argument("--long", "-l", action="store", - help="Long description of package.") - - operation = parser.add_argument_group(title='operation arguments', description=None) - operation.add_argument("--output", "-o", action="store", - help="Specify location of output file.") - operation.add_argument("--force", "-f", action="store_true", default=False, - help="Force overwrite of existing metadata.") - operation.add_argument("--verbose", "-v", action="store_true", default=True, - help="Verbose. Output of file to stdout. (default)") - operation.add_argument("--quiet", "-q", action="store_false", dest="verbose", - help="Squelch output of file to stdout.") - operation.add_argument("-Q", action="store_true", dest="no_write", - default=False, - help="Do not write file to disk.") - - options = parser.parse_args() - - if options.desc or options.name: - if not options.email and not options.echangelog: - print(red("!!! No maintainer's email address specified.")) - print(red("!!! Options -d and -n are only valid with -e or -m")) - sys.exit(1) - - if not options.email and not options.echangelog: - print(red("!!! You must specify --echangelog|-m " + - "or maintainer's email address (-e)\n")) - sys.exit(1) - - if (options.email or options.echangelog) and not options.maintainer_type: - print(red("!!! No maintainer type specified. Please pass one of the following, in addition:")) - for candidate in _VALID_MAINTAINER_TYPES: - print(red("!!! --type %s" % candidate)) - sys.exit(1) - - txt = generate_xml(options) - - error_status = validate_xml(txt) - if error_status < 0: - print(red("!!! Error - Invalid XML")) - print(red("!!! Please report this bug with the options you used and the output:")) - print(error_status) - print(txt) - sys.exit(1) - - if options.verbose: - print("\n%s" % txt) - - out_file = "./metadata.xml" - if options.output: - out_file = options.output - if not options.no_write and os.path.exists(out_file): - if not options.force: - print(red("!!! File %s exists." % out_file)) - print(red("!!! Use -f to force overwrite.")) - sys.exit(1) - if not options.no_write: - open("%s" % out_file, "w").writelines(txt) - print(blue("%s written") % out_file) - diff --git a/metagen/test_cli b/metagen/test_cli index 959388d..fb394ca 100755 --- a/metagen/test_cli +++ b/metagen/test_cli @@ -1,6 +1,6 @@ #!/bin/bash metagen() { - PYTHONPATH=. ./metagen/main.py "$@" + PYTHONPATH=. python3 -m metagen "$@" } handle_error() { -- cgit v1.2.3-65-gdbad From f2443f9dcb21c7a1e1095df21a90e85a386453e1 Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Sat, 25 Jan 2020 23:28:29 +0100 Subject: setup.py: Generate entrypoint script Signed-off-by: Sebastian Pipping --- setup.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/setup.py b/setup.py index ff39677..838c27a 100755 --- a/setup.py +++ b/setup.py @@ -63,6 +63,12 @@ def main(): packages = packages, data_files = data_files, package_data = package_data, + + entry_points = { + 'console_scripts': [ + "metagen = metagen.__main__:main", + ], + } ) -- cgit v1.2.3-65-gdbad