From d0c9d44f87e208fd244de4a10f0ff30f0c323c64 Mon Sep 17 00:00:00 2001 From: Orion Poplawski Date: Mon, 2 Mar 2015 11:11:27 -0700 Subject: [PATCH] Handle more prefix/suffix cases in createmodule.{sh,py} (bug #1079341) --- createmodule.py | 68 +++++++++++++++++++++++++++++++--------- createmodule.sh | 64 +++++++++++++++++++++++++++++-------- environment-modules.spec | 1 + testscript.sh | 8 +++++ 4 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 testscript.sh diff --git a/createmodule.py b/createmodule.py index a73b1b1..3c778c1 100755 --- a/createmodule.py +++ b/createmodule.py @@ -79,6 +79,7 @@ env2=getenv(". " + " ".join(args)) chdir = None appendpath = {} prependpath = {} +unhandled = {} setenv = {} unsetenv = [] pathnames = [] @@ -88,7 +89,7 @@ def normpaths(paths): newpaths = [] for path in paths: normpath = os.path.normpath(path) - if normpath not in newpaths: + if normpath not in newpaths and normpath != '.': newpaths.append(os.path.normpath(path)) return newpaths @@ -109,19 +110,36 @@ for key in env1.keys(): del env2[key] continue # Determine modifcations to beginning and end of the string - (prepend,append) = env2[key].split(env1[key]) + try: + (prepend,append) = env2[key].split(env1[key]) + except ValueError: + continue if prepend: - prependpaths = prepend.strip(':').split(':') + presep = prepend[-1:] + prependpaths = prepend.strip(presep).split(presep) # LICENSE variables often include paths outside install directory if 'LICENSE' not in key: pathnames += prependpaths - prependpath[key] = ':'.join(normpaths(prependpaths)) + if presep not in prependpath: + prependpath[presep] = {} + newpath = presep.join(normpaths(prependpaths)) + if newpath: + prependpath[presep][key] = newpath + else: + unhandled[key] = env2[key] if append: - appendpaths = append.strip(':').split(':') + appsep = append[0:1] + appendpaths = append.strip(appsep).split(appsep) # LICENSE variables often include paths outside install directory if 'LICENSE' not in key: pathnames += appendpaths - appendpath[key] = ':'.join(normpaths(appendpaths)) + if appsep not in appendpath: + appendpath[appsep] = {} + newpath = appsep.join(normpaths(appendpaths)) + if newpath: + appendpath[appsep][key] = newpath + else: + unhandled[key] = env2[key] del env2[key] # We're left with new keys in env2 @@ -133,13 +151,25 @@ for key in env2.keys(): # LICENSE variables often include paths outside install directory if key != 'MANPATH' and 'LICENSE' not in key: pathnames += prependpaths - prependpath[key] = ':'.join(normpaths(prependpaths)) + if ':' not in prependpath: + prependpath[':'] = {} + prependpath[':'][key] = ':'.join(normpaths(prependpaths)) continue # Set new variables setenv[key] = os.path.normpath(env2[key]) if 'LICENSE' not in key: pathnames.append(setenv[key]) +# Report unhandled keys +for key in unhandled.keys(): + print("Unhandled change of", key, file=sys.stderr) + print("Before <%s>" % env1[key], file=sys.stderr) + print("After <%s>" % unhandled[key], file=sys.stderr) + for sepkey in appendpath.keys(): + appendpath[sepkey].pop(key, None) + for sepkey in prependpath.keys(): + prependpath[sepkey].pop(key, None) + # Determine a prefix prefix=None if options.prefix: @@ -173,13 +203,23 @@ def formatline(item, key, value=None): print(value) # Paths first, grouped by variable name -pathkeys = list(appendpath.keys()) + list(prependpath.keys()) -pathkeys.sort() -for key in pathkeys: - if key in prependpath: - formatline("prepend-path",key,prependpath[key]) - if key in appendpath: - formatline("append-path",key,appendpath[key]) +for sepkey in prependpath.keys(): + pathkeys = prependpath[sepkey].keys() + pathkeys.sort() + for key in pathkeys: + if sepkey == ":": + formatline("prepend-path",key,prependpath[sepkey][key]) + else: + formatline("prepend-path --delim %s" % sepkey,key,prependpath[sepkey][key]) + +for sepkey in appendpath.keys(): + pathkeys = appendpath[sepkey].keys() + pathkeys.sort() + for key in pathkeys: + if sepkey == ":": + formatline("append-path",key,appendpath[sepkey][key]) + else: + formatline("append-path --delim %s" % sepkey,key,appendpath[sepkey][key]) # Setenv setenvkeys = list(setenv.keys()) diff --git a/createmodule.sh b/createmodule.sh index f0b3b32..b0edfc5 100755 --- a/createmodule.sh +++ b/createmodule.sh @@ -74,11 +74,13 @@ echo "#%Module 1.0" #Prefix [ -n "$prefix" ] && echo -e "\nset prefix $prefix\n" +# dedup - remove duplicate entries from a list #Subshell so we can sort the output ( dedup() { list=`mktemp` - echo $1 | sed -r -e 's,[^/]+/\.\./,,g' -e 's,[^/]+/\.\./,,g' -e 's/:/\n/g' | + [ -n "$2" ] && sep=$2 || sep=: + echo $1 | sed -r -e 's,[^/]+/\.\./,,g' -e 's,[^/]+/\.\./,,g' -e "s/\\$sep/\n/g" | while read x do grep -Fx ${x} $list && continue @@ -89,7 +91,7 @@ dedup() { echo $x fi echo $x >> $list - done | tr '\n' : | sed -e 's/:$//' + done | tr '\n' $sep | sed -e "s/\\$sep\$//" rm $list } @@ -114,25 +116,61 @@ do #Test for prepend elif [ "${env2[$key]%${env1[$key]}}" != "${env2[$key]}" ] then - added=$(dedup ${env2[$key]%:${env1[$key]}}) - echo -e "prepend-path\t$key\t${added}" + added=${env2[$key]%${env1[$key]}} + sep=${added: -1} + added=${added%$sep} + added=$(dedup $added $sep) + if [ $sep = : ] + then + echo -e "prepend-path\t$key\t${added}" + else + echo -e "prepend-path\t--delim $sep\t$key\t${added}" + fi #Test for prepend plus : added at end (MANPATH) - elif [ "${env2[$key]%${env1[$key]}:}" != "${env2[$key]}" ] + elif [ "${key: -4}" = PATH -a "${env2[$key]%${env1[$key]}:}" != "${env2[$key]}" ] then added=$(dedup ${env2[$key]%${env1[$key]}:}) echo -e "prepend-path\t$key\t${added}" #Test for append elif [ "${env2[$key]#${env1[$key]}}" != "${env2[$key]}" ] then - added=$(dedup ${env2[$key]#:${env1[$key]}}) - echo -e "append-path\t$key\t${added}" + added=${env2[$key]#${env1[$key]}} + sep=${added:0:1} + added=${added#$sep} + added=$(dedup $added $sep) + if [ $sep = : ] + then + echo -e "append-path\t$key\t${added}" + else + echo -e "append-path\t--delim $sep\t$key\t${added}" + fi #Test for prepend plus append - elif [ "${env2[$key]%${env1[$key]}:*}" != "${env2[$key]}" ] + elif [ "${env2[$key]%${env1[$key]}*}" != "${env2[$key]}" ] then - added=$(dedup ${env2[$key]%:${env1[$key]}*}) - echo -e "prepend-path\t$key\t${added}" - added=$(dedup ${env2[$key]#*${env1[$key]}:}) - echo -e "append-path\t$key\t${added}" + prepended=${env2[$key]%${env1[$key]}*} + presep=${prepended: -1} + prepended=${prepended%$presep} + prepended=$(dedup $prepended $presep) + appended=${env2[$key]#*${env1[$key]}} + appsep=${appended:0:1} + appended=${appended#$appsep} + appended=$(dedup $appended $appsep) + if [ $presep != $appsep -o -z "$prepended" -o -z "$appended" ] + then + #Unhandled + echo "Unhandled change of $key" 1>&2 + echo "Before <${env1[$key]}>" 1>&2 + echo "After <${env2[$key]}>" 1>&2 + else + if [ $presep = : ] + then + echo -e "prepend-path\t$key\t${prepended}" + echo -e "append-path\t$key\t${appended}" + else + echo -e "prepend-path\t--delim $presep\t$key\t${prepended}" + echo -e "append-path\t--delim $appsep\t$key\t${appended}" + fi + fi else #Unhandled echo "Unhandled change of $key" 1>&2 @@ -140,7 +178,7 @@ do echo "After <${env2[$key]}>" 1>&2 fi fi - #Delete keys we've handled + #Delete keys we have handled unset env1[$key] unset env2[$key] done diff --git a/environment-modules.spec b/environment-modules.spec index 15057c5..2724545 100644 --- a/environment-modules.spec +++ b/environment-modules.spec @@ -142,6 +142,7 @@ fi %changelog * Mon Mar 2 2015 Orion Poplwski - 3.2.10-14 - Fix createmodule.sh to handle exported functions (bug #1197321) +- Handle more prefix/suffix cases in createmodule.{sh,py} (bug #1079341) * Wed Jan 28 2015 Orion Poplwski - 3.2.10-13 - Add patch for python 3 support, use python3 for createmodule.py on F22 diff --git a/testscript.sh b/testscript.sh new file mode 100644 index 0000000..3accc01 --- /dev/null +++ b/testscript.sh @@ -0,0 +1,8 @@ +#!bin/bash +export TESTVAR2=origvalue/suffix +export TESTVAR3=prefix/origvalue +export TESTVAR4=prefix:origvalue:suffix +export TESTVAR5=prefix/origvalue/suffix +### The following is not so crucial, but still: +export TESTVAR8=prefix/origvalue: +export TESTVAR9=prefix:origvalue: