From 7f432bca3f9b3d461a3d802cd0f9de283f7fb0f3 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Fri, 31 Dec 2021 13:12:46 +0000
Subject: [PATCH 1/4] RF: Change variable names to make script easier to follow

---
 share/fsl/sbin/createFSLWrapper | 70 ++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/share/fsl/sbin/createFSLWrapper b/share/fsl/sbin/createFSLWrapper
index 5ad8a0b..07dfab0 100755
--- a/share/fsl/sbin/createFSLWrapper
+++ b/share/fsl/sbin/createFSLWrapper
@@ -48,7 +48,7 @@
 # file systems are usually case-sensitive.
 #
 # To work around this, and to not accidentally create a link called <Command>
-# to <command>, the FSL package post link scripts should only specify
+# to <command>, the FSL package post link scripts must only specify
 # "<Command>_gui", and *not* "<Command>".  This script will create a wrapper
 # script for the appropriate variant ("<Command>_gui" on macOS, or "<Command>"
 # on Linux).
@@ -60,60 +60,66 @@ targets="$@"
 
 # Only create wrappers if the FSL_CREATE_WRAPPER_SCRIPTS
 # environment variable is set
-if [ -z "$FSL_CREATE_WRAPPER_SCRIPTS" ]; then
+if [ -z "${FSL_CREATE_WRAPPER_SCRIPTS}" ]; then
   exit 0
 fi
 
 # Only create wrappers if FSLDIR exists
-if [ ! -d "$FSLDIR" ]; then
+if [ ! -d "${FSLDIR}" ]; then
   exit 0
 fi
 
 # and if FSLDIR == PREFIX
-if [ "$FSLDIR" != "$PREFIX" ]; then
+if [ "${FSLDIR}" != "${PREFIX}" ]; then
   exit 0
 fi
 
 
-for script in $targets; do
-  sourceScript="${PREFIX}/bin/$script"
+for targetName in ${targets}; do
 
-  # Wrapper script for a FSL TCL GUI - here, we
-  # remove the _gui suffix if no source file
-  # exists (in which we are likely running on
-  # Linux).
-  if [[ "$script" == *"_gui" ]] && [ ! -f "$sourceScript" ]; then
-    script=${script/_gui/}
-    sourceScript="${PREFIX}/bin/$script"
-  fi
+  target="${PREFIX}/bin/${targetName}"
 
-  targetScript="${FSLDIR}/share/fsl/bin/$script"
+  # Wrapper script for a FSL TCL GUI - here,
+  # we remove the _gui suffix if the target
+  # file does not exist (in which case we are
+  # likely running on Linux).
+  if [[ "${targetName}" == *"_gui" ]] && [ ! -f "${target}" ]; then
+    targetName=${targetName/%_gui}
+    target=${target/%_gui}
+  fi
 
-  if [ ! -f "$sourceScript" ]; then
+  # Don't create wrapper scripts for non-
+  # existent targets (e.g. the post-link.sh
+  # script for a package may be out-dated,
+  # and request wrappers for commmands that
+  # have been removed).
+  if [ ! -f "${target}" ]; then
     continue
   fi
 
+  wrapper="${FSLDIR}/share/fsl/bin/${targetName}"
+
   # create share/fsl/bin/ if it doesn't
   # already exist
-  if [ ! -e "$FSLDIR/share/fsl/bin" ]; then
-    mkdir -p "$FSLDIR/share/fsl/bin"
+  if [ ! -e "${FSLDIR}/share/fsl/bin" ]; then
+    mkdir -p "${FSLDIR}/share/fsl/bin"
   fi
 
-  # remove target script if it already exists
-  if [ -e "$targetScript" ]; then
-    rm "$targetScript"
+  # remove wrapper script if it already exists
+  if [ -e "${wrapper}" ]; then
+    rm "${wrapper}"
   fi
 
   # Figure out whether this is a python
   # executable or some other type of
   # executable.
-  id=$(head -c 1024 "$sourceScript" | grep -e '^#!.*pythonw\?$')
+  id=$(head -c 1024 "${target}" | grep -e '^#!.*pythonw\?$')
 
   # Non-python executable - use
   # a pass-through script
