Updated createmodule.sh and added createmodule.py
This commit is contained in:
parent
2ccfc854ef
commit
9c1d7d9012
186
createmodule.py
Executable file
186
createmodule.py
Executable file
@ -0,0 +1,186 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# createmodule.py - Takes the name of a environment init script and
|
||||
# produces a modulefile that duplicates the changes made by the init script
|
||||
#
|
||||
# Copyright (C) 2012 by Orion E. Poplawski <orion@cora.nwra.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from optparse import OptionParser
|
||||
import os,sys
|
||||
from subprocess import *
|
||||
|
||||
# Handle options
|
||||
usage = "Usage: %prog [-p prefix] <initscript> [args]"
|
||||
parser = OptionParser()
|
||||
parser.set_usage(usage)
|
||||
parser.add_option('-p', '--prefix', dest='prefix', help='Specify path prefix')
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# Need a script name
|
||||
if not args:
|
||||
parser.print_usage()
|
||||
exit(1)
|
||||
|
||||
# Return environment after a command
|
||||
def getenv(cmd = ':'):
|
||||
env = {}
|
||||
p = Popen(cmd + ";env", shell=True, stdout=PIPE, stderr=PIPE)
|
||||
(stdout, stderr) = p.communicate()
|
||||
if p.returncode != 0:
|
||||
print "EROR: Could not execute initscript:"
|
||||
print "%s returned exit code %d" % (cmd, p.returncode)
|
||||
print stderr
|
||||
exit(1)
|
||||
if stderr != '':
|
||||
print "WARNING: initscript sent the following to stderr:"
|
||||
print stderr
|
||||
# Parse the output key=value pairs
|
||||
for line in stdout.splitlines():
|
||||
try:
|
||||
(var,value) = line.split('=',1)
|
||||
except ValueError:
|
||||
print "ERROR: Could not parse output:"
|
||||
print stdout
|
||||
exit(1)
|
||||
env[var] = value
|
||||
return env
|
||||
|
||||
#Record initial environment
|
||||
env1=getenv()
|
||||
|
||||
#Record environment after sourcing the initscript
|
||||
env2=getenv(". " + " ".join(args))
|
||||
|
||||
# Initialize our variables for storing modifications
|
||||
chdir = None
|
||||
appendpath = {}
|
||||
prependpath = {}
|
||||
setenv = {}
|
||||
unsetenv = []
|
||||
pathnames = []
|
||||
|
||||
# Function to nomalize all paths in a list of paths and remove duplicate items
|
||||
def normpaths(paths):
|
||||
newpaths = []
|
||||
for path in paths:
|
||||
normpath = os.path.normpath(path)
|
||||
if normpath not in newpaths:
|
||||
newpaths.append(os.path.normpath(path))
|
||||
return newpaths
|
||||
|
||||
# Start with existing keys and look for changes
|
||||
for key in env1.keys():
|
||||
# Test for delete
|
||||
if key not in env2:
|
||||
unsetenv.append(key)
|
||||
continue
|
||||
# No change
|
||||
if env1[key] == env2[key]:
|
||||
del env2[key]
|
||||
continue
|
||||
#Working directory change
|
||||
if key == 'PWD':
|
||||
chdir=os.path.normpath(env2[key])
|
||||
pathnames.append(chdir)
|
||||
del env2[key]
|
||||
continue
|
||||
# Determine modifcations to beginning and end of the string
|
||||
(prepend,append) = env2[key].split(env1[key])
|
||||
if prepend:
|
||||
prependpaths = prepend.strip(':').split(':')
|
||||
# LICENSE variables often include paths outside install directory
|
||||
if 'LICENSE' not in key:
|
||||
pathnames += prependpaths
|
||||
prependpath[key] = ':'.join(normpaths(prependpaths))
|
||||
if append:
|
||||
appendpaths = append.strip(':').split(':')
|
||||
# LICENSE variables often include paths outside install directory
|
||||
if 'LICENSE' not in key:
|
||||
pathnames += appendpaths
|
||||
appendpath[key] = ':'.join(normpaths(appendpaths))
|
||||
del env2[key]
|
||||
|
||||
# We're left with new keys in env2
|
||||
for key in env2.keys():
|
||||
# Use prepend-path for new paths
|
||||
if ('PATH' in key) or (':' in env2[key]):
|
||||
prependpaths = env2[key].strip(':').split(':')
|
||||
# MANPATH can have system defaults added it it wasn't previously set
|
||||
# LICENSE variables often include paths outside install directory
|
||||
if key != 'MANPATH' and 'LICENSE' not in key:
|
||||
pathnames += prependpaths
|
||||
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])
|
||||
|
||||
# Determine a prefix
|
||||
prefix = None
|
||||
if options.prefix:
|
||||
prefix = options.prefix
|
||||
else:
|
||||
prefix = os.path.commonprefix(pathnames).rstrip('/')
|
||||
if prefix == '':
|
||||
prefix = None
|
||||
|
||||
# Print out the modulefile
|
||||
print "#%Module 1.0"
|
||||
|
||||
# Prefix
|
||||
if prefix is not None:
|
||||
print "\nset prefix " + prefix + "\n"
|
||||
|
||||
# Chdir
|
||||
if chdir is not None:
|
||||
print "chdir\t" + chdir
|
||||
|
||||
# Function to format output line with tabs and substituting prefix
|
||||
def formatline(item, key, value=None):
|
||||
print item,
|
||||
print "\t"*(2-(len(item)+1)/8),
|
||||
print key,
|
||||
if value is not None:
|
||||
print "\t"*(3-(len(key)+1)/8),
|
||||
if prefix is not None:
|
||||
print value.replace(prefix,'$prefix')
|
||||
else:
|
||||
print value
|
||||
|
||||
# Paths first, grouped by variable name
|
||||
pathkeys = appendpath.keys() + 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])
|
||||
|
||||
# Setenv
|
||||
setenvkeys = setenv.keys()
|
||||
setenvkeys.sort()
|
||||
if setenvkeys:
|
||||
print
|
||||
for key in setenvkeys:
|
||||
formatline("setenv",key,setenv[key])
|
||||
|
||||
# Unsetenv
|
||||
unsetenv.sort()
|
||||
if unsetenv:
|
||||
print
|
||||
for key in unsetenv:
|
||||
formatline("unsetenv",key)
|
149
createmodule.sh
149
createmodule.sh
@ -3,7 +3,7 @@
|
||||
# createmodule.sh - Takes the name of a environment init script and
|
||||
# produces a modulefile that duplicates the changes made by the init script
|
||||
#
|
||||
# Copyright (C) 2010 by Orion E. Poplawski
|
||||
# Copyright (C) 2010-2012 by Orion E. Poplawski <orion@cora.nwra.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -18,10 +18,29 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "usage: $0 <initscript> [args]" 1>&2
|
||||
usage="Usage: $0 [-p prefix] <initscript> [args]"
|
||||
|
||||
usage() {
|
||||
echo $usage 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
while getopts "p:" opt
|
||||
do
|
||||
case $opt in
|
||||
p) prefix=$OPTARG; shift 2;;
|
||||
*) usage;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Need a script name
|
||||
[ -z "$1" ] && usage
|
||||
|
||||
# Need to be a readable script
|
||||
if [ ! -r "$1" ]
|
||||
then
|
||||
echo "ERROR: Cannot read $1" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#Will print out array assignment list
|
||||
@ -49,53 +68,99 @@ eval env2=(`printenvarray`)
|
||||
#Print out the modulefile
|
||||
echo "#%Module 1.0"
|
||||
|
||||
#Prefix
|
||||
[ -n "$prefix" ] && echo -e "\nset prefix $prefix\n"
|
||||
|
||||
#Subshell so we can sort the output
|
||||
(
|
||||
dedup() {
|
||||
list=`mktemp`
|
||||
echo $1 | sed -r -e 's,[^/]+/\.\./,,g' -e 's,[^/]+/\.\./,,g' -e 's/:/\n/g' |
|
||||
while read x
|
||||
do
|
||||
grep -Fx ${x} $list && continue
|
||||
if [ -n "$prefix" ]
|
||||
then
|
||||
echo $x | sed -e s,$prefix,\$prefix,
|
||||
else
|
||||
echo $x
|
||||
fi
|
||||
echo $x >> $list
|
||||
done | tr '\n' : | sed -e 's/:$//'
|
||||
rm $list
|
||||
}
|
||||
|
||||
#Keys that changed
|
||||
for key in "${!env1[@]}"
|
||||
do
|
||||
if [ "${env1[$key]}" != "${env2[$key]}" ]
|
||||
then
|
||||
#Working directory change
|
||||
if [ "$key" = PWD ]
|
||||
if [ "${env1[$key]}" != "${env2[$key]}" ]
|
||||
then
|
||||
#Working directory change
|
||||
if [ "$key" = PWD ]
|
||||
then
|
||||
if [ -n "$prefix" ]
|
||||
then
|
||||
echo -e "chdir\t\t${env2[PWD]}"
|
||||
#Test for delete
|
||||
elif [ -z "${env2[$key]}" ]
|
||||
then
|
||||
echo -e "unsetenv\t${key}\t${env2[$key]}"
|
||||
#Test for prepend
|
||||
elif [ "${env2[$key]%${env1[$key]}}" != "${env2[$key]}" ]
|
||||
then
|
||||
added="${env2[$key]%${env1[$key]}}"
|
||||
echo -e "prepend-path\t$key\t${added%:}"
|
||||
#Test for append
|
||||
elif [ "${env2[$key]#${env1[$key]}}" != "${env2[$key]}" ]
|
||||
then
|
||||
added="${env2[$key]#${env1[$key]}}"
|
||||
echo -e "append-path\t$key\t${added#:}"
|
||||
echo -e "chdir\t\t${env2[PWD]}" | sed -e s,$prefix,\$prefix,g
|
||||
else
|
||||
#Unhandled
|
||||
echo "Unhandled change of $key" 1>&2
|
||||
echo "Before <${env1[$key]}>" 1>&2
|
||||
echo "After <${env2[$key]}>" 1>&2
|
||||
echo -e "chdir\t\t${env2[PWD]}"
|
||||
fi
|
||||
fi
|
||||
#Delete keys we've handled
|
||||
unset env1[$key]
|
||||
unset env2[$key]
|
||||
#Test for delete
|
||||
elif [ -z "${env2[$key]}" ]
|
||||
then
|
||||
echo -e "unsetenv\t${key}\t${env2[$key]}"
|
||||
#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}"
|
||||
#Test for prepend plus : added at end (MANPATH)
|
||||
elif [ "${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}"
|
||||
#Test for prepend plus append
|
||||
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}"
|
||||
else
|
||||
#Unhandled
|
||||
echo "Unhandled change of $key" 1>&2
|
||||
echo "Before <${env1[$key]}>" 1>&2
|
||||
echo "After <${env2[$key]}>" 1>&2
|
||||
fi
|
||||
fi
|
||||
#Delete keys we've handled
|
||||
unset env1[$key]
|
||||
unset env2[$key]
|
||||
done
|
||||
|
||||
#New keys
|
||||
for key in "${!env2[@]}"
|
||||
do
|
||||
if [ "$key" = OLDPWD ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
#Use prepend-path for new paths
|
||||
if [ "${key/PATH/}" != "$key" ]
|
||||
then
|
||||
echo -e "prepend-path\t${key}\t${env2[$key]}"
|
||||
else
|
||||
echo -e "setenv\t\t${key}\t${env2[$key]}"
|
||||
fi
|
||||
if [ "$key" = OLDPWD ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
#Use prepend-path for new paths
|
||||
if [ "${key/PATH/}" != "$key" ]
|
||||
then
|
||||
# TODO - Need to handle stripping of default MANPATH
|
||||
echo -e "prepend-path\t${key}\t"$(dedup ${env2[$key]})
|
||||
else
|
||||
if [ -n "$prefix" ]
|
||||
then
|
||||
echo -e "setenv\t\t${key}\t${env2[$key]}" | sed -e s,$prefix,\$prefix,g
|
||||
else
|
||||
echo -e "setenv\t\t${key}\t${env2[$key]}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
) | sort
|
||||
|
Loading…
Reference in New Issue
Block a user