cea-hpc / modules

Environment Modules: provides dynamic modification of a user's environment
http://modules.sourceforge.net/
GNU General Public License v2.0
668 stars 102 forks source link

Export module file #447

Closed leoheck closed 1 year ago

leoheck commented 2 years ago

Hi, I would like to suggest something like a module export feature if we don't have such thing of course. This would export the modulefile to a simple env.sh script that you can share and use in other computers that do not have a module environment configured.

For instance, I used to manage modules and software/tools in my research group. And most of the time, students would like to have a set of tools in their own computers. The easiest way for me to do that was to copy the tool folder as it is, and then port the modulefile to a script like tool-env.sh to be loaded directly. It would be nice to have such functionality where modulefiles could be exported and converted easily to this bash format instead.

# to export a single module
module export <modulename>

# to export all modulefiles each one in its own file
module export 

Also, a flag would be good to set the output path, but the default option would be to create the file where the command was executed.

xdelaruelle commented 2 years ago

Hi, Such feature is somehow already available as module is composed of:

So calling directly the modulecmd.tcl command will produce on stdout the shell code for the shell specified as argument. The MODULES_CMD environment variable points to the full path location of the modulecmd.tcl command:

$ $MODULES_CMD bash load dot
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:.; export PATH;
_LMFILES_=/usr/share/Modules/modulefiles/dot; export _LMFILES_;
LOADEDMODULES=dot; export LOADEDMODULES;
test 0;

Based on that, some shell script could easily be crafted to create shell scripts from modulefiles in desired location. Here is an example to dump all available modulefiles into bash scripts:

module avail -t -o "" | while read mod; do
  mkdir -p scripts/$(dirname $mod)
  $MODULES_CMD bash load $mod >scripts/$mod.sh
done
leoheck commented 2 years ago

That is pretty nice. And it works really nice here too, thanks for sharing this @xdelaruelle

RobyB commented 2 years ago

Yup this works, but maybe having a dedicated module command the performs that and writes it to a file named modulemame.shell would be great. Of course no high priority for that, just something to remember fir future features.

Roberto

On Wed, Mar 2, 2022, 20:55 Leandro Heck @.***> wrote:

That is pretty nice. And it works really nice here too, thanks for sharing this @xdelaruelle https://github.com/xdelaruelle

— Reply to this email directly, view it on GitHub https://github.com/cea-hpc/modules/issues/447#issuecomment-1057322854, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABEJ6O2JH4NSSLMMNZ6P3G3U57BUXANCNFSM5PXZFQZA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

leoheck commented 2 years ago

Nice, wise words @RobyB. Well, since this can have a simple implementation, and also since its use is not regular, it could be implemented as a function inside the init scripts as an alternative

I created this with @xdelaruelle code

function module_export()
{
  modfiles=($@)
  if [[ "$modfiles" == "" ]]; then
    module avail -t -o "" 2>/dev/null | while read mod; do
      echo "Exporting $mod -> $mod.sh"
      $MODULES_CMD bash load $mod > $mod.sh 2> /dev/null
    done
  else
    IFS=' '
    for mod in "${modfiles[@]}"; do
      echo "Exporting $mod -> $mod.sh"
      $MODULES_CMD bash load $mod > $mod.sh 2> /dev/null
    done
  fi
}

It does not allow to pass the path, but it is working already (tested on zsh)

➜ module_export 
Exporting dot -> dot.sh
Exporting module-git -> module-git.sh
Exporting module-info -> module-info.sh
Exporting modules -> modules.sh
Exporting null -> null.sh
Exporting use.own -> use.own.sh

➜  ls
dot.sh  module-git.sh  module-info.sh  modules.sh  null.sh  use.own.sh

➜  rm -rf *

➜  module_export dot null
Exporting dot -> dot.sh
Exporting null -> null.sh

➜  ls
dot.sh  null.sh
xdelaruelle commented 2 years ago

@RobyB It would mean to add a mod-to-sh sub-command that would take 2 arguments: shell name and module name.

I would prefer outputting shell code directly on stdout, then let people choose where to save that code with I/O redirection.

$ module mod-to-sh bash modname >modname.sh
leoheck commented 2 years ago

I would prefer outputting shell code directly on stdout

@xdelaruelle may I ask why this is better in this case? I think it is a good approach. But it is going to do half of the work since I think most of the time people want to have a file.

But having the command that outputs to a shell it is easy to create the one that redirects to a file.

Ah, and fix the typo in your preview example (you mentioned mod-to-sh and not sh-to-mod)

xdelaruelle commented 2 years ago

@xdelaruelle may I ask why this is better in this case? I think it is a good approach. But it is going to do half of the work since I think most of the time people want to have a file.

I do not see a clear consensus on where to save such file with what file name. People will want different file location, different filename extension. So it seems simpler to output the content to stdout then let people decide what they do with that (either just look at the produced code, pipe it to another process or save it into a file)

Ah, and fix the typo in your preview example (you mentioned mod-to-sh and not sh-to-mod)

I do not understand this part of your comment. There is no typo, this is about introducing a new sub-command on the module command. This sub-command could be named mod-to-sh and it would be somehow the opposite of the sh-to-mod sub-command.

leoheck commented 2 years ago

Alright, it makes sense.

I do not understand this part of your comment..

It is not a big deal, but you are proposing this command mod-to-sh and the example you are showing shows sh-to-mod. Unless you are showing the existing opposite command. But I thought you wanted to show the command you are proposing, instead.

xdelaruelle commented 2 years ago

It is not a big deal, but you are proposing this command mod-to-sh and the example you are showing shows sh-to-mod. Unless you are showing the existing opposite command. But I thought you wanted to show the command you are proposing, instead.

Got it. Thanks. I have fixed the comment.