-  if [ -z "$id" ]; then
-    echo "#!/usr/bin/env bash"         > "$targetScript"
-    echo "$FSLDIR/bin/$script "'"$@"' >> "$targetScript"
+  if [ -z "${id}" ]; then
+    echo "#!/usr/bin/env bash" > "${wrapper}"
+    echo "${target} "'"$@"'   >> "${wrapper}"
   else
 
     # Python executable - run it via
@@ -121,21 +127,21 @@ for script in $targets; do
     # mode.  Under macOS, GUI apps are
     # invoked with pythonw, so we need
     # to preserve the interpreter.
-    if [[ "$id" == *"pythonw" ]]; then
+    if [[ "${id}" == *"pythonw" ]]; then
       interp="pythonw"
     else
       interp="python"
     fi
 
-    echo "#!/usr/bin/env bash"                              > "$targetScript"
-    echo "${FSLDIR}/bin/${interp} -I $sourceScript "'"$@"' >> "$targetScript"
+    echo "#!/usr/bin/env bash"                          > "${wrapper}"
+    echo "${FSLDIR}/bin/${interp} -I ${target} "'"$@"' >> "${wrapper}"
   fi
 
   # Preserve file permissions
-  if [[ "$OSTYPE" == "darwin"* ]]; then
-    perms=$(stat -f "%A" "$sourceScript")
-    chmod ${perms} "$targetScript"
+  if [[ "${OSTYPE}" == "darwin"* ]]; then
+    perms=$(stat -f "%A" "${target}")
+    chmod ${perms} "${wrapper}"
   else
-    chmod --reference="$sourceScript" "$targetScript"
+    chmod --reference="${target}" "${wrapper}"
   fi
 done
-- 
GitLab


From 5ab211b1bf233746e0aabb1814aad3f34e93c737 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Fri, 31 Dec 2021 17:12:50 +0000
Subject: [PATCH 2/4] ENH: New option in createFSLWrapper to generate wrapper
 script with different name to executable

---
 share/fsl/sbin/createFSLWrapper | 75 +++++++++------------------------
 share/fsl/sbin/removeFSLWrapper | 29 +++++++++----
 2 files changed, 41 insertions(+), 63 deletions(-)

diff --git a/share/fsl/sbin/createFSLWrapper b/share/fsl/sbin/createFSLWrapper
index 07dfab0..5093df3 100755
--- a/share/fsl/sbin/createFSLWrapper
+++ b/share/fsl/sbin/createFSLWrapper
@@ -1,57 +1,15 @@
 #!/usr/bin/env bash
 #
 # Create wrapper scripts in $FSLDIR/share/fsl/bin/ which invoke commands that
-# are installed in $FSLDIR/bin/.
+# are installed in $FSLDIR/bin/. Calling this script like:
 #
-# This script is used to create isolated versions of all executables provided
-# by FSL projects, so they can be added to the user $PATH without any other
-# executables that are installed into the FSL conda environment (for example,
-# python, pip, tcl, etc).
+#   createFSLWrapper command1 command2 command3
 #
-# This script is intended to be called by the post-link.sh script of the conda
-# recipe for each FSL project that provides executable commands.
+# will cause wrapper scripts to be created in $FSLDIR/share/fsl/bin/, which
+# call the commands of the same name in $FSLDIR/bin/, i.e.:
 #
