forked from easybuilders/easybuild-easyblocks
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpythonbundle.py
More file actions
119 lines (95 loc) · 4.9 KB
/
pythonbundle.py
File metadata and controls
119 lines (95 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
##
# Copyright 2018-2019 Ghent University
#
# 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 <http://www.gnu.org/licenses/>.
##
"""
EasyBuild support for installing a bundle of Python packages, implemented as a generic easyblock
@author: Kenneth Hoste (Ghent University)
"""
import os
from easybuild.easyblocks.generic.bundle import Bundle
from easybuild.easyblocks.generic.pythonpackage import EBPYTHONPREFIXES, PythonPackage, det_pylibdir
from easybuild.tools.build_log import EasyBuildError
from easybuild.tools.modules import get_software_root
class PythonBundle(Bundle):
"""
Bundle of modules: only generate module files, nothing to build/install
"""
@staticmethod
def extra_options(extra_vars=None):
"""Easyconfig parameters specific to bundles of Python packages."""
if extra_vars is None:
extra_vars = {}
# combine custom easyconfig parameters of Bundle & PythonPackage
extra_vars = Bundle.extra_options(extra_vars)
return PythonPackage.extra_options(extra_vars)
def __init__(self, *args, **kwargs):
"""Initialize PythonBundle easyblock."""
super(PythonBundle, self).__init__(*args, **kwargs)
self.cfg['exts_defaultclass'] = 'PythonPackage'
# need to disable templating to ensure that actual value for exts_default_options is updated...
prev_enable_templating = self.cfg.enable_templating
self.cfg.enable_templating = False
# set default options for extensions according to relevant top-level easyconfig parameters
pypkg_keys = PythonPackage.extra_options().keys()
for key in pypkg_keys:
if key not in self.cfg['exts_default_options']:
self.cfg['exts_default_options'][key] = self.cfg[key]
self.cfg['exts_default_options']['download_dep_fail'] = True
self.log.info("Detection of downloaded extension dependencies is enabled")
self.cfg.enable_templating = prev_enable_templating
self.log.info("exts_default_options: %s", self.cfg['exts_default_options'])
self.pylibdir = None
# figure out whether this bundle of Python packages is being installed for multiple Python versions
self.multi_python = 'Python' in self.cfg['multi_deps']
def prepare_step(self, *args, **kwargs):
"""Prepare for installing bundle of Python packages."""
super(Bundle, self).prepare_step(*args, **kwargs)
if get_software_root('Python') is None:
raise EasyBuildError("Python not included as dependency!")
self.pylibdir = det_pylibdir()
def test_step(self):
"""No global test step for bundle of Python packages."""
# required since runtest is set to True for Python packages by default
pass
def make_module_extra(self, *args, **kwargs):
"""Extra statements to include in module file: update $PYTHONPATH."""
txt = super(Bundle, self).make_module_extra(*args, **kwargs)
# update $EBPYTHONPREFIXES rather than $PYTHONPATH
# if this Python package was installed for multiple Python versions
if self.multi_python:
txt += self.module_generator.prepend_paths(EBPYTHONPREFIXES, '')
else:
txt += self.module_generator.prepend_paths('PYTHONPATH', self.pylibdir)
return txt
def sanity_check_step(self, *args, **kwargs):
"""Custom sanity check for bundle of Python package."""
# inject directory path that uses %(pyshortver)s template into default value for sanity_check_paths
# this is relevant for installations of Python bundles for multiple Python versions (via multi_deps)
# (we can not pass this via custom_paths, since then the %(pyshortver)s template value will not be resolved)
if not self.cfg['sanity_check_paths']:
self.cfg['sanity_check_paths'] = {
'files': [],
'dirs': [os.path.join('lib', 'python%(pyshortver)s', 'site-packages')],
}
super(Bundle, self).sanity_check_step(*args, **kwargs)