diff --git a/easybuild/easyblocks/generic/juliabundle.py b/easybuild/easyblocks/generic/juliabundle.py new file mode 100644 index 0000000000..9aa033420b --- /dev/null +++ b/easybuild/easyblocks/generic/juliabundle.py @@ -0,0 +1,100 @@ +## +# Copyright 2022-2022 Vrije Universiteit Brussel +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for bundles of Julia packages, implemented as an easyblock + +@author: Alex Domingo (Vrije Universiteit Brussel) +""" +import os + +from easybuild.easyblocks.generic.bundle import Bundle +from easybuild.easyblocks.generic.juliapackage import EXTS_FILTER_JULIA_PACKAGES, JuliaPackage +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.modules import get_software_root + + +class JuliaBundle(Bundle): + """ + Bundle of JuliaPackages: install Julia packages as extensions in a bundle + Defines custom sanity checks and module environment + """ + + @staticmethod + def extra_options(extra_vars=None): + """Easyconfig parameters specific to bundles of Julia packages.""" + if extra_vars is None: + extra_vars = {} + # combine custom easyconfig parameters of Bundle & JuliaPackage + extra_vars = Bundle.extra_options(extra_vars) + return JuliaPackage.extra_options(extra_vars) + + def __init__(self, *args, **kwargs): + """Initialize JuliaBundle easyblock.""" + super(JuliaBundle, self).__init__(*args, **kwargs) + + self.cfg['exts_defaultclass'] = 'JuliaPackage' + self.cfg['exts_filter'] = EXTS_FILTER_JULIA_PACKAGES + + # need to disable templating to ensure that actual value for exts_default_options is updated... + with self.cfg.disable_templating(): + # set default options for extensions according to relevant top-level easyconfig parameters + jlpkg_keys = JuliaPackage.extra_options().keys() + for key in jlpkg_keys: + if key not in self.cfg['exts_default_options']: + self.cfg['exts_default_options'][key] = self.cfg[key] + + # Sources of Julia packages are commonly distributed from GitHub repos. + # By default, rename downloaded tarballs to avoid name collisions on + # packages sharing the same version string + if 'sources' not in self.cfg['exts_default_options']: + self.cfg['exts_default_options']['sources'] = [ + { + 'download_filename': 'v%(version)s.tar.gz', + 'filename': '%(name)s-%(version)s.tar.gz', + } + ] + + self.log.info("exts_default_options: %s", self.cfg['exts_default_options']) + + def prepare_step(self, *args, **kwargs): + """Prepare for installing bundle of Julia packages.""" + super(JuliaBundle, self).prepare_step(*args, **kwargs) + + if get_software_root('Julia') is None: + raise EasyBuildError("Julia not included as dependency!") + + def make_module_extra(self, *args, **kwargs): + """Prepend installation directory to JULIA_DEPOT_PATH in module file.""" + txt = super(JuliaBundle, self).make_module_extra() + txt += self.module_generator.prepend_paths('JULIA_DEPOT_PATH', ['']) + return txt + + def sanity_check_step(self, *args, **kwargs): + """Custom sanity check for bundle of Julia packages""" + custom_paths = { + 'files': [], + 'dirs': [os.path.join('packages', self.name)], + } + super(JuliaBundle, self).sanity_check_step(custom_paths=custom_paths) diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index 6d8bc1c729..2e302cd864 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -42,6 +42,7 @@ from easybuild.base import fancylogger from easybuild.base.testing import TestCase from easybuild.easyblocks.generic.gopackage import GoPackage +from easybuild.easyblocks.generic.juliabundle import JuliaBundle from easybuild.easyblocks.generic.juliapackage import JuliaPackage from easybuild.easyblocks.generic.intelbase import IntelBase from easybuild.easyblocks.generic.pythonbundle import PythonBundle @@ -287,8 +288,8 @@ def template_module_only_test(self, easyblock, name, version='1.3.2', extra_txt= os.environ['EBROOTGO'] = '/fake/install/prefix/Go/1.14' os.environ['EBVERSIONGO'] = '1.14' - elif app_class == JuliaPackage: - # $EBROOTJULIA must be set for JuliaPackage easyblock + elif app_class in (JuliaPackage, JuliaBundle): + # $EBROOTJULIA must be set for JuliaPackage/JuliaBundle easyblock os.environ['EBROOTJULIA'] = '/fake/install/prefix/Julia/1.6.7' os.environ['EBVERSIONJULIA'] = '1.6.7'