-# This script should only be invoked when FSL is being installed via the
-# fslinstaller script - it is not intended to be used when individual FSL
-# projects are explicitly installed into a custom conda environment.
-#
-# The fslinstaller script should ensure that the FSLDIR and
-# FSL_CREATE_WRAPPER_SCRIPTS variables are set appropriately before creating
-# the FSL conda environment.
-#
-# Wrapper scripts will only be created if the following conditions are met:
-#
-#  - The $FSLDIR and $PREFIX environment variables are set, and
-#    are equivalent
-#  - The $FSL_CREATE_WRAPPER_SCRIPTS environment variable is set and is not
-#    empty.
-#
-# Wrapper scripts, and not sym-links, are used to avoid a couple of potential
-# problems:
-#
-#  - We need python executables to exclusively use the libraries installed in
-#    the FSL conda environment. Users may have other Python environments
-#    activated, and/or libraries installed into a local site-packages
-#    directory. So we need to invoke the python interpreter in isolated mode,
-#    with the -I flag:
-#
-#        https://docs.python.org/3/using/cmdline.html#id2
-#
-#  - There is no guarantee that a shell supports shebang lines longer than 127
-#    characters. Depending on where FSL is installed, it may not be possible
-#    to have a shebang line pointing to $FSLDIR/bin/python which does not
-#    exceed 127 characters.
-#
-# Wrapper scripts are created for *all* FSL commands, including FSL TCL GUI
-# commands (e.g. "fsl", "Flirt", "Flirt_gui", etc).  FSL TCL GUIs are called
-# (e.g.) "<Command>" om Linux, but "<Command>_gui" on macOS, because macOS
-# file systems are usually case-sensitive.
-#
-# To work around this, and to not accidentally create a link called <Command>
-# to <command>, the FSL package post link scripts must only specify
-# "<Command>_gui", and *not* "<Command>".  This script will create a wrapper
-# script for the appropriate variant ("<Command>_gui" on macOS, or "<Command>"
-# on Linux).
+#    $FSLDIR/share/fsl/bin/command1 calls $FSLDIR/bin/command1
+#    $FSLDIR/share/fsl/bin/command2 calls $FSLDIR/bin/command2
 
 # Names of all executables for which wrapper
 # scripts are to be created are passed as
@@ -75,16 +33,27 @@ if [ "${FSLDIR}" != "${PREFIX}" ]; then
 fi
 
 
-for targetName in ${targets}; do
+for target in ${targets}; do
+
+  # A wrapper script with a different
+  # name to the target can be created
+  # by passing "targetName=wrapperName"
+  if [[ "${target}" == *"="* ]]; then
+    wrapper=${target#*=}
+    target=${target%=*}
+  else
+    wrapper=${target}
+  fi
 
-  target="${PREFIX}/bin/${targetName}"
+  target="${FSLDIR}/bin/${target}"
+  wrapper="${FSLDIR}/share/fsl/bin/${wrapper}"
 
   # Wrapper script for a FSL TCL GUI - here,
   # we remove the _gui suffix if the target
   # file does not exist (in which case we are
   # likely running on Linux).
-  if [[ "${targetName}" == *"_gui" ]] && [ ! -f "${target}" ]; then
-    targetName=${targetName/%_gui}
+  if [[ "${target}" == *"_gui" ]] && [ ! -f "${target}" ]; then
+    wrapper=${wrapper/%_gui}
     target=${target/%_gui}
   fi
 
@@ -97,8 +66,6 @@ for targetName in ${targets}; do
     continue
   fi
 
-  wrapper="${FSLDIR}/share/fsl/bin/${targetName}"
-
   # create share/fsl/bin/ if it doesn't
   # already exist
   if [ ! -e "${FSLDIR}/share/fsl/bin" ]; then
diff --git a/share/fsl/sbin/removeFSLWrapper b/share/fsl/sbin/removeFSLWrapper
index 8b42934..6e122d7 100755
--- a/share/fsl/sbin/removeFSLWrapper
+++ b/share/fsl/sbin/removeFSLWrapper
@@ -1,7 +1,7 @@
 #!/usr/bin/env bash
 #
 # Remove wrapper script/links in $FSLDIR/share/fsl/bin/ which invoke commands
-# that are installed in $FSLDIR/bin/.  See createFSLWrapper for more
+# that are installed in $FSLDIR/bin/. See createFSLWrapper for more
 # information.
 #
 # This script is intended to be called by the pre-unlink.sh script of the
@@ -19,25 +19,36 @@ targets="$@"
 # delete any wrapper scripts that exist.
 
 # Only remove wrappers if FSLDIR exists
-if [ ! -d "$FSLDIR" ]; then
+if [ ! -d "${FSLDIR}" ]; then
   exit 0
 fi
 
 # and if FSLDIR == PREFIX
-if [ "$FSLDIR" != "$PREFIX" ]; then
+if [ "${FSLDIR}" != "${PREFIX}" ]; then
   exit 0
 fi
 
 # Only remove if scripts are in subdirectory of FSLDIR
-for script in $targets; do
-  targetScript="${FSLDIR}/share/fsl/bin/$script"
+for target in ${targets}; do
+
+  # A wrapper script with a different
+  # name to the target can be created
+  # by passing "targetName=wrapperName"
+  if [[ "${target}" == *"="* ]]; then
+    wrapper=${target#*=}
+    target=${target%=*}
+  else
+    wrapper=${target}
+  fi
+
+  wrapper="${FSLDIR}/share/fsl/bin/${wrapper}"
 
   # See comment about FSL GUIs in post-link.sh
-  if [[ "$targetScript" == *"_gui" ]] && [ ! -f "$targetScript" ]; then
-    targetScript=${targetScript/_gui/}
+  if [[ "${target}" == *"_gui" ]] && [ ! -f "${wrapper}" ]; then
+    wrapper=${wrapper/%_gui}
   fi
 
-  if [ -f "$targetScript" ]; then
-    rm "$targetScript"
+  if [ -f "${wrapper}" ]; then
+    rm "${wrapper}"
   fi
 done
-- 
GitLab


From eeb2580ca43eeb40bb2143cc13c4bb090015f224 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Fri, 31 Dec 2021 17:13:20 +0000
Subject: [PATCH 3/4] TEST: Test createFSLWrapper rename capability

---
 tests/test_create_remove_wrapper.py | 40 +++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/tests/test_create_remove_wrapper.py b/tests/test_create_remove_wrapper.py
index b2abcce..624fd5e 100755
--- a/tests/test_create_remove_wrapper.py
+++ b/tests/test_create_remove_wrapper.py
@@ -305,6 +305,46 @@ def test_create_wrappers_no_handle_gui_wrappers():
                 assert not op.exists(wrapper)
 
 
+def test_create_wrappers_rename():
+    """Tests the renaming functionality in createFSLWrapper.  If
+    $FSLDIR/bin/script exists, a wrapper with a different name
+    (e.g. $FSLDIR/share/fsl/bin/renamed_script) can be created by passing
+    "script=renamed_script".
+    """
+
+    # Keys are passed to createFSLWrapper, values
+    # are wrappers that should be created
+    scripts = {
+        'script1=renamed_script1'         : 'renamed_script1',
+        'script2=renamed_script2'         : 'renamed_script2',
+        'script3_gui=renamed_script3_gui' : 'renamed_script3_gui',
+        'script4_gui=renamed_script4'     : 'renamed_script4'
+    }
+
+    with temp_fsldir() as (fsldir, wrapperdir):
+        for script in scripts.keys():
+            target = script.split('=')[0]
+            with open(target, 'wt') as f:
+                touch(op.join(fsldir, 'bin', target))
+
+        for wrappers in it.permutations(scripts.keys()):
+            args  = ' '.join(wrappers)
+            run(f'{CREATE_WRAPPER} {args}')
+
+            for arg in wrappers:
+                target  = arg.split('=')[0]
+                wrapper = op.join(wrapperdir, scripts[arg])
+
+                assert op.exists(wrapper)
+                assert get_called_command(wrapper) == target
+
+            run(f'{REMOVE_WRAPPER} {args}')
+            for arg in wrappers:
+                target  = scripts[arg]
+                wrapper = op.join(wrapperdir, target)
+                assert not op.exists(wrapper)
+
+
 if __name__ == '__main__':
     # base dir can be speecified on command line
     if len(sys.argv) > 1:
-- 
GitLab


From 1393d89493cf2589e6d9d34f910721fa38db7fda Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Fri, 31 Dec 2021 17:14:24 +0000
Subject: [PATCH 4/4] DOC: changelog

---
 CHANGELOG.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b86a7a..58f02a9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
 # FSL base project changelog
 
 
+## 2112.6 (Thursday 31st December 2021)
+
+* The `createFSLWrapper` script nowe has the ability to generate a wrapper
+  script with a name different to the called executable.
+
 
 ## 2112.5 (Thursday 30th December 2021)
 
-- 
GitLab