-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for --list-software #1883
Changes from 14 commits
73c08a2
5f9130b
6cf3c24
0c8750a
4f3faea
a538aac
9a7504d
7a191e0
1147432
de78713
df4aaf1
5b43b07
05b83d2
3e0fc9f
b62f0c0
1ec5af4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,9 @@ | |
import inspect | ||
import os | ||
import re | ||
import string | ||
import sys | ||
from distutils.version import LooseVersion | ||
from vsc.utils import fancylogger | ||
from vsc.utils.docs import mk_rst_table | ||
from vsc.utils.missing import nub | ||
|
@@ -48,14 +50,18 @@ | |
from easybuild.framework.easyconfig.constants import EASYCONFIG_CONSTANTS | ||
from easybuild.framework.easyconfig.easyconfig import get_easyblock_class | ||
from easybuild.framework.easyconfig.licenses import EASYCONFIG_LICENSES_DICT | ||
from easybuild.framework.easyconfig.parser import EasyConfigParser | ||
from easybuild.framework.easyconfig.templates import TEMPLATE_NAMES_CONFIG, TEMPLATE_NAMES_EASYCONFIG | ||
from easybuild.framework.easyconfig.templates import TEMPLATE_NAMES_LOWER, TEMPLATE_NAMES_LOWER_TEMPLATE | ||
from easybuild.framework.easyconfig.templates import TEMPLATE_NAMES_EASYBLOCK_RUN_STEP, TEMPLATE_CONSTANTS | ||
from easybuild.framework.easyconfig.templates import TEMPLATE_SOFTWARE_VERSIONS | ||
from easybuild.framework.easyconfig.templates import TEMPLATE_SOFTWARE_VERSIONS, template_constant_dict | ||
from easybuild.framework.easyconfig.tweak import find_matching_easyconfigs | ||
from easybuild.framework.extension import Extension | ||
from easybuild.tools.build_log import EasyBuildError | ||
from easybuild.tools.build_log import EasyBuildError, print_msg | ||
from easybuild.tools.config import build_option | ||
from easybuild.tools.filetools import read_file | ||
from easybuild.tools.ordereddict import OrderedDict | ||
from easybuild.tools.toolchain import DUMMY_TOOLCHAIN_NAME | ||
from easybuild.tools.toolchain.utilities import get_toolchain, search_toolchain | ||
from easybuild.tools.utilities import import_available_modules, quote_str | ||
|
||
|
@@ -81,11 +87,13 @@ def generate_doc(name, params): | |
|
||
def rst_title_and_table(title, table_titles, table_values): | ||
"""Generate table in section with title in .rst format.""" | ||
doc = [ | ||
title, | ||
'-' * len(title), | ||
'', | ||
] | ||
doc = [] | ||
if title is not None: | ||
doc.extend([ | ||
title, | ||
'-' * len(title), | ||
'', | ||
]) | ||
doc.extend(mk_rst_table(table_titles, table_values)) | ||
return doc | ||
|
||
|
@@ -514,6 +522,160 @@ def add_class(classes, cls): | |
return '\n'.join(txt) | ||
|
||
|
||
def list_software(output_format=FORMAT_TXT, detailed=False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. doc args 😉 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
"""Show list of supported software""" | ||
silent = build_option('silent') | ||
|
||
ec_paths = find_matching_easyconfigs('*', '*', build_option('robot_path') or []) | ||
ecs = [] | ||
cnt = len(ec_paths) | ||
for idx, ec_path in enumerate(ec_paths): | ||
ecs.append(EasyConfigParser(filename=ec_path).get_config_dict()) | ||
print_msg('\r', prefix=False, newline=False, silent=silent) | ||
print_msg("Processed %d/%d easyconfigs..." % (idx+1, cnt), newline=False, silent=silent) | ||
print_msg('', prefix=False, silent=silent) | ||
|
||
software = {} | ||
for ec in ecs: | ||
software.setdefault(ec['name'], []) | ||
if ec['toolchain']['name'] == DUMMY_TOOLCHAIN_NAME: | ||
toolchain = DUMMY_TOOLCHAIN_NAME | ||
else: | ||
toolchain = '%s/%s' % (ec['toolchain']['name'], ec['toolchain']['version']) | ||
|
||
template_values = template_constant_dict(ec) | ||
|
||
software[ec['name']].append({ | ||
'description': ec['description'], | ||
'homepage': ec['homepage'], | ||
'toolchain': toolchain, | ||
'version': ec['version'], | ||
'versionsuffix': ec.get('versionsuffix', '') % template_values, | ||
}) | ||
|
||
print_msg("Found %d different software packages" % len(software), silent=silent) | ||
|
||
return generate_doc('list_software_%s' % output_format, [software, detailed]) | ||
|
||
|
||
def list_software_rst(software, detailed=False): | ||
"""Return overview of supported software in RST format""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. doc args There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
title = "List of supported software" | ||
lines = [ | ||
title, | ||
'=' * len(title), | ||
'', | ||
"EasyBuild |version| supports %d different software packages (incl. toolchains, bundles):" % len(software), | ||
'', | ||
] | ||
|
||
# links to per-letter tables | ||
letter_refs = '' | ||
key_letters = nub(sorted(k[0].lower() for k in software.keys())) | ||
for letter in string.lowercase: | ||
if letter in key_letters: | ||
if letter_refs: | ||
letter_refs += " - :ref:`list_software_letter_%s`" % letter | ||
else: | ||
letter_refs = ":ref:`list_software_letter_%s`" % letter | ||
lines.extend([letter_refs, '']) | ||
|
||
def key_to_ref(name): | ||
"""Create a reference label for the specified software name.""" | ||
return 'list_software_%s_%d' % (name, sum(ord(l) for l in name)) | ||
|
||
letter = None | ||
sorted_keys = sorted(software.keys(), key=lambda x: x.lower()) | ||
for key in sorted_keys: | ||
|
||
# start a new subsection for each letter | ||
if key[0].lower() != letter: | ||
|
||
# subsection for new letter | ||
letter = key[0].lower() | ||
lines.extend([ | ||
'', | ||
'.. _list_software_letter_%s:' % letter, | ||
'', | ||
"*%s*" % letter.upper(), | ||
'-' * 3, | ||
'', | ||
]) | ||
|
||
if detailed: | ||
# quick links per software package | ||
lines.extend([ | ||
'', | ||
' - '.join(':ref:`%s`' % key_to_ref(k) for k in sorted_keys if k[0].lower() == letter), | ||
'', | ||
]) | ||
|
||
# append software to list, including version(suffix) & toolchain info if detailed info is requested | ||
if detailed: | ||
table_titles = ['version', 'toolchain'] | ||
table_values = [[], []] | ||
|
||
pairs = nub((x['version'], x['versionsuffix']) for x in software[key]) | ||
|
||
with_vsuff = any(vs for (_, vs) in pairs) | ||
if with_vsuff: | ||
table_titles.insert(1, 'versionsuffix') | ||
table_values.insert(1, []) | ||
|
||
for ver, vsuff in sorted((LooseVersion(v), vs) for (v, vs) in pairs): | ||
table_values[0].append('``%s``' % ver) | ||
if vsuff: | ||
table_values[1].append('``%s``' % vsuff) | ||
tcs = [x['toolchain'] for x in software[key] if x['version'] == ver and x['versionsuffix'] == vsuff] | ||
table_values[-1].append(', '.join('``%s``' % tc for tc in sorted(nub(tcs)))) | ||
|
||
lines.extend([ | ||
'', | ||
'.. _%s:' % key_to_ref(key), | ||
'', | ||
'*%s*' % key, | ||
'+' * (len(key) + 2), | ||
'', | ||
' '.join(software[key][-1]['description'].split('\n')).lstrip(' '), | ||
'', | ||
"*homepage*: %s" % software[key][-1]['homepage'], | ||
'', | ||
] + rst_title_and_table(None, table_titles, table_values)) | ||
else: | ||
lines.append("* %s" % key) | ||
|
||
return '\n'.join(lines) | ||
|
||
|
||
def list_software_txt(software, detailed=False): | ||
"""Return overview of supported software in plain text""" | ||
|
||
lines = [''] | ||
for key in sorted(software, key=lambda x: x.lower()): | ||
lines.append('* %s' % key) | ||
if detailed: | ||
lines.extend([ | ||
'', | ||
' '.join(software[key][-1]['description'].split('\n')), | ||
'', | ||
"homepage: %s" % software[key][-1]['homepage'], | ||
'', | ||
]) | ||
pairs = nub((x['version'], x['versionsuffix']) for x in software[key]) | ||
for ver, vsuff in sorted((LooseVersion(v), vs) for (v, vs) in pairs): | ||
tcs = [x['toolchain'] for x in software[key] if x['version'] == ver and x['versionsuffix'] == vsuff] | ||
|
||
line = " * %s v%s" % (key, ver) | ||
if vsuff: | ||
line += " (versionsuffix: '%s')" % vsuff | ||
line += ": %s" % ', '.join(sorted(nub(tcs))) | ||
lines.append(line) | ||
lines.append('') | ||
|
||
return '\n'.join(lines) | ||
|
||
|
||
def list_toolchains(output_format=FORMAT_TXT): | ||
"""Show list of known toolchains.""" | ||
_, all_tcs = search_toolchain('') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a comment why you do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done