From 19b481ec7c0e266eb2cea87e35d2424129c2a8d3 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 29 Aug 2025 17:07:28 +0200 Subject: [PATCH 1/3] Avoid using user-HOME when installing RPackage --- easybuild/easyblocks/generic/rpackage.py | 49 +++++++++++------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/easybuild/easyblocks/generic/rpackage.py b/easybuild/easyblocks/generic/rpackage.py index 7fa64356737..d9fdda97739 100644 --- a/easybuild/easyblocks/generic/rpackage.py +++ b/easybuild/easyblocks/generic/rpackage.py @@ -36,6 +36,7 @@ import pathlib import re +import easybuild.tools.environment as env from easybuild.easyblocks.r import EXTS_FILTER_R_PACKAGES, EB_R from easybuild.easyblocks.generic.configuremake import check_config_guess, obtain_config_guess from easybuild.framework.easyconfig import CUSTOM @@ -52,16 +53,11 @@ def make_R_install_option(opt, values, cmdline=False): """ txt = "" if values: + values_str = " ".join(values) if cmdline: - txt = " --%s=\"%s" % (opt, values[0]) + txt = f' --{opt}="{values_str}"' else: - txt = "%s=c(\"%s" % (opt, values[0]) - for i in values[1:]: - txt += " %s" % i - if cmdline: - txt += "\"" - else: - txt += "\")" + txt = f'{opt}=c("{values_str}")' return txt @@ -81,7 +77,7 @@ def extra_options(extra_vars=None): return extra_vars def __init__(self, *args, **kwargs): - """Initliaze RPackage-specific class variables.""" + """Initialize RPackage-specific class variables.""" super().__init__(*args, **kwargs) @@ -130,17 +126,9 @@ def make_r_cmd(self, prefix=None): def make_cmdline_cmd(self, prefix=None): """Create a command line to install an R package.""" - confvars = "" - if self.configurevars: - confvars = make_R_install_option("configure-vars", self.configurevars, cmdline=True) - confargs = "" - if self.configureargs: - confargs = make_R_install_option("configure-args", self.configureargs, cmdline=True) - - if prefix: - prefix = '--library=%s' % prefix - else: - prefix = '' + confvars = make_R_install_option("configure-vars", self.configurevars, cmdline=True) + confargs = make_R_install_option("configure-args", self.configureargs, cmdline=True) + prefix = make_R_install_option("prefix", prefix, cmdline=True) loc = self.start_dir if loc is None: @@ -173,9 +161,21 @@ def build_step(self): """No separate build step for R packages.""" pass + def set_R_user_vars(self): + """Set R user environment variables to avoid writes to home directory.""" + # set $R_LIBS_USER to non-existing path in build directory, + # to avoid picking up on R packages installed in home directory of current user + # (from ~/R/x86_64-pc-linux-gnu-library/) + setvar('R_LIBS_USER', os.path.join(self.builddir, 'r_libs')) + # Avoid writes to $HOME/$XDG_CACHE_HOME etc. + r_home = os.path.join(self.builddir, 'R_home') + env.setvar('R_USER_DATA_DIR', os.path.join(r_home, '.data')) + env.setvar('R_USER_CACHE_DIR', os.path.join(r_home, '.cache')) + env.setvar('R_USER_CONFIG_DIR', os.path.join(r_home, '.config')) + def install_R_package(self, cmd, inp=None): """Install R package as specified, and check for errors.""" - + self.set_R_user_vars() res = run_shell_cmd(cmd, stdin=inp) self.check_install_output(res.output) @@ -187,7 +187,6 @@ def check_install_output(self, output): if errors: self.log.info("R package %s failed with error:\n%s", self.name, '\n'.join(errors)) - self.handle_installation_errors() cmd = "R -q --no-save" stdin = """ remove.library(%s) @@ -278,11 +277,7 @@ def prepare_r_ext_install(self): :return: Shell command to run + string to pass to stdin. """ - # set $R_LIBS_USER to non-existing path in build directory, - # to avoid picking up on R packages installed in home directory of current user - # (from ~/R/x86_64-pc-linux-gnu-library/) - setvar('R_LIBS_USER', os.path.join(self.builddir, 'r_libs')) - + self.set_R_user_vars() # determine location if isinstance(self.master, EB_R): # extension is being installed as part of an R installation/module From 86f92db616095eb49250f1e68212b5ca29439904 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 29 Aug 2025 17:46:48 +0200 Subject: [PATCH 2/3] Also set the XDG variables and fix call --- easybuild/easyblocks/generic/rpackage.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/generic/rpackage.py b/easybuild/easyblocks/generic/rpackage.py index d9fdda97739..5646f006396 100644 --- a/easybuild/easyblocks/generic/rpackage.py +++ b/easybuild/easyblocks/generic/rpackage.py @@ -128,7 +128,7 @@ def make_cmdline_cmd(self, prefix=None): """Create a command line to install an R package.""" confvars = make_R_install_option("configure-vars", self.configurevars, cmdline=True) confargs = make_R_install_option("configure-args", self.configureargs, cmdline=True) - prefix = make_R_install_option("prefix", prefix, cmdline=True) + prefix = make_R_install_option("prefix", [prefix], cmdline=True) loc = self.start_dir if loc is None: @@ -167,11 +167,12 @@ def set_R_user_vars(self): # to avoid picking up on R packages installed in home directory of current user # (from ~/R/x86_64-pc-linux-gnu-library/) setvar('R_LIBS_USER', os.path.join(self.builddir, 'r_libs')) - # Avoid writes to $HOME/$XDG_CACHE_HOME etc. + # Avoid writes to $HOME via $XDG_CACHE_HOME, $R_USER_DATA_DIR etc r_home = os.path.join(self.builddir, 'R_home') - env.setvar('R_USER_DATA_DIR', os.path.join(r_home, '.data')) - env.setvar('R_USER_CACHE_DIR', os.path.join(r_home, '.cache')) - env.setvar('R_USER_CONFIG_DIR', os.path.join(r_home, '.config')) + for i in ('CACHE', 'CONFIG', 'DATA'): + path = os.path.join(r_home, i.lower()) + env.setvar(f'XDG_{i}_HOME', path) + env.setvar(f'R_USER_{i}_DIR', path) def install_R_package(self, cmd, inp=None): """Install R package as specified, and check for errors.""" From 9814f842cadda631af201826ea61a0871c8f91c3 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 1 Sep 2025 08:57:59 +0200 Subject: [PATCH 3/3] Fix prefix option name --- easybuild/easyblocks/generic/rpackage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/rpackage.py b/easybuild/easyblocks/generic/rpackage.py index 5646f006396..c7791bbdb95 100644 --- a/easybuild/easyblocks/generic/rpackage.py +++ b/easybuild/easyblocks/generic/rpackage.py @@ -128,7 +128,7 @@ def make_cmdline_cmd(self, prefix=None): """Create a command line to install an R package.""" confvars = make_R_install_option("configure-vars", self.configurevars, cmdline=True) confargs = make_R_install_option("configure-args", self.configureargs, cmdline=True) - prefix = make_R_install_option("prefix", [prefix], cmdline=True) + prefix = make_R_install_option("library", [prefix], cmdline=True) loc = self.start_dir if loc is None: