Hello community, here is the log from the commit of package kapidox for openSUSE:Factory checked in at 2016-08-22 14:00:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kapidox (Old) and /work/SRC/openSUSE:Factory/.kapidox.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kapidox" Changes: -------- --- /work/SRC/openSUSE:Factory/kapidox/kapidox.changes 2016-07-16 22:13:30.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.kapidox.new/kapidox.changes 2016-08-22 14:00:38.000000000 +0200 @@ -1,0 +2,10 @@ +Sun Aug 7 21:50:16 UTC 2016 - hrvoje.sen...@gmail.com + +- Update to 5.25.0 + * Qt >= 5.5 is now required + * Many improvements to the output formatting + * Mainpage.dox has now higher priority than README.md + * For more details please see: + https://www.kde.org/announcements/kde-frameworks-5.25.0.php + +------------------------------------------------------------------- Old: ---- kapidox-5.24.0.tar.xz New: ---- kapidox-5.25.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kapidox.spec ++++++ --- /var/tmp/diff_new_pack.NpJdvT/_old 2016-08-22 14:00:39.000000000 +0200 +++ /var/tmp/diff_new_pack.NpJdvT/_new 2016-08-22 14:00:39.000000000 +0200 @@ -16,9 +16,9 @@ # -%define _tar_path 5.24 +%define _tar_path 5.25 Name: kapidox -Version: 5.24.0 +Version: 5.25.0 Release: 0 Requires: doxygen BuildRequires: fdupes ++++++ kapidox-5.24.0.tar.xz -> kapidox-5.25.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/README.md new/kapidox-5.25.0/README.md --- old/kapidox-5.24.0/README.md 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/README.md 2016-08-06 01:24:22.000000000 +0200 @@ -14,6 +14,7 @@ ## Dependencies +### Required Python 2 or 3 is required to run the scripts. Whichever version of python you use needs to have the jinja2 and yaml (or pyyaml) modules. @@ -21,12 +22,17 @@ pip install --user PyYAML jinja2 +Of course, you need Doxygen! + +### Optional +Doxyqml and doxypypy might be needed to let doxygen document respectevely qml +and python sources. + To generate the dependency diagrams, you need the Graphviz Python bindings. They are currently not available from pip, but most distributions provide them. You can get binaries and source archives from <http://www.graphviz.org/Download.php>. - ## Installation Unlike almost every other KDE module, kapidox does not use CMake. This is diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/setup.py new/kapidox-5.25.0/setup.py --- old/kapidox-5.24.0/setup.py 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/setup.py 2016-08-06 01:24:22.000000000 +0200 @@ -6,7 +6,7 @@ setup( name='kapidox', - version='5.24.0', + version='5.25.0', description='KDE API documentation generation tools', maintainer = 'Alex Merry', maintainer_email = 'alex.me...@kde.org', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/__init__.py new/kapidox-5.25.0/src/kapidox/__init__.py --- old/kapidox-5.24.0/src/kapidox/__init__.py 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/__init__.py 2016-08-06 01:24:22.000000000 +0200 @@ -1,2 +1,4 @@ - -from . import generator, preprocessing, utils, argparserutils +## @package kapidox +# +# The root of the module +# \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/argparserutils.py new/kapidox-5.25.0/src/kapidox/argparserutils.py --- old/kapidox-5.24.0/src/kapidox/argparserutils.py 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/argparserutils.py 2016-08-06 01:24:22.000000000 +0200 @@ -37,7 +37,7 @@ description='Generate API documentation for the KDE Products' ) group = add_sources_group(parser) - group.add_argument('frameworksdir', + group.add_argument('sourcesdir', help='Location of the sources.') group.add_argument('--depdiagram-dot-dir', help='Generate dependency diagrams, using the .dot files from DIR.', @@ -55,8 +55,8 @@ 'See <http://www.graphviz.org/Download.php>.') exit(1) - if not os.path.isdir(args.frameworksdir): - logging.error(args.frameworksdir + " is not a directory") + if not os.path.isdir(args.sourcesdir): + logging.error(args.sourcesdir + " is not a directory") exit(2) return args @@ -68,7 +68,7 @@ def add_output_group(parser): group = parser.add_argument_group('output options') - group.add_argument('--title', default='KDE API Documentation', + group.add_argument('--title', default='API Documentation', help='String to use for page titles.') group.add_argument('--man-pages', action='store_true', help='Generate man page documentation.') @@ -77,7 +77,7 @@ group.add_argument('--searchengine', action='store_true', help="Enable Doxygen's search engine feature.") group.add_argument('--api-searchbox', action='store_true', - help="Enable the API searchbox (only useful for api.kde.org).") + help="Enable the API searchbox.") return group diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/data/Doxyfile.global new/kapidox-5.25.0/src/kapidox/data/Doxyfile.global --- old/kapidox-5.24.0/src/kapidox/data/Doxyfile.global 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/data/Doxyfile.global 2016-08-06 01:24:22.000000000 +0200 @@ -117,7 +117,7 @@ # Use doxyqml filter for qml files FILTER_PATTERNS = *.qml=doxyqml - +EXTENSION_MAPPING = qml=C++ USE_MDFILE_AS_MAINPAGE = README.md #--------------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/data/htmlresource/kde.css new/kapidox-5.25.0/src/kapidox/data/htmlresource/kde.css --- old/kapidox-5.24.0/src/kapidox/data/htmlresource/kde.css 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/data/htmlresource/kde.css 2016-08-06 01:24:22.000000000 +0200 @@ -102,17 +102,22 @@ font-weight: bold; } -dt a { +.menu_box dl { + padding: 0 0 0 10px; +} + +.menu_box dt a { font-weight: bold; } -dt { +.menu_box dt { + font-weight: bold; margin-top: 0.8em; } -dt:first-child { +.menu_box dt:first-child { margin-top: 0; } -dd { +.menu_box dd { margin-left: 1em; color: #323232; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/data/templates/base.html new/kapidox-5.25.0/src/kapidox/data/templates/base.html --- old/kapidox-5.24.0/src/kapidox/data/templates/base.html 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/data/templates/base.html 2016-08-06 01:24:22.000000000 +0200 @@ -27,7 +27,9 @@ <script type="text/javascript" src="dynsections.js"></script> <link rel="shortcut icon" href="{{resources}}/favicon.ico" /> <link rel="icon" href="{{resources}}/favicon.ico" /> +{% if doxygencss %} <link rel="stylesheet" type="text/css" href="{{doxygencss}}" /> +{% endif %} <link rel="stylesheet" type="text/css" href="{{resources}}/kde.css" /> {% block head %}{% endblock %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/data/templates/frontpage.html new/kapidox-5.25.0/src/kapidox/data/templates/frontpage.html --- old/kapidox-5.24.0/src/kapidox/data/templates/frontpage.html 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/data/templates/frontpage.html 2016-08-06 01:24:22.000000000 +0200 @@ -40,7 +40,13 @@ <ul class="list-unstyled"> <li class=product-name><a name="prod-{{ product.name }}" href="{{ product.href }}">{{ product.fancyname }}</a></li> <li>{{ product.description }}</li> - <li class="prod-maintainers">{% include "maintainers.html" %}</li> + <li class="prod-maintainers"> + {% for maintainer in product.maintainers %} + <a href="mailto:{{ maintainer.email }}">{{ maintainer.name }}</a>{% if not loop.last %},{% endif %} + {% else %} + <a href="mailto:kde-de...@kde.org">The KDE Community</a> + {% endfor %} + </li> {% if product.platforms %} <li class="prod-platforms">{{ product.platforms | join(' | ') }}</li> {% endif %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/data/templates/libinfo.html new/kapidox-5.25.0/src/kapidox/data/templates/libinfo.html --- old/kapidox-5.24.0/src/kapidox/data/templates/libinfo.html 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/data/templates/libinfo.html 2016-08-06 01:24:22.000000000 +0200 @@ -10,7 +10,7 @@ <p>{{ fwinfo.description }}</p> <dl> - <dt>Maintainer{% if fwinfo.maintainers|count != 0 %}s{% endif %}</dt> + <dt>Maintainer{% if fwinfo.maintainers|count > 1 %}s{% endif %}</dt> <dd>{% set product = fwinfo %}{% include "maintainers.html" %}</dd> {# <dt>Dependencies</dt> @@ -36,8 +36,8 @@ </dd> <dt>Community</dt> - <dd>IRC channel: #{{ fwinfo.irc }} on Freenode</dd> - <dd><a href="https://mail.kde.org/mailman/listinfo/{{ fwinfo.mailinglist }}">Mailing list</a></dd> + <dd>IRC channel: <a href="irc://freenode/#{{ fwinfo.irc }}">#{{ fwinfo.irc }}</a> on Freenode</dd> + <dd>Mailing list: <a href="https://mail.kde.org/mailman/listinfo/{{ fwinfo.mailinglist }}">{{ fwinfo.mailinglist }}</a></dd> {% if fwinfo.libraries is iterable and fwinfo.libraries|count != 0 %} <dt>Use with <a href="https://techbase.kde.org/Development/Tutorials/CMake">CMake</a></dt> @@ -50,7 +50,9 @@ <dd><pre class="fragment">QT +={% for lib in fwinfo.libraries|selectattr("qmake") %} {{ lib.qmake }}{% endfor %} {% for line in fwinfo.qmakepro %}<br/>{{ line }} {% endfor %}</pre></dd> {% endif %} - <dt>Clone URL</dt> - <dd><pre class="fragment">git clone <a href="https://quickgit.kde.org/?p={{ fwinfo.name }}.git">git://anongit.kde.org/{{ fwinfo.name }}.git</a></pre></dd> + <dt>Clone</dt> + <dd><pre class="fragment">git clone git://anongit.kde.org/{{ fwinfo.name }}.git</pre></dd> + <dt>Browse source</dt> + <dd>{{ fwinfo.fancyname }} on <a href="https://quickgit.kde.org/?p={{ fwinfo.name }}.git">Quickgit</a></dd> </dl> </div> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/data/templates/maintainers.html new/kapidox-5.25.0/src/kapidox/data/templates/maintainers.html --- old/kapidox-5.24.0/src/kapidox/data/templates/maintainers.html 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/data/templates/maintainers.html 2016-08-06 01:24:22.000000000 +0200 @@ -1,5 +1,5 @@ {% for maintainer in product.maintainers %} - <a href="mailto:{{ maintainer.email }}">{{ maintainer.name }} <{{ maintainer.email }}></a>{% if not loop.last %},<br/>{% endif %} + <a href="mailto:{{ maintainer.email }}">{{ maintainer.name }}</a>{% if not loop.last %},<br/>{% endif %} {% else %} <a href="mailto:kde-de...@kde.org">The KDE Community</a> {% endfor %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/data/templates/subgroup.html new/kapidox-5.25.0/src/kapidox/data/templates/subgroup.html --- old/kapidox-5.24.0/src/kapidox/data/templates/subgroup.html 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/data/templates/subgroup.html 2016-08-06 01:24:22.000000000 +0200 @@ -83,16 +83,16 @@ </div> <h2>List of the libraries</h2> - {% if group.libraries | selectattr('subgroup', 'none') | list | length > 0 %} - {% if group.subgroups | length > 0 %} - <h3><a name="sg-{{ nosubgroup }}"></a>Without subgroup</h3> + {% if group.libraries | selectattr('subproduct', 'none') | list | length > 0 %} + {% if group.subproducts | length > 0 %} + <h3><a name="sg-{{ nosubproduct }}"></a>Without subgroup</h3> {% endif %} - {{ write_library_list(group.libraries | selectattr('subgroup', 'none') )}} + {{ write_library_list(group.libraries | selectattr('subproduct', 'none') )}} {% endif %} - {% for subgroup in group.subgroups |sort(attribute='order') %} - <h3><a name="sg-{{ subgroup.name }}"></a>{{ subgroup.fancyname }}</h3> - <p> {{ subgroup.description }}</p> - {{ write_library_list(subgroup.libraries) }} + {% for subproduct in group.subproducts |sort(attribute='order') %} + <h3><a name="sg-{{ subproduct.name }}"></a>{{ subproduct.fancyname }}</h3> + <p> {{ subproduct.description }}</p> + {{ write_library_list(subproduct.libraries) }} {% endfor %} @@ -112,15 +112,15 @@ <ul> <li> <ul> - {% if group.libraries | selectattr('subgroup', 'none') | list | length > 0 %} - {% if group.subgroups | length > 0 %} - <li><a href="#sg-{{ nosubgroup }}">Without subgroups</a></li> + {% if group.libraries | selectattr('subproducts', 'none') | list | length > 0 %} + {% if group.subproduct | length > 0 %} + <li><a href="#sg-{{ nosubproduct }}">Without subgroup</a></li> {% else %} <li><a href="#content">All</a></li> {% endif %} {% endif %} - {% for subgroup in group.subgroups | sort(attribute='order') %} - <li><a href="#sg-{{ subgroup.name }}">{{ subgroup.fancyname }}</a></li> + {% for subproduct in group.subproducts | sort(attribute='order') %} + <li><a href="#sg-{{ subproduct.name }}">{{ subproduct.fancyname }}</a></li> {% endfor %} </ul> </li> @@ -160,4 +160,24 @@ </div> </div> + <div class="menu_box"> + <div class="menutitle"> + <div> + <h2>About</h2> + </div> + </div> + + <p>{{ group.description }}</p> + + <dl> + <dt>Maintainer{% if group.maintainers|count > 1 %}s{% endif %}</dt> + <dd>{% set product = group %}{% include "maintainers.html" %}</dd> + <dt>Supported platforms</dt> + <dd>{{ group.platforms | join(', ') }}</dd> + <dt>Community</dt> + <dd>IRC channel: <a href="irc://freenode/#{{ group.irc }}">#{{ group.irc }}</a> on Freenode</dd> + <dd>Mailing list: <a href="https://mail.kde.org/mailman/listinfo/{{ group.mailinglist }}">{{ group.mailinglist }}</a></dd> + </dl> + </div> + {% endblock %} {# sidebar #} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/doxyfilewriter.py new/kapidox-5.25.0/src/kapidox/doxyfilewriter.py --- old/kapidox-5.24.0/src/kapidox/doxyfilewriter.py 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/doxyfilewriter.py 2016-08-06 01:24:22.000000000 +0200 @@ -40,8 +40,11 @@ def write_entry(self, key, value): """Write an entry - key -- the key part of the entry - value -- the value part of the entry. Can be a string, a list, a tuple or a boolean""" + Args: + key: the key part of the entry + value: the value part of the entry. Can be a string, a list, a + tuple or a boolean + """ if isinstance(value, (list, tuple)): txt = ' '.join([_quote(x) for x in value]) elif isinstance(value, bool): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/generator.py new/kapidox-5.25.0/src/kapidox/generator.py --- old/kapidox-5.24.0/src/kapidox/generator.py 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/generator.py 2016-08-06 01:24:22.000000000 +0200 @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- # -# Copyright 2016 Olivier Churlaud <oliv...@churlaud.com> # Copyright 2014 Alex Merry <alex.me...@kdemail.net> # Copyright 2014 Aurélien Gâteau <agat...@kde.org> # Copyright 2014 Alex Turbov <i.za...@gmail.com> +# Copyright 2016 Olivier Churlaud <oliv...@churlaud.com> # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -54,6 +54,11 @@ from .doxyfilewriter import DoxyfileWriter + +## @package kapidox.generator +# +# The generator + __all__ = ( "Context", "generate_apidocs", @@ -88,6 +93,7 @@ 'srcdir', 'tagfiles', 'dependency_diagram', + 'copyright', # Output 'outputdir', 'htmldir', @@ -129,13 +135,12 @@ def process_toplevel_html_file(outputfile, doxdatadir, products, title, api_searchbox=False): - products.sort(key=lambda x: x['name'].lower()) + products.sort(key=lambda x: x.fancyname.lower()) mapping = { 'resources': './resources', 'api_searchbox': api_searchbox, # steal the doxygen css from one of the frameworks # this means that all the doxygen-provided images etc. will be found - 'doxygencss': products[0]['outputdir'] + '/html/doxygen.css', 'title': title, 'breadcrumbs': { 'entries': [ @@ -159,9 +164,6 @@ mapping = { 'resources': '../resources', 'api_searchbox': api_searchbox, - # steal the doxygen css from one of the frameworks - # this means that all the doxygen-provided images etc. will be found - 'doxygencss': group['libraries'][0]['outputdir'] + '/html/doxygen.css', 'title': title, 'breadcrumbs': { 'entries': [ @@ -171,7 +173,7 @@ }, { 'href': './index.html', - 'text': group['fancyname'] + 'text': group.fancyname } ] }, @@ -179,9 +181,9 @@ 'available_platforms': sorted(available_platforms), } - if not os.path.isdir(group['name']): - os.mkdir(group['name']) - outputfile = group['name']+'/index.html' + if not os.path.isdir(group.name): + os.mkdir(group.name) + outputfile = group.name + '/index.html' tmpl = create_jinja_environment(doxdatadir).get_template('subgroup.html') with codecs.open(outputfile, 'w', 'utf-8') as outf: outf.write(tmpl.render(mapping)) @@ -189,7 +191,7 @@ def create_dirs(ctx): ctx.htmldir = os.path.join(ctx.outputdir, HTML_SUBDIR) - ctx.tagfile = os.path.join(ctx.htmldir, ctx.modulename + '.tags') + ctx.tagfile = os.path.join(ctx.htmldir, ctx.fwinfo.fancyname + '.tags') if not os.path.exists(ctx.outputdir): os.makedirs(ctx.outputdir) @@ -215,21 +217,24 @@ def find_tagfiles(docdir, doclink=None, flattenlinks=False, exclude=None, _depth=0): - """Find Doxygen-generated tag files in a directory + """Find Doxygen-generated tag files in a directory. The tag files must have the extention .tags, and must be in the listed directory, a subdirectory or a subdirectory named html of a subdirectory. - docdir -- the directory to search - doclink -- the path or URL to use when creating the documentation - links; if None, this will default to docdir - flattenlinks -- if this is True, generated links will assume all the html - files are directly under doclink; if False (the default), - the html files are assumed to be at the same relative - location to doclink as the tag file is to docdir; ignored - if doclink is not set + Args: + docdir: (string) the directory to search. + doclink: (string) the path or URL to use when creating the + documentation links; if None, this will default to + docdir. (optional, default None) + flattenlinks: (bool) if True, generated links will assume all the html + files are directly under doclink; else the html files are + assumed to be at the same relative location to doclink as + the tag file is to docdir; ignored if doclink is not set. + (optional, default False) - Returns a list of pairs of (tag_file,link_path) + Returns: + A list of pairs of (tag_file,link_path). """ if not os.path.isdir(docdir): @@ -283,18 +288,20 @@ At least one of docdir or searchpaths must be given for it to find anything. - suggestion -- the first place to look (will complain if there are no - documentation tag files there) - doclink -- the path or URL to use when creating the documentation - links; if None, this will default to docdir - flattenlinks -- if this is True, generated links will assume all the html - files are directly under doclink; if False (the default), - the html files are assumed to be at the same relative - location to doclink as the tag file is to docdir; ignored - if doclink is not set - searchpaths -- other places to look for documentation tag files + Args: + suggestion: the first place to look (will complain if there are no + documentation tag files there) + doclink: the path or URL to use when creating the documentation + links; if None, this will default to docdir + flattenlinks: if this is True, generated links will assume all the html + files are directly under doclink; if False (the default), + the html files are assumed to be at the same relative + location to doclink as the tag file is to docdir; ignored + if doclink is not set + searchpaths: other places to look for documentation tag files - Returns a list of pairs of (tag_file,link_path) + Returns: + A list of pairs of (tag_file,link_path) """ if not suggestion is None: @@ -323,9 +330,12 @@ Looks for a set of standard Doxygen files (like namespaces.html) and provides menu text for those it finds in htmldir. - htmldir -- the directory the HTML files are contained in + Args: + htmldir: (string) the directory the HTML files are contained in. + modulname: (string) the name of the library - Returns a list of maps with 'text' and 'href' keys + Returns: + A list of maps with 'text' and 'href' keys. """ entries = [ {'text': 'Main Page', 'href': 'index.html'}, @@ -355,20 +365,21 @@ The HTML files produced by Doxygen with our custom header and footer files look like this: - <!-- - key1: value1 - key2: value2 - ... - --> - <html> - <head> - ... - </head> - <body> - ... - </body> - </html> - + @code + <!-- + key1: value1 + key2: value2 + ... + --> + <html> + <head> + ... + </head> + <body> + ... + </body> + </html> + @endcode The parser fills the dict from the top key/value block, and add the content of the body to the dict using the "content" key. @@ -417,8 +428,10 @@ Performs text substitutions on each line in each .html file in a directory. - htmldir -- the directory containing the .html files - mapping -- a dict of mappings + Args: + htmldir: (string) the directory containing the .html files. + mapping: (dict) a dict of mappings. + """ for name in os.listdir(htmldir): if name.endswith('.html'): @@ -447,9 +460,11 @@ def build_classmap(tagfile): """Parses a tagfile to get a map from classes to files - tagfile -- the Doxygen-generated tagfile to parse + Args: + tagfile: the Doxygen-generated tagfile to parse. - Returns a list of maps (keys: classname and filename) + Returns: + A list of maps (keys: classname and filename). """ import xml.etree.ElementTree as ET tree = ET.parse(tagfile) @@ -469,14 +484,19 @@ """Write a mapping out as PHP code Creates a PHP array as described by mapping. For example, the mapping - [("foo","bar"),("x","y")] + + [("foo","bar"),("x","y")] + would cause the file - <?php $map = array('foo' => 'bar','x' => 'y') ?> + + <?php $map = array('foo' => 'bar','x' => 'y') ?> + to be written out. - mapping -- a list of pairs of strings - outputfile -- the file to write to - varname -- override the PHP variable name (defaults to 'map') + Args: + mapping: a list of pairs of strings + outputfile: the file to write to + varname: override the PHP variable name (defaults to 'map') """ logging.info('Generating PHP mapping') with codecs.open(outputfile, 'w', 'utf-8') as f: @@ -511,7 +531,7 @@ def find_src_subdir(dirlist, deeper_subd=None): returnlist = [] for d in dirlist: - pth = os.path.join(ctx.fwinfo['path'], d) + pth = os.path.join(ctx.fwinfo.path, d) if deeper_subd is not None: pth = os.path.join(pth, deeper_subd) if os.path.isdir(pth) or os.path.isfile(pth): @@ -520,20 +540,14 @@ pass # We drop it return returnlist - # Paths and basic project info - - # FIXME: preprocessing? - # What about providing the build directory? We could get the version - # as well, then. - input_list = [] - if os.path.isfile(ctx.fwinfo['path']+"/README.md"): - input_list.append(ctx.fwinfo['path']+"/README.md") - if os.path.isfile(ctx.fwinfo['path']+"/Mainpage.dox"): - input_list.append(ctx.fwinfo['path']+"/Mainpage.dox") + if os.path.isfile(ctx.fwinfo.path + "/Mainpage.dox"): + input_list.append(ctx.fwinfo.path + "/Mainpage.dox") + elif os.path.isfile(ctx.fwinfo.path + "/README.md"): + input_list.append(ctx.fwinfo.path + "/README.md") - input_list.extend(find_src_subdir(ctx.fwinfo['srcdirs'])) - input_list.extend(find_src_subdir(ctx.fwinfo['docdir'])) + input_list.extend(find_src_subdir(ctx.fwinfo.srcdirs)) + input_list.extend(find_src_subdir(ctx.fwinfo.docdir)) image_path_list = [] if ctx.dependency_diagram: @@ -556,11 +570,11 @@ # FIXME: can we get the project version from CMake? No from GIT TAGS! # Input locations - image_path_list.extend(find_src_subdir(ctx.fwinfo['docdir'], 'pics')) + image_path_list.extend(find_src_subdir(ctx.fwinfo.docdir, 'pics')) writer.write_entries( INPUT=input_list, - DOTFILE_DIRS=find_src_subdir(ctx.fwinfo['docdir'], 'dot'), - EXAMPLE_PATH=find_src_subdir(ctx.fwinfo['exampledir']), + DOTFILE_DIRS=find_src_subdir(ctx.fwinfo.docdir, 'dot'), + EXAMPLE_PATH=find_src_subdir(ctx.fwinfo.exampledir), IMAGE_PATH=image_path_list) # Other input settings @@ -595,8 +609,8 @@ writer.write_entries(**doxyfile_entries) # Module-specific overrides - if find_src_subdir(ctx.fwinfo['docdir']): - localdoxyfile = os.path.join(find_src_subdir(ctx.fwinfo['docdir'])[0], 'Doxyfile.local') + if find_src_subdir(ctx.fwinfo.docdir): + localdoxyfile = os.path.join(find_src_subdir(ctx.fwinfo.docdir)[0], 'Doxyfile.local') if os.path.isfile(localdoxyfile): with codecs.open(localdoxyfile, 'r', 'utf-8') as f: for line in f: @@ -607,14 +621,12 @@ def postprocess(ctx, classmap, template_mapping=None): - # TODO: copyright must be set from outside - copyright = '1996-' + str(datetime.date.today().year) + ' The KDE developers' mapping = { 'doxygencss': 'doxygen.css', 'resources': ctx.resourcedir, 'title': ctx.title, 'fwinfo': ctx.fwinfo, - 'copyright': copyright, + 'copyright': ctx.copyright, 'api_searchbox': ctx.api_searchbox, 'doxygen_menu': {'entries': menu_items(ctx.htmldir, ctx.modulename)}, 'class_map': {'classes': classmap}, @@ -671,21 +683,21 @@ return True -def create_fw_context(args, lib, tagfiles): +def create_fw_context(args, lib, tagfiles, copyright=''): return Context(args, # Names - modulename=lib['name'], - fancyname=lib['fancyname'], + modulename=lib.name, + fancyname=lib.fancyname, fwinfo=lib, # KApidox files - resourcedir=('../../resources' if lib['parent'] is None - else '../../../resources'), + resourcedir=('../../../resources' if lib.part_of_group + else '../../resources'), # Input - #srcdir=lib['srcdir'], + copyright=copyright, tagfiles=tagfiles, - dependency_diagram=lib['dependency_diagram'], + dependency_diagram=lib.dependency_diagram, # Output - outputdir=lib['outputdir'], + outputdir=lib.outputdir, ) @@ -706,11 +718,11 @@ 'href': '../../index.html', 'text': 'KDE API Reference' }] - if ctx.fwinfo['parent'] is not None: + if ctx.fwinfo.part_of_group: entries[0]['href'] = '../' + entries[0]['href'] entries.append({ 'href': '../../index.html', - 'text': ctx.fwinfo['product']['fancyname'] + 'text': ctx.fwinfo.product.fancyname }) entries.append({ 'href': 'index.html', @@ -745,7 +757,11 @@ def create_fw_tagfile_tuple(lib): tagfile = os.path.abspath( os.path.join( - lib['outputdir'], + lib.outputdir, 'html', - lib['fancyname']+'.tags')) - return (tagfile, '../../' + lib['outputdir'] + '/html/') + lib.fancyname+'.tags')) + if lib.part_of_group: + prefix = '../../../' + else: + prefix = '../../' + return (tagfile, prefix + lib.outputdir + '/html/') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/models.py new/kapidox-5.25.0/src/kapidox/models.py --- old/kapidox-5.24.0/src/kapidox/models.py 1970-01-01 01:00:00.000000000 +0100 +++ new/kapidox-5.25.0/src/kapidox/models.py 2016-08-06 01:24:22.000000000 +0200 @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2016 Olivier Churlaud <oliv...@churlaud.com> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import logging +import os.path +import string +from kapidox import utils + +## @package kapidox.models +# +# Contains the classes representing the objects used by kapidox +# + +class Library(object): + """ Library + """ + def __init__(self, metainfo, products, platforms, all_maintainers): + + # If it does not belong to a product, no need to go further + self.product = None + self.subproduct = None + + if 'group' in metainfo: + productname = metainfo['group'] + self.part_of_group = True + else: + productname = metainfo['name'] + self.part_of_group = False + if utils.serialize_name(productname) not in products: + productname = metainfo['name'] + del metainfo['group'] + products[metainfo['name']] = Product(metainfo, all_maintainers) + self.part_of_group = False + logging.warning("Group of {} not found: dropped.".format(metainfo['fancyname'])) + self.product = products[utils.serialize_name(productname)] + if self.product is None: + raise ValueError("'{}' does not belong to a product." + .format(metainfo['name'])) + + if 'subgroup' in metainfo: + for sp in self.product.subproducts: + if sp.name == utils.serialize_name(metainfo['subgroup']): + self.subproduct = sp + if self.subproduct is None: + logging.warning("Subgroup {} of library {} not documentated, subgroup will be None" + .format(metainfo['subgroup'], metainfo['name'])) + + if self.subproduct is not None: + self.parent = self.subproduct + self.subproduct.libraries.append(self) + else: + self.parent = self.product + self.product.libraries.append(self) + + self.name = metainfo['name'] + self.fancyname = metainfo['fancyname'] + self.description = metainfo.get('description') + self.maintainers = utils.set_maintainers(metainfo.get('maintainer'), all_maintainers) + self.platforms = platforms + self.outputdir = self._set_outputdir(self.part_of_group) + self.href = '../' + self.outputdir.lower() + '/html/index.html' + self.path = metainfo['path'] + self.srcdirs = utils.tolist(metainfo.get('public_source_dirs', ['src'])) + self.docdir = utils.tolist(metainfo.get('public_doc_dir', ['docs'])) + self.exampledir = utils.tolist(metainfo.get('public_example_dir', ['examples'])) + self.dependency_diagram = None + self.type = metainfo.get('type', '') + self.portingAid = metainfo.get('portingAid', False) + self.deprecated = metainfo.get('deprecated', False) + self.libraries = metainfo.get('libraries', []) + self.cmakename = metainfo.get('cmakename', '') + self.irc = metainfo.get('irc', self.product.irc) + self.mailinglist = metainfo.get('mailinglist', self.product.mailinglist) + + def _extend_parent(self, metainfo, key, key_obj, default): + if key in metainfo: + return metainfo[key] + elif getattr(self.product, key_obj) is not None: + return getattr(self.product, key_obj) + else: + return default + + def _set_outputdir(self, grouped): + outputdir = self.name + if grouped: + outputdir = self.product.outputdir + '/' + outputdir + return outputdir.lower() + + +class Product(object): + """ Product + """ + parent = None + # if there is a group, the product is the group + # else the product is directly the library + def __init__(self, metainfo, all_maintainers): + if 'group_info' in metainfo: + self.name = utils.serialize_name(metainfo['group']) + self.fancyname = metainfo['group_info'].get('fancyname', string.capwords(metainfo['group'])) + self.description = metainfo['group_info'].get('description') + self.long_description = metainfo['group_info'].get('long_description', []) + self.maintainers = utils.set_maintainers(metainfo['group_info']['maintainer'], + all_maintainers) + self.platforms = metainfo['group_info'].get('platforms') + self.outputdir = self.name + self.href = self.outputdir + '/index.html' + self.logo_url_src = self._set_logo_src(metainfo['path'], + metainfo['group_info']) + self.logo_url = self._set_logo() + self.libraries = [] # We'll set this later + self.subgroups = [] # We'll set this later + self.irc = metainfo['group_info'].get('irc', 'kde-devel') + self.mailinglist = metainfo['group_info'].get('mailinglist', 'kde-devel') + self.subproducts = self._extract_subproducts(metainfo['group_info']) + + elif 'group' not in metainfo: + self.name = utils.serialize_name(metainfo['name']) + self.fancyname = metainfo['fancyname'] + self.description = metainfo.get('description') + self.maintainers = utils.set_maintainers(metainfo.get('maintainer'), all_maintainers) + self.platforms = [x['name'] for x in metainfo.get('platforms', [{'name': None}])] + self.outputdir = self.name + self.href = self.outputdir + '/html/index.html' + self.logo_url_src = self._set_logo_src(metainfo['path'], metainfo) + self.logo_url = self._set_logo() + self.libraries = [] + self.irc = None + self.mailinglist = None + else: + raise ValueError("I do not recognize a product in {}." + .format(metainfo['name'])) + + def _extract_subproducts(self, groupinfo): + subproducts = [] + if 'subgroups' in groupinfo: + for sg in groupinfo['subgroups']: + sg + if 'name' in sg: + subproducts.append(Subproduct(sg, self)) + return subproducts + + def _set_logo(self): + if self.logo_url_src is not None: + filename, ext = os.path.splitext(self.logo_url_src) + return self.outputdir + '/' + self.name + ext + else: + return None + + def _set_logo_src(self, path, dct): + if 'logo' in dct: + logo_url = os.path.join(path, dct['logo']) + if os.path.isfile(logo_url): + return logo_url + else: + logging.warning("{} logo file doesn't exist, set back to None" + .format(self.fancyname)) + return None + else: + return None + +class Subproduct(object): + """ Subproduct + """ + def __init__(self, sginfo, product): + self.fancyname = sginfo['name'] + self.name = utils.serialize_name(sginfo['name']) + self.description = sginfo.get('description') + self.order = sginfo.get('order', 99) # If no order, go to end + self.libraries = [] + self.product = product + self.parent = product diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/preprocessing.py new/kapidox-5.25.0/src/kapidox/preprocessing.py --- old/kapidox-5.24.0/src/kapidox/preprocessing.py 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/preprocessing.py 2016-08-06 01:24:22.000000000 +0200 @@ -32,7 +32,6 @@ import logging import os -import string try: from urllib2 import Request, urlopen, HTTPError @@ -43,11 +42,11 @@ import yaml from kapidox import utils +from kapidox.models import Library, Product __all__ = ( "create_metainfo", - "parse_tree", - "set_maintainers") + "parse_tree") PLATFORM_ALL = "All" @@ -56,7 +55,7 @@ ## @package kapidox.preprocessing # -# Preprocess the needed information. +# Preprocessing of the needed information. # # The module allow to walk through folders, read metainfo files and create # products, subgroups and libraries representing the projects. @@ -90,7 +89,7 @@ """Look for a `metadata.yaml` file and create a dictionary out it. Args: - path: (string) the current path to search; + path: (string) the current path to search. Returns: A dictionary containing all the parsed information, or `None` if it did not fullfill some conditions. @@ -105,7 +104,8 @@ try: metainfo = yaml.load(open(metainfo_file)) - except: + except Exception as e: + print(e) logging.warning('Could not load metainfo.yaml for {}, skipping it' .format(path)) return None @@ -121,12 +121,17 @@ return None name = os.path.basename(path) - fancyname = utils.parse_fancyname(path) + if 'fancyname' in metainfo: + fancyname = metainfo['fancyname'] + else: + fancyname = utils.parse_fancyname(path) + if not fancyname: logging.warning('Could not find fancy name for {}, skipping it' .format(path)) return None - + # A fancyname has 1st char capitalized + fancyname = fancyname[0].capitalize() + fancyname[1:] metainfo.update({ 'fancyname': fancyname, 'name': name, @@ -142,10 +147,10 @@ """Recursively call create_metainfo() in subdirs of rootdir Args: - rootdir: (string) Top level directory containing the libraries + rootdir: (string) Top level directory containing the libraries. Returns: - A list of metainfo dictionary (see create_metainfo()) + A list of metainfo dictionary (see create_metainfo()). """ metalist = [] @@ -165,22 +170,31 @@ def sort_metainfo(metalist, all_maintainers): - products = [] + """Extract the structure (Product/Subproduct/Library) from the metainfo + list. + + Args: + metalist: (list of dict) lists of the metainfo extracted in + parse_tree(). + all_maintainers: (dict of dict) all possible maintainers. + + Returns: + A list of Products, a list of groups (which are products containing + several libraries), a list of Libraries and the available platforms. + """ + products = dict() groups = [] libraries = [] available_platforms = set(['Windows', 'MacOSX', 'Linux']) - all_groups = [] - defined_groups = [] + # First extract the structural info for metainfo in metalist: - if 'group' in metainfo: - all_groups.append(metainfo['group']) - if 'group_info' in metainfo: - defined_groups.append(metainfo['group']) - undefined_groups = [x for x in list(set(all_groups)) if x not in defined_groups] + product = extract_product(metainfo, all_maintainers) + if product is not None: + products[product.name] = product + # Second extract the libraries for metainfo in metalist: - try: platforms = metainfo['platforms'] platform_lst = [x['name'] for x in platforms @@ -189,7 +203,7 @@ available_platforms.update(set(platform_lst)) except (KeyError, TypeError): - logging.warning('{} framework lacks valid platform definitions' + logging.warning('{} library lacks valid platform definitions' .format(metainfo['fancyname'])) platforms = [dict(name=PLATFORM_UNKNOWN)] @@ -197,217 +211,33 @@ expand_platform_all(dct, available_platforms) platforms = dct - - lib = extract_lib(metainfo, platforms, all_maintainers) + lib = Library(metainfo, products, platforms, all_maintainers) libraries.append(lib) - product = extract_product(metainfo, platforms, all_maintainers, undefined_groups) - if product is not None: - products.append(product) + groups = [p for p in list(products.values()) if len(p.libraries) > 1] - # We have all groups and libraries, let set the parents. - # and check the platforms - for lib in libraries: - if lib['parent'].get('group') is not None: - product_list = [x for x in products if x['name'].lower() == lib['parent']['group'].lower()] - if not product_list: - continue # The group_info was not defined - else: - product = product_list[0] - lib['product'] = product - if lib['mailinglist'] is None: - if product['mailinglist'] is not None: - lib['mailinglist'] = product['mailinglist'] - else: - lib['mailinglist'] = 'kde-devel' - if lib['irc'] is None: - if product['irc'] is not None: - lib['irc'] = product['irc'] - else: - lib['irc'] = 'kde-devel' - - product['libraries'].append(lib) - if lib['parent'].get('subgroup') is None: - lib['subgroup'] = None - else: - subgroup_list = [x for x in lib['product']['subgroups'] if x['name'].lower() == lib['parent']['subgroup'].lower()] - if not subgroup_list: - logging.warning("Subgroup {} of library {} not documentated, setting subgroup to None" - .format(lib['parent']['subgroup'], lib['name'])) - lib['subgroup'] = None - lib['parent'] = product - else: - subgroup = subgroup_list[0] - lib['subgroup'] = subgroup - subgroup['libraries'].append(lib) - groups.append(product) - else: - lib['parent'] = None - - return products, groups, libraries, available_platforms - - -def extract_lib(metainfo, platforms, all_maintainers): - def tolist(a): - if type(a) is list: - return a - else: - return [a] - - outputdir = metainfo.get('name') - if 'group' in metainfo: - outputdir = metainfo.get('group') + '/' + outputdir - outputdir = utils.serialize_name(outputdir) - lib = { - 'name': metainfo['name'], - 'fancyname': metainfo['fancyname'], - 'description': metainfo.get('description'), - 'maintainers': set_maintainers(metainfo, 'maintainer', all_maintainers), - 'platforms': platforms, - 'parent': {'group': utils.serialize_name(metainfo.get('group')), - 'subgroup': utils.serialize_name(metainfo.get('subgroup'))}, - 'href': '../'+outputdir.lower() + '/html/index.html', - 'outputdir': outputdir.lower(), - 'path': metainfo['path'], - 'srcdirs': tolist(metainfo.get('public_source_dirs', ['src'])), - 'docdir': tolist(metainfo.get('public_doc_dir', ['docs'])), - 'exampledir': tolist(metainfo.get('public_example_dir', ['examples'])), - 'dependency_diagram': None, - 'type': metainfo.get('type', ''), - 'portingAid': metainfo.get('portingAid', False), - 'deprecated': metainfo.get('deprecated', False), - 'libraries': metainfo.get('libraries', []), - 'cmakename': metainfo.get('cmakename', ''), - 'irc': metainfo.get('irc'), - 'mailinglist': metainfo.get('mailinglist'), - } - - return lib - - -def extract_product(metainfo, platforms, all_maintainers, undefined_groups): - def get_logo_url(dct, name): - # take care of the logo - if 'logo' in dct: - logo_url = os.path.join(metainfo['path'], dct['logo']) - if os.path.isfile(logo_url): - return logo_url - else: - logging.warning("{} logo file doesn't exist, set back to None".format(name)) - return None - else: - return None - - def set_logo(product): - if product['logo_url_src'] is not None: - filename = os.path.basename(product['logo_url_src']) - product['logo_url'] = outputdir + '/'+ product['name'] + '.' + filename.split('.')[-1] - - # if there is a group, the product is the group - # else the product is directly the library - if 'group_info' in metainfo: - outputdir = utils.serialize_name(metainfo['group']) - product = { - 'name': utils.serialize_name(metainfo['group']), - 'fancyname': metainfo['group_info'].get('fancyname', string.capwords(metainfo['group'])), - 'description': metainfo['group_info'].get('description'), - 'long_description': metainfo['group_info'].get('long_description', []), - 'maintainers': set_maintainers(metainfo['group_info'], - 'maintainer', - all_maintainers), - 'platforms': metainfo['group_info'].get('platforms'), - 'logo_url_src': get_logo_url(metainfo['group_info'], - metainfo['group']), - 'logo_url': None, # We'll set this later - 'outputdir': outputdir, - 'href': outputdir + '/index.html', - 'libraries': [], # We'll set this later - 'subgroups': [], # We'll set this later - 'irc': metainfo['group_info'].get('irc'), - 'mailinglist': metainfo['group_info'].get('mailinglist'), - } - - if 'subgroups' in metainfo['group_info']: - for sg in metainfo['group_info']['subgroups']: - if 'name' in sg: - product['subgroups'].append({ - 'fancyname': sg['name'], - 'name': utils.serialize_name(sg['name']), - 'description': sg.get('description'), - 'order': sg.get('order', 99), # If no order, go to end - 'libraries': [] - }) - set_logo(product) - return product - elif 'group' in metainfo and metainfo['group'] in undefined_groups: - outputdir = utils.serialize_name(metainfo['group']) - product = { - 'name': utils.serialize_name(metainfo['group']), - 'fancyname': string.capwords(metainfo['group']), - 'description': '', - 'long_description': [], - 'maintainers': set_maintainers(dict(), - 'maintainer', - all_maintainers), - 'platforms': None, - 'logo_url_src': None, - 'logo_url': None, # We'll set this later - 'outputdir': outputdir, - 'href': outputdir + '/index.html', - 'libraries': [], # We'll set this later - 'subgroups': [], # We'll set this later - 'irc': None, - 'mailinglist': None, - } - return product - elif 'group' not in metainfo: - outputdir = metainfo['name'] + return list(products.values()), groups, libraries, available_platforms - product = { - 'name': utils.serialize_name(metainfo['name']), - 'fancyname': metainfo['fancyname'], - 'description': metainfo.get('description'), - 'maintainers': set_maintainers(metainfo, - 'maintainer', - all_maintainers), - 'platforms': platforms, - 'logo_url_src': get_logo_url(metainfo, metainfo['fancyname']), - 'logo_url': None, # We'll set that later - 'href': outputdir + '/html/index.html', - 'outputdir': outputdir - } - set_logo(product) - return product - else: - return None -def set_maintainers(dictionary, key, maintainers): - """ Expend the name of the maintainers. +def extract_product(metainfo, all_maintainers): + """Extract a product from a metainfo dictionary. Args: - dictonary: (dict) Dictionary from which the name to expend will be read. - key: (string) Key of the dictionary where the name to expend is saved. - maintainers: (list of dict) Look-up table where the names and emails of - the maintainers are stored. - - Examples: - - metainfo = { 'key1': 'something', 'maintainers': ['arthur', 'toto']} - myteam = [{'arthur': {'name': 'Arthur Pendragon', - 'email': 'art...@example.com'}, - 'toto': {'name': 'Toto', - 'email: 'toto...@example.com'} - }] - set_maintainers(metainfo, "maintainers", my_team) + metainfo: (dict) metainfo created by the create_metainfo() function. + all_maintainer: (dict of dict) all possible maintainers + + Returns: + A Product or None if the metainfo does not describe a product. """ - if key not in dictionary: - fw_maintainers = [] - elif isinstance(dictionary[key], list): - fw_maintainers = map(lambda x: maintainers.get(x, None), - dictionary[key]) - else: - fw_maintainers = [maintainers.get(dictionary[key], None)] + if 'group_info' not in metainfo and 'group' in metainfo: + # This is not a product but a simple lib + return None - fw_maintainers = [x for x in fw_maintainers if x is not None] - return fw_maintainers + try: + product = Product(metainfo, all_maintainers) + except ValueError as e: + logging.error(e) + product = None + finally: + return product diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox/utils.py new/kapidox-5.25.0/src/kapidox/utils.py --- old/kapidox-5.24.0/src/kapidox/utils.py 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox/utils.py 2016-08-06 01:24:22.000000000 +0200 @@ -36,29 +36,74 @@ import sys import tempfile -""" -This module contains code which is shared between depdiagram-prepare and other -components. - -Code in this dir should not import any module which is not shipped with Python -because this module is used by depdiagram-prepare, which must be able to run -on builds.kde.org, which may not have all the required dependencies. -""" +## @package kapidox.utils +# +# Multiple usage utils. +# +# This module contains code which is shared between depdiagram-prepare and +# other components. +# +# Code in this dir should not import any module which is not shipped with +# Python because this module is used by depdiagram-prepare, which must be able +# to run on builds.kde.org, which may not have all the required dependencies. +# def setup_logging(): FORMAT = '%(asctime)s %(levelname)s %(message)s' logging.basicConfig(format=FORMAT, datefmt='%H:%M:%S', level=logging.DEBUG) +def tolist(a): + """ Return a list based on `a`. """ + return a if type(a) is list else [a] + + def serialize_name(name): + """ Return a serialized name. + + For now it only replaces ' ' with '_' and lower the letters. + """ if name is not None: return '_'.join(name.lower().split(' ')) else: return None +def set_maintainers(maintainer_keys, all_maintainers): + """ Expend the name of the maintainers. + + Args: + dictonary: (dict) Dictionary from which the name to expend will be read. + key: (string) Key of the dictionary where the name to expend is saved. + all_maintainers: (dict of dict) Look-up table where the names and emails of + the maintainers are stored. + + Examples: + >>> maintainer_keys = ['arthur', 'toto'] + + >>> myteam = {'arthur': {'name': 'Arthur Pendragon', + 'email': 'art...@example.com'}, + 'toto': {'name': 'Toto', + 'email: 'toto...@example.com'} + } + + >>> set_maintainers(maintainer_keys, my_team) + """ + + if not maintainer_keys: + maintainers = [] + elif isinstance(maintainer_keys, list): + maintainers = map(lambda x: all_maintainers.get(x, None), + maintainer_keys) + else: + maintainers = [all_maintainers.get(maintainer_keys, None)] + + maintainers = [x for x in maintainers if x is not None] + return maintainers + + def parse_fancyname(fw_dir): - """Returns the framework name for a given source dir + """Return the framework name for a given source dir The framework name is the name of the toplevel CMake project """ @@ -66,7 +111,7 @@ if not os.path.exists(cmakelists_path): logging.error("No CMakeLists.txt in {}".format(fw_dir)) return None - project_re = re.compile(r"project\s*\(\s*(\w+)", re.I) + project_re = re.compile(r"project\s*\(\s*([\w\-\_]+)", re.I) with open(cmakelists_path) as f: for line in f.readlines(): match = project_re.search(line) @@ -112,7 +157,18 @@ def svn_export(remote, local, overwrite=False): """Wraps svn export. - Raises an exception on failure. + Args: + remote: (string) the remote url. + local: (string) the local path where to dowload. + overwrite: (bool) whether to overwrite `local` or not. (optional, + default = False) + + Returns: + True if success. + + Raises: + FileNotFoundError: + subprocess.CalledProcessError: """ try: import svn.core @@ -134,7 +190,7 @@ try: subprocess.check_call(cmd, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - raise StandardException(e.output) + raise subprocess.StandardException(e.output) except FileNotFoundError as e: logging.debug("External svn client not found") return False @@ -146,8 +202,9 @@ def copy_dir_contents(directory, dest): """Copy the contents of a directory - directory -- the directory to copy the contents of - dest -- the directory to copy them into + Args: + directory: (string) the directory to copy the contents of. + dest: (string) the directory to copy them into. """ ignored = ['CMakeLists.txt'] ignore = shutil.ignore_patterns(*ignored) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kapidox-5.24.0/src/kapidox_generate new/kapidox-5.25.0/src/kapidox_generate --- old/kapidox-5.24.0/src/kapidox_generate 2016-06-20 15:51:32.000000000 +0200 +++ new/kapidox-5.25.0/src/kapidox_generate 2016-08-06 01:24:22.000000000 +0200 @@ -1,10 +1,10 @@ #! /usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright 2016 Olivier Churlaud <oliv...@churlaud.com> # Copyright 2014 Alex Merry <alex.me...@kdemail.net> # Copyright 2014 Aurélien Gâteau <agat...@kde.org> # Copyright 2014 Alex Turbov <i.za...@gmail.com> +# Copyright 2016 Olivier Churlaud <oliv...@churlaud.com> # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -37,14 +37,14 @@ import sys import tempfile import time +import datetime if sys.version_info.major < 3: from urllib import urlretrieve else: from urllib.request import urlretrieve -import kapidox as kdx -from kapidox import generator +from kapidox import generator, utils, argparserutils, preprocessing try: from kapidox import depdiagram @@ -65,7 +65,7 @@ """Download the "accounts" file on the KDE SVN repository in order to get the KDE identities with their name and e-mail address """ - cache_file = os.path.join(kdx.utils.cache_dir(), 'kde-accounts') + cache_file = os.path.join(utils.cache_dir(), 'kde-accounts') needs_download = True if os.path.exists(cache_file): logging.debug("Found cached identities file at %s", cache_file) @@ -79,7 +79,7 @@ if needs_download: logging.info("Downloading KDE identities") try: - if not kdx.utils.svn_export( + if not utils.svn_export( 'svn://anonsvn.kde.org/home/kde/trunk/kde-common/accounts', cache_file, overwrite=True): @@ -109,8 +109,9 @@ def main(): - kdx.utils.setup_logging() - args = kdx.argparserutils.parse_args(DEPDIAGRAM_AVAILABLE) + kde_copyright = '1996-' + str(datetime.date.today().year) + ' The KDE developers' + utils.setup_logging() + args = argparserutils.parse_args(DEPDIAGRAM_AVAILABLE) tagfiles = generator.search_for_tagfiles( suggestion=args.qtdoc_dir, @@ -119,10 +120,10 @@ searchpaths=['/usr/share/doc/qt5', '/usr/share/doc/qt']) maintainers = download_kde_identities() - rootdir = args.frameworksdir + rootdir = args.sourcesdir - metalist = kdx.preprocessing.parse_tree(rootdir) - products, groups, libraries, available_platforms = kdx.preprocessing.sort_metainfo(metalist, maintainers) + metalist = preprocessing.parse_tree(rootdir) + products, groups, libraries, available_platforms = preprocessing.sort_metainfo(metalist, maintainers) dirsrc = os.path.join(args.doxdatadir, 'htmlresource') dirdest = 'resources' @@ -131,13 +132,13 @@ shutil.copytree(dirsrc, dirdest) os.rename(dirdest+'/favicon.ico', './favicon.ico') - kdx.generator.process_toplevel_html_file('index.html', + generator.process_toplevel_html_file('index.html', args.doxdatadir, title=args.title, products=products, api_searchbox=args.api_searchbox ) - kdx.generator.process_subgroup_html_files('index.html', + generator.process_subgroup_html_files('index.html', args.doxdatadir, title=args.title, groups=groups, @@ -152,34 +153,34 @@ assert(dot_files) for lib in libraries: - logging.info('# Generating doc for {}'.format(lib['fancyname'])) + logging.info('# Generating doc for {}'.format(lib.fancyname)) if args.depdiagram_dot_dir: - png_path = os.path.join(tmp_dir, lib['name']) + '.png' - ok = kdx.generator.generate_diagram(png_path, lib['fancyname'], + png_path = os.path.join(tmp_dir, lib.name) + '.png' + ok = generator.generate_diagram(png_path, lib.fancyname, dot_files, tmp_dir) if ok: - lib['dependency_diagram'] = png_path - ctx = kdx.generator.create_fw_context(args, lib, tagfiles) - kdx.generator.gen_fw_apidocs(ctx, tmp_dir) - tagfiles.append(kdx.generator.create_fw_tagfile_tuple(lib)) + lib.dependency_diagram = png_path + ctx = generator.create_fw_context(args, lib, tagfiles) + generator.gen_fw_apidocs(ctx, tmp_dir) + tagfiles.append(generator.create_fw_tagfile_tuple(lib)) # Rebuild for interdependencies # FIXME: can we be cleverer about deps? for lib in libraries: logging.info('# Rebuilding {} for interdependencies' - .format(lib['name'])) - shutil.rmtree(lib['outputdir']) - ctx = kdx.generator.create_fw_context(args, lib, tagfiles) - kdx.generator.gen_fw_apidocs(ctx, tmp_dir) - kdx.generator.finish_fw_apidocs(ctx, None) + .format(lib.fancyname)) + shutil.rmtree(lib.outputdir) + ctx = generator.create_fw_context(args, lib, tagfiles, kde_copyright) + generator.gen_fw_apidocs(ctx, tmp_dir) + generator.finish_fw_apidocs(ctx, None) logging.info('# Done') finally: for product in products: - if product['logo_url'] is not None: - logodir = os.path.dirname(product['logo_url']) + if product.logo_url is not None: + logodir = os.path.dirname(product.logo_url) if not os.path.isdir(logodir): os.mkdir(logodir) - shutil.copy(product['logo_url_src'], product['logo_url']) + shutil.copy(product.logo_url_src, product.logo_url) if args.keep_temp_dirs: logging.info('Kept temp dir at {}'.format(tmp_dir))