Skip to content

Conversation

@geimer
Copy link
Contributor

@geimer geimer commented Feb 10, 2017

This PR implements support for additional easyconfig parameters for customizing the documentation as discussed here: https://www.mail-archive.com/[email protected]/msg03050.html
It also includes the list of installed extensions of a package in the module help output.

'docpaths': [None, "List of paths of installed documentation relative to package root dir", MODULES],
'docurls': [None, "List of URLs to package documentation", MODULES],
'support': [None, "Package-specific support/bug report address", MODULES],
'contact': [None, "Site contact for the package", MODULES],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, this is getting a bit messy, is it not?

we should try and sort these alphabetically, although maybe also keep related ones together in groups?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for contact, don't make it specific to site contact, could also be upstream contact for this software package (e.g. a mailing list)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the idea was to separate upstream contacts (support) from site-local contacts (contact). The documentation of those two parameters already tries to make that clear. But maybe the naming is sub-optimal. I'm open for suggestions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I just noticed that there is already a docurls parameter defined in the MANDATORY section, though it is not (yet) enforced. I guess it hasn't been used so far?

Regarding the "messiness": Would it make sense to add a DOCUMENTATION group and add all those variables to it? Though description would then need to be in MANDATORY and DOCUMENTATION...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the support documentation needs to indicate that this is for upstream, not site-local support. Otherwise it's rather ambiguous.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about upstream_contact and site_contact? This should make it clear. And since the list values are free-form text fields, one could do something like

upstream_contact = [
    'Support e-mail: [email protected]',
    'Mailing list: [email protected]',
    'Bugtracker: https://www.project.org/bugzilla'
]
site_contact = ['Jane Admin']

Which would be rendered as

More information
================
 - Homepage: https://www.project.org
 - Upstream contact:
    - Support e-mail: [email protected]
    - Mailing list: [email protected]
    - Bugtracker: https://www.project.org/bugzilla
 - Site contact: Jane Admin

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly what I had in mind.

from easybuild.tools.filetools import convert_name, mkdir, read_file
from easybuild.tools.modules import ROOT_ENV_VAR_NAME_PREFIX, modules_tool
from easybuild.tools.utilities import quote_str
from textwrap import wrap
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a non-easybuild import, it should go up with the others?

'Description',
'===========',
"%s" % description.strip(),
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a common pattern below, so maybe define a helper function inside of this method to ensure consistency of the format?

def _generate_help_text(self):
    ...

    def generate_section(sec_name, sec_txt):
        """
        Generate section with given name and contents
        """"
        if sec_txt:
            return [
                '',
                sec_name,
                '=' * len(sec_name),
                sec_txt.strip(),
             ]
         else:
             return []

        # General package description (mandatory)
        lines = generate_section('Description', self.app.cfg['description'])

        # Package usage instructions (optional)
        lines.extend('Usage', self.app.cfg['usage'])

        # Additional information: homepage + (if available) doc paths/urls, support info, contacts, ...
        lines.extend('More information', " - Homepage: %s" % self.app.cfg['homepage'])
        ...

        extensions = ', '.join(sorted(['%s-%s' % (ext[0], ext[1]) for ext in exts_list], key=str.lower))
        lines.extend('Extensions', '\n'.join(wrap(extensions, 78)))

