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)
|
@ -3,7 +3,7 @@
|
|||||||
# createmodule.sh - Takes the name of a environment init script and
|
# createmodule.sh - Takes the name of a environment init script and
|
||||||
# produces a modulefile that duplicates the changes made by the init script
|
# 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
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -18,9 +18,28 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
if [ -z "$1" ]
|
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
|
then
|
||||||
echo "usage: $0 <initscript> [args]" 1>&2
|
echo "ERROR: Cannot read $1" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -49,6 +68,28 @@ eval env2=(`printenvarray`)
|
|||||||
#Print out the modulefile
|
#Print out the modulefile
|
||||||
echo "#%Module 1.0"
|
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
|
#Keys that changed
|
||||||
for key in "${!env1[@]}"
|
for key in "${!env1[@]}"
|
||||||
do
|
do
|
||||||
@ -57,7 +98,12 @@ do
|
|||||||
#Working directory change
|
#Working directory change
|
||||||
if [ "$key" = PWD ]
|
if [ "$key" = PWD ]
|
||||||
then
|
then
|
||||||
|
if [ -n "$prefix" ]
|
||||||
|
then
|
||||||
|
echo -e "chdir\t\t${env2[PWD]}" | sed -e s,$prefix,\$prefix,g
|
||||||
|
else
|
||||||
echo -e "chdir\t\t${env2[PWD]}"
|
echo -e "chdir\t\t${env2[PWD]}"
|
||||||
|
fi
|
||||||
#Test for delete
|
#Test for delete
|
||||||
elif [ -z "${env2[$key]}" ]
|
elif [ -z "${env2[$key]}" ]
|
||||||
then
|
then
|
||||||
@ -65,13 +111,25 @@ do
|
|||||||
#Test for prepend
|
#Test for prepend
|
||||||
elif [ "${env2[$key]%${env1[$key]}}" != "${env2[$key]}" ]
|
elif [ "${env2[$key]%${env1[$key]}}" != "${env2[$key]}" ]
|
||||||
then
|
then
|
||||||
added="${env2[$key]%${env1[$key]}}"
|
added=$(dedup ${env2[$key]%:${env1[$key]}})
|
||||||
echo -e "prepend-path\t$key\t${added%:}"
|
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
|
#Test for append
|
||||||
elif [ "${env2[$key]#${env1[$key]}}" != "${env2[$key]}" ]
|
elif [ "${env2[$key]#${env1[$key]}}" != "${env2[$key]}" ]
|
||||||
then
|
then
|
||||||
added="${env2[$key]#${env1[$key]}}"
|
added=$(dedup ${env2[$key]#:${env1[$key]}})
|
||||||
echo -e "append-path\t$key\t${added#:}"
|
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
|
else
|
||||||
#Unhandled
|
#Unhandled
|
||||||
echo "Unhandled change of $key" 1>&2
|
echo "Unhandled change of $key" 1>&2
|
||||||
@ -94,8 +152,15 @@ do
|
|||||||
#Use prepend-path for new paths
|
#Use prepend-path for new paths
|
||||||
if [ "${key/PATH/}" != "$key" ]
|
if [ "${key/PATH/}" != "$key" ]
|
||||||
then
|
then
|
||||||
echo -e "prepend-path\t${key}\t${env2[$key]}"
|
# 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
|
else
|
||||||
echo -e "setenv\t\t${key}\t${env2[$key]}"
|
echo -e "setenv\t\t${key}\t${env2[$key]}"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
) | sort
|
||||||
|
Loading…
Reference in New Issue
Block a user