Skip to content
Snippets Groups Projects

ENH: New option in createFSLWrapper to generate wrapper script with different name to executable

Merged Paul McCarthy requested to merge rf/rename-wrapper into master
4 files
+ 116
87
Compare changes
  • Side-by-side
  • Inline
Files
4
#!/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 should 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
@@ -60,60 +18,75 @@ 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 target 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"
# 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
targetScript="${FSLDIR}/share/fsl/bin/$script"
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 [[ "${target}" == *"_gui" ]] && [ ! -f "${target}" ]; then
wrapper=${wrapper/%_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
# 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 +94,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
Loading