Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .hunspell.en.dic
Original file line number Diff line number Diff line change
Expand Up @@ -1338,3 +1338,4 @@ ts
OSX
BAWT
HTTPS
mirrorEnvVarChange
4 changes: 3 additions & 1 deletion INSTALL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1721,7 +1721,9 @@ installation.
| :mconfig:`implicit_requirement` | ``1`` | :instopt:`--enable-implicit-requirement`, | | |
| | | :envvar:`MODULES_IMPLICIT_REQUIREMENT` | | |
+-----------------------------------+----------------------------------------------+----------------------------------------------+--------------+-----------+
| :mconfig:`info_extension` | ``0`` | :envvar:`MODULES_INFO_EXTENSION`, | | |
| :mconfig:`info_extension` | ``0`` | :envvar:`MODULES_INFO_EXTENSION` | | |
+-----------------------------------+----------------------------------------------+----------------------------------------------+--------------+-----------+
| :mconfig:`linked_envvars` | *Empty by default* | :envvar:`MODULES_LINKED_ENVVARS` | | |
+-----------------------------------+----------------------------------------------+----------------------------------------------+--------------+-----------+
| :mconfig:`list_output` | ``header:idx:variant:sym:tag:key`` | :instopt:`--with-list-output`, | | |
| | | :envvar:`MODULES_LIST_OUTPUT`, | | |
Expand Down
1 change: 1 addition & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Modules 5.7.0 (not yet released)
command are not affected by this mechanism. When :mconfig:`info_extension`
is changed with :subcmd:`config` sub-command, it sets the
:envvar:`MODULES_INFO_EXTENSION` environment variable. (fix issue #585)
* Doc: add :ref:`linked-envvars` design notes.


.. _5.6 release notes:
Expand Down
8 changes: 5 additions & 3 deletions doc/source/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1075,8 +1075,9 @@ The following environment variables appeared on Modules 5.
+------------+-----------------------------------------------------------------+
| 5.7 | :envvar:`MODULES_PATH_ENTRY_REORDER`, |
| | :envvar:`MODULES_PAGINATE`, |
| | :envvar:`MODULES_NON_EXPORTABLE_TAGS` |
| | :envvar:`MODULES_INFO_EXTENSION` |
| | :envvar:`MODULES_NON_EXPORTABLE_TAGS`, |
| | :envvar:`MODULES_INFO_EXTENSION`, |
| | :envvar:`MODULES_LINKED_ENVVARS` |
+------------+-----------------------------------------------------------------+

Modules Specific Tcl Commands
Expand Down Expand Up @@ -1290,7 +1291,8 @@ The following Modules configuration option has been introduced on Modules 5.
| | :mconfig:`spider_indepth`, :mconfig:`require_via` |
+------------+-----------------------------------------------------------------+
| 5.7 | :mconfig:`path_entry_reorder`, :mconfig:`paginate`, |
| | :mconfig:`non_exportable_tags`, :mconfig:`info_extension` |
| | :mconfig:`non_exportable_tags`, :mconfig:`info_extension`, |
| | :mconfig:`linked_envvars` |
+------------+-----------------------------------------------------------------+

:mconfig:`auto_handling`
Expand Down
77 changes: 77 additions & 0 deletions doc/source/design/linked-envvars.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.. _linked-envvars:

Linked environment variables
============================

This document describes the mechanism to link one environment variables onto
others and apply the same value changes.

The goal is to link environment variables together and apply all changes to
both once linked.

Design choices:

* When link is being established, variable value is not synced
* Link is not reflexive: if A is linked to B, all changes made to A are
applied to B, but direct changes to B are not applied to A unless if this
link is also configured
* A ``module display`` shows the environment changes applying to linked
environment variables

This mechanism applies to all environment variable management modulefile
commands and module sub-commands:

* :mfcmd:`append-path`
* :mfcmd:`prepend-path`
* :mfcmd:`pushenv`
* :mfcmd:`remove-path`
* :mfcmd:`setenv`
* :mfcmd:`unsetenv`

.. note:: Link is not effective when a value is set to the environment
variable through the ``::env`` Tcl global array.

``linked_envvars`` configuration option
---------------------------------------

New configuration option :mconfig:`linked_envvars` is made to configure these
links between environment variables.

* Items are separated by colon character
* One variable can be linked to several ones, either through:

- one item with several variables: ``A&B&C``
- several items: ``A&B:A&C``

Implementation
--------------

* Define an internal state (``current_envvar``) to indicate the name of the
environment variable currently modified
* Set a ``trace`` to execute ``mirrorEnvVarChange`` procedure at the end of
the execution of environment variable management commands
* No trace setup if :mconfig:`linked_envvars` is empty
* ``mirrorEnvVarChange`` procedure:

- get currently modified environment variable name through
``current_envvar`` state
- get environment variable change command to execute through
``command-string`` trace argument
- replace ``current_envvar`` in this command string by linked environment
variable name
- execute resulting command string in currently active interpreter
- do this for each linked environment variable, including recursively linked
ones: trace is triggered one and handle all environment variables to avoid
cycle loop

.. note:: No other environment variable change can occur between the
definition of the ``current_envvar`` state and the execution of the
``mirrorEnvVarChange`` trace procedure. The link mechanism cannot apply to
Modules internal environment variables like ``__MODULES_SHARE_*``.

.. note:: Environment variable name argument is always positioned before any
value, thus replacing the first occurrence found of this name will
accurately change the name argument on all environment variable change
commands.

.. vim:set tabstop=2 shiftwidth=2 expandtab autoindent:
41 changes: 41 additions & 0 deletions doc/source/module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,21 @@ Module Sub-Commands

.. versionadded:: 5.7

.. mconfig:: linked_envvars

Define links between environment variables to apply same value modification
to each linked variables.

This configuration option is set to an empty value by default. The
:envvar:`MODULES_LINKED_ENVVARS` environment variable is defined by
:subcmd:`config` sub-command when changing this configuration option from
its default value. See :envvar:`MODULES_LINKED_ENVVARS` description for
details

.. only:: html or latex

.. versionadded:: 5.7

.. mconfig:: list_output

Content to report in addition to module names on :subcmd:`list` sub-command
Expand Down Expand Up @@ -5149,6 +5164,32 @@ ENVIRONMENT

.. versionadded:: 5.7

.. envvar:: MODULES_LINKED_ENVVARS

A colon-separated list of environment variable link sets. Each link set is a
group of environment variable names separated by the ampersand character.
When an environment variable modification command is applied to the first
variable in a link set, the same command is automatically applied to all
other variables in that set.

This link mechanism applies to all environment variable management modulefile
commands and module sub-commands (:mfcmd:`append-path`,
:mfcmd:`prepend-path`, :mfcmd:`pushenv`, :mfcmd:`remove-path`,
:mfcmd:`setenv` and :mfcmd:`unsetenv`).

For example, if the configuration option is set to ``FOO&BAR&BAZ:BAR&QUX``, a
:mfcmd:`prepend-path` command applied to ``FOO`` will also be applied to
``BAR``, ``BAZ``, and ``QUX``. Linking is not reflexive: a command applied to
``QUX`` is not propagated to any other environment variable in the link set.

This environment variable value supersedes the default value set in the
:mconfig:`linked_envvars` configuration option. It can be defined with the
:subcmd:`config` sub-command.

.. only:: html or latex

.. versionadded:: 5.7

.. envvar:: MODULES_LIST_OUTPUT

A colon separated list of the elements to report in addition to module names
Expand Down
2 changes: 1 addition & 1 deletion init/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ comp_lint_opts := -a -i --all --icase
comp_modtosh_opts := --auto --no-auto --force -f --icase -i
comp_path_opts := -d --delim --duplicates
comp_rm_path_opts := -d --delim --index
comp_config_opts := --dump-state --reset abort_on_error advanced_version_spec auto_handling avail_indepth avail_output avail_terse_output cache_buffer_bytes cache_expiry_secs collection_pin_version collection_pin_tag collection_target color colors conflict_unload contact editor extended_default extra_siteconfig hide_auto_loaded home icase ignore_cache ignore_user_rc implicit_default implicit_requirement info_extension list_output list_terse_output locked_configs logged_events logger mcookie_check mcookie_version_check ml nearly_forbidden_days non_exportable_tags pager paginate path_entry_reorder protected_envvars quarantine_support rcfile redirect_output require_via reset_target_state run_quarantine search_match set_shell_startup shells_with_ksh_fpath silent_shell_debug source_cache spider_indepth spider_output spider_terse_output sticky_purge tag_abbrev tag_color_name tcl_linter term_background term_width unique_name_loaded unload_match_order variant_shortcut verbosity wa_277
comp_config_opts := --dump-state --reset abort_on_error advanced_version_spec auto_handling avail_indepth avail_output avail_terse_output cache_buffer_bytes cache_expiry_secs collection_pin_version collection_pin_tag collection_target color colors conflict_unload contact editor extended_default extra_siteconfig hide_auto_loaded home icase ignore_cache ignore_user_rc implicit_default implicit_requirement info_extension linked_envvars list_output list_terse_output locked_configs logged_events logger mcookie_check mcookie_version_check ml nearly_forbidden_days non_exportable_tags pager paginate path_entry_reorder protected_envvars quarantine_support rcfile redirect_output require_via reset_target_state run_quarantine search_match set_shell_startup shells_with_ksh_fpath silent_shell_debug source_cache spider_indepth spider_output spider_terse_output sticky_purge tag_abbrev tag_color_name tcl_linter term_background term_width unique_name_loaded unload_match_order variant_shortcut verbosity wa_277

define translate-in-script
$(ECHO_GEN)
Expand Down
2 changes: 1 addition & 1 deletion init/fish_completion
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ complete -c module -n '__fish_module_use_stashlist' -f -a "(module stashlist --c
/Stash collection list\$/d; \
/:\$/d; \
/:ERROR:/d;')"
complete -c module -n '__fish_module_use_config' -f -a "--dump-state --reset abort_on_error advanced_version_spec auto_handling avail_indepth avail_output avail_terse_output cache_buffer_bytes cache_expiry_secs collection_pin_version collection_pin_tag collection_target color colors conflict_unload contact editor extended_default extra_siteconfig hide_auto_loaded home icase ignore_cache ignore_user_rc implicit_default implicit_requirement info_extension list_output list_terse_output locked_configs logged_events logger mcookie_check mcookie_version_check ml nearly_forbidden_days non_exportable_tags pager paginate path_entry_reorder protected_envvars quarantine_support rcfile redirect_output require_via reset_target_state run_quarantine search_match set_shell_startup shells_with_ksh_fpath silent_shell_debug source_cache spider_indepth spider_output spider_terse_output sticky_purge tag_abbrev tag_color_name tcl_linter term_background term_width unique_name_loaded unload_match_order variant_shortcut verbosity wa_277"
complete -c module -n '__fish_module_use_config' -f -a "--dump-state --reset abort_on_error advanced_version_spec auto_handling avail_indepth avail_output avail_terse_output cache_buffer_bytes cache_expiry_secs collection_pin_version collection_pin_tag collection_target color colors conflict_unload contact editor extended_default extra_siteconfig hide_auto_loaded home icase ignore_cache ignore_user_rc implicit_default implicit_requirement info_extension linked_envvars list_output list_terse_output locked_configs logged_events logger mcookie_check mcookie_version_check ml nearly_forbidden_days non_exportable_tags pager paginate path_entry_reorder protected_envvars quarantine_support rcfile redirect_output require_via reset_target_state run_quarantine search_match set_shell_startup shells_with_ksh_fpath silent_shell_debug source_cache spider_indepth spider_output spider_terse_output sticky_purge tag_abbrev tag_color_name tcl_linter term_background term_width unique_name_loaded unload_match_order variant_shortcut verbosity wa_277"

complete -f -n '__fish_module_no_subcommand' -c module -a 'help' --description 'Print this or modulefile(s) help info'
complete -f -n '__fish_module_no_subcommand' -c module -a 'avail' --description 'List all or matching available modules'
Expand Down
2 changes: 1 addition & 1 deletion init/zsh-functions/_module.in
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ _module() {
_arguments \
'--dump-state[Report each state value of current Modules execution]' \
'--reset[Unset environment variable relative to configuration key]' \
'1:configuration key:(abort_on_error advanced_version_spec auto_handling avail_indepth avail_output avail_terse_output cache_buffer_bytes cache_expiry_secs collection_pin_version collection_pin_tag collection_target color colors conflict_unload contact editor extended_default extra_siteconfig hide_auto_loaded home icase ignore_cache ignore_user_rc implicit_default implicit_requirement info_extension list_output list_terse_output locked_configs logged_events logger mcookie_check mcookie_version_check ml nearly_forbidden_days non_exportable_tags pager paginate path_entry_reorder protected_envvars quarantine_support rcfile redirect_output require_via reset_target_state run_quarantine search_match set_shell_startup shells_with_ksh_fpath silent_shell_debug source_cache spider_indepth spider_output spider_terse_output sticky_purge tag_abbrev tag_color_name tcl_linter term_background term_width unique_name_loaded unload_match_order variant_shortcut verbosity wa_277)' \
'1:configuration key:(abort_on_error advanced_version_spec auto_handling avail_indepth avail_output avail_terse_output cache_buffer_bytes cache_expiry_secs collection_pin_version collection_pin_tag collection_target color colors conflict_unload contact editor extended_default extra_siteconfig hide_auto_loaded home icase ignore_cache ignore_user_rc implicit_default implicit_requirement info_extension linked_envvars list_output list_terse_output locked_configs logged_events logger mcookie_check mcookie_version_check ml nearly_forbidden_days non_exportable_tags pager paginate path_entry_reorder protected_envvars quarantine_support rcfile redirect_output require_via reset_target_state run_quarantine search_match set_shell_startup shells_with_ksh_fpath silent_shell_debug source_cache spider_indepth spider_output spider_terse_output sticky_purge tag_abbrev tag_color_name tcl_linter term_background term_width unique_name_loaded unload_match_order variant_shortcut verbosity wa_277)' \
&& ret=0
;;
(edit)
Expand Down
46 changes: 46 additions & 0 deletions tcl/envmngt.tcl.in
Original file line number Diff line number Diff line change
Expand Up @@ -1642,6 +1642,9 @@ proc unload-path {cmd mode dflbhv args} {
allow_dup idx_val ign_refcount val_set_is_delim glob_match bhv var\
path_list

# indicate env var name to configured traces
setState current_envvar $var

switch -- $bhv {
noop {
return [list $bhv $var]
Expand Down Expand Up @@ -1792,6 +1795,9 @@ proc add-path {cmd mode dflbhv args} {
path_list
}

# indicate env var name to configured traces
setState current_envvar $var

# clean any previously defined pushenv stack
unset-env [getPushenvVarName $var] 1

Expand Down Expand Up @@ -2062,6 +2068,46 @@ proc getModulesEnvVarGlobList {{loaded_ctx 0}} {
return $envvar_glob_list
}

# trace procedure to apply same env change procedure to linked env vars
proc mirrorEnvVarChange {cmd_str code result op} {
# skip mirror processing if initial command failed
if {$code} {
return
}
set envvar [getState current_envvar]
if {[info exists ::g_linkedEnvvars($envvar)]} {
# collect all direct and indirect linked env vars, avoiding cycle loop
set linked_envvar_list $::g_linkedEnvvars($envvar)
for {set i 0} {$i < [llength $linked_envvar_list]} {incr i} {
set linked_envvar [lindex $linked_envvar_list $i]
if {[info exists ::g_linkedEnvvars($linked_envvar)]} {
lappendNoDup linked_envvar_list\
{*}$::g_linkedEnvvars($linked_envvar)
}
}

if {![isTopEvaluation]} {
set interp_eval_cmd [list interp eval [getCurrentModfileInterpName]]
}

# apply same env var change command on linked env vars
# no other trace hook will be triggered as we are processing this one
foreach linked_envvar $linked_envvar_list {
if {$linked_envvar eq $envvar} {
continue
}
set linked_cmd_str [replaceFirstInStr $cmd_str $envvar\
$linked_envvar]
# adapt execution if called from modulefile interp
if {[info exists interp_eval_cmd]} {
set linked_cmd_str [list {*}$interp_eval_cmd $linked_cmd_str]
}
# execute in same context than initial command
uplevel 1 $linked_cmd_str
}
}
}

# ;;; Local Variables:
# ;;; Mode: tcl-mode
# ;;; tcl-indent-level: 3
Expand Down
Loading
Loading