'',
"Included extensions",
'===================',
"%s" % '\n'.join(wrap(extensions, 78)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, the 78 here looks very arbitrary/harcoded... why exactly 78?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it fit nicely into a 80-character-wide terminal window 😁

When making this a configuration parameter, I'd also like to see all other sections to be wrapped at the given width. But this is (at least from my "I don't know much Python" perspective) by no means trivial to achieve with textwrap.wrap(). Maybe someone knows a good rst-to-ascii-text renderer that we could leverage?

"proc ModulesHelp { } {",
" puts stderr { %(description)s",
" puts stderr {"
"%s" % self._generate_help_text(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"%s" % x is the same thing as just x

lines = [
"help([[%(description)s]])",
'help([[',
"%s" % self._generate_help_text(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too, no need for the "%s" %

contact = self.app.cfg['contact']
if contact:
if isinstance(contact, list):
lines.extend([" - Site contacts:"])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop the Site ?

@boegel boegel added this to the 3.2.0 milestone Feb 10, 2017
@pforai
Copy link
Contributor

pforai commented Feb 11, 2017

I like the idea 👍

@geimer geimer changed the title Additional easyconfig parameters for documentation (WIP) Additional easyconfig parameters for documentation (REVIEW) Mar 4, 2017
@geimer
Copy link
Contributor Author

geimer commented Mar 4, 2017

@boegel There is no test yet for the whatis/help text in the presence of extensions, and I'm not quite sure where to put it. Any suggestion? Otherwise I think this is now ready for prime time.

@boegel
Copy link
Member

boegel commented Mar 30, 2017

@geimer Can you take care of the conflict before I revisit this?

W.r.t. a test for whatis/help with extensions involved, we have toy tests that involve extensions, maybe there? Let me know if you're up for looking into that.

@geimer
Copy link
Contributor Author

geimer commented Mar 30, 2017

@boegel Who f?$%ed up the module_generator ;-) Conflict resolved, Travis is running.

The test checking the modulefile contents is currently using test_toy_tweaked, but could use test_toy_advanced instead. But I'm not yet convinced that this doesn't create other problems...

@boegel
Copy link
Member

boegel commented Mar 30, 2017

@geimer @damianam did an effort to sort things alphabetically in module_generator, cfr. #2132

@boegel
Copy link
Member

boegel commented Mar 30, 2017

@geimer why would using test_toy_advanced be better (or why would it create problems)?

@damianam
Copy link
Member

Who f?$%ed up the module_generator

Ups ;-P. Sorting it wasn't really necessary, but working with it with methods put at random places in the file was kind of annoying, that's why I shuffled everything around.

@geimer
Copy link
Contributor Author

geimer commented Mar 30, 2017

@boegel If I'm not mistaken, test_toy_advanced is the one using extensions. But it would have to be adjusted to include the additional ec parameters which may have undesired side effects.


# MODULES documentation easyconfig parameters
# (docurls is part of MANDATORY)
'docpaths': [None, "List of paths of installed documentation relative to package root dir", MODULES],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List of paths for documentation relative to installation directory

# MODULES documentation easyconfig parameters
# (docurls is part of MANDATORY)
'docpaths': [None, "List of paths of installed documentation relative to package root dir", MODULES],
'examples': [None, "Free-form text with examples", MODULES],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... with examples on using the software

# (docurls is part of MANDATORY)
'docpaths': [None, "List of paths of installed documentation relative to package root dir", MODULES],
'examples': [None, "Free-form text with examples", MODULES],
'site_contact': [None, "String/list of strings with site contacts for the package", MODULES],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plural: site_contacts

also: s/package/software/

'site_contact': [None, "String/list of strings with site contacts for the package", MODULES],
'upstream_contact': [None, ("String/list of strings with upstream contact addresses "
"(e.g., support e-mail, mailing list, bugtracker)"), MODULES],
'usage': [None, "Usage instructions for the package", MODULES],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/package/software/

'upstream_contact': [None, ("String/list of strings with upstream contact addresses "
"(e.g., support e-mail, mailing list, bugtracker)"), MODULES],
'usage': [None, "Usage instructions for the package", MODULES],
'whatis': [None, "List of brief (one line) package description entries", MODULES],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/package/software/


return whatis

def _generate_extension_list(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort these methods alphabetically, let's not let @damianam's efforts go to waste ;)

Generate a string with a comma-separated list of extensions.
"""
exts_list = self.app.cfg['exts_list']
extensions = ', '.join(sorted(['%s-%s' % (ext[0], ext[1]) for ext in exts_list], key=str.lower))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/(ext[0], ext[1])/ext[:2]/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeError: not enough arguments for format string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now using '-'.join(ext[:2]) for ext in ... but I'm not sure it helps w.r.t. readablity...

# - 'conflict Compiler/GCC/4.8.2/OpenMPI' for 'Compiler/GCC/4.8.2/OpenMPI/1.6.4'
lines.extend(['', "conflict %s" % os.path.dirname(self.app.short_mod_name)])

whatis = self._generate_whatis_lines()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just move this inline, only used in one place?

# conflict on 'name' part of module name (excluding version part at the end)
lines.extend(['', 'conflict("%s")' % os.path.dirname(self.app.short_mod_name)])

whatis = self._generate_whatis_lines()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, move this inline?


gzip_txt = "gzip (GNU zip) is a popular data compression program as a replacement for compress "
gzip_txt += "- Homepage: http://www.gzip.org/"
gzip_txt = "gzip (GNU zip) is a popular data compression program as a replacement for compress"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename gzip_txt to descr?

@boegel
Copy link
Member

boegel commented May 2, 2017

lgtm, going in, thanks for your hard work and patience on this @geimer!

@boegel boegel merged commit 7f0bf95 into easybuilders:develop May 2, 2017
@geimer geimer deleted the additional_doc_params branch October 30, 2017 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants