FEATURE: Configuration scripts for other shells generated from bashrc; added support for zsh, fish, tcsh. Author: Bernhard Gschaider. Merge: Dominik Christ.

This commit is contained in:
Dominik Christ 2015-05-12 16:28:53 +01:00
commit 5d910b7aaf
4 changed files with 496 additions and 0 deletions

41
etc/fishrc Executable file
View file

@ -0,0 +1,41 @@
#! /usr/bin/env zsh
#----------------------------------*-sh-*--------------------------------------
# ========= |
# \\ / F ield | foam-extend: Open Source CFD
# \\ / O peration |
# \\ / A nd | For copyright notice see file Copyright
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of foam-extend.
#
# foam-extend 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 3 of the License, or (at your
# option) any later version.
#
# foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# etc/fishrc
#
# Description
# Startup file for OpenFOAM
# Sourced from ~/..config/fish/config.fish
# To be used from the fish-shell
# Not really functional as no variables can be specified (somehow this breaks $argv)
#
#------------------------------------------------------------------------------
set thisScript $argv[1]
set thisDir (python -c "from os.path import *;import sys;sys.stdout.write(dirname(abspath(join(curdir,'$thisScript'))))")
python $thisDir/getVariables.py fish | source -
# -----------------------------------------------------------------------------

343
etc/getVariables.py Executable file
View file

@ -0,0 +1,343 @@
#! /usr/bin/env python
# This file sources the etc bashrc, finds the differences to the old
# configuration and makes them available in a format that the calling
# shell can understand
#
import sys
# This part is lifted from six.py (https://pythonhosted.org/six/) to
# make sure that this script runs with Python 2 and Python 3
# True if we are running on Python 3.
PY3 = sys.version_info[0] == 3
if PY3:
import builtins
print_ = getattr(builtins, "print")
del builtins
else:
def print_(*args, **kwargs):
"""The new-style print function."""
fp = kwargs.pop("file", sys.stdout)
if fp is None:
return
def write(data):
if not isinstance(data, basestring):
data = str(data)
fp.write(data)
want_unicode = False
sep = kwargs.pop("sep", None)
if sep is not None:
if isinstance(sep, unicode):
want_unicode = True
elif not isinstance(sep, str):
raise TypeError("sep must be None or a string")
end = kwargs.pop("end", None)
if end is not None:
if isinstance(end, unicode):
want_unicode = True
elif not isinstance(end, str):
raise TypeError("end must be None or a string")
if kwargs:
raise TypeError("invalid keyword arguments to print()")
if not want_unicode:
for arg in args:
if isinstance(arg, unicode):
want_unicode = True
break
if want_unicode:
newline = unicode("\n")
space = unicode(" ")
else:
newline = "\n"
space = " "
if sep is None:
sep = space
if end is None:
end = newline
for i, arg in enumerate(args):
if i:
write(sep)
write(arg)
write(end)
def printDebug(*args):
print_(*args,file=sys.stderr)
# the actual work starts here
from os import environ,path
if sys.version_info<(2,6):
from popen2 import popen4
else:
from subprocess import Popen,PIPE,STDOUT
# only for development
verbose="FOAM_NEW_STARTUP_DEBUG" in environ
# Location of this script
here=path.dirname(path.abspath(sys.argv[0]))
if verbose:
printDebug("Using scripts in",here)
# For which shell
destShell=sys.argv[1]
# Variables like WM_COMPILER=Gcc46
additional=sys.argv[2:]
if verbose:
printDebug("Target shell",destShell)
printDebug("Additional settings:",additional)
# Certain bashrc-s fail if these are set
for v in ["FOAM_INST_DIR",
"WM_THIRD_PARTY_DIR",
"WM_PROJECT_USER_DIR",
"OPAL_PREFIX"]:
try:
del environ[v]
except KeyError:
pass
# To be executed in bash
cmd ='echo "=== Export pre";export;echo "=== Alias pre";alias;'
cmd+='echo "=== Script";. '+path.join(here,"bashrc")+' '+' '.join(additional)+';'
cmd+='echo "=== Export post";export;echo "=== Alias post";alias;'
cmd+='echo "=== End"'
cmd="bash -c '"+cmd+"'"
if verbose:
printDebug("Cmd:",cmd)
# Execute the shell commands
if sys.version_info<(2,6):
# for old machines (RHEL 5)
raus,rein = popen4(cmd)
ret=0 # standin for a proper implementation
else:
p = Popen(cmd, shell=True,
stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(rein,raus)=(p.stdin,p.stdout)
ret=p.wait()
lines=[l.strip().decode() for l in raus.readlines()]
rein.close()
raus.close()
if verbose or ret!=0:
printDebug("========= Script output start")
for l in lines:
printDebug(l)
printDebug("========= Script output end")
if ret!=0:
printDebug("Command return code",ret,". There seems to be a problem")
def extractVariables(lines):
vars={}
# different forms if bash is called as sh
prefixes=["export ","declare -x "]
for l in lines:
pref=None
for p in prefixes:
if l.find(p)==0:
pref=p
break
pos=l.find("=")
name=l[len(pref):pos]
if pos>0:
val=l[pos+1:]
if val[0]=='"' and val[-1]=='"':
val=val[1:-1]
else:
val=""
vars[name]=val
return vars
def extractAliases(lines):
aliases={}
for l in lines:
pref="" # if called as sh
if l.find("alias ")==0:
pref="alias "
pos=l.find("=")
aliases[l[len(pref):pos]]=l[pos+2:-1]
return aliases
def changedVars(old,new):
changed={}
for k in new:
if k not in old:
changed[k]=new[k]
elif old[k]!=new[k]:
changed[k]=new[k]
return changed
def splitPaths(orig):
new={}
for k in orig.keys():
if k.find("PATH")>=0 and orig[k].find(":")>=0:
new[k]=orig[k].split(":")
else:
new[k]=orig[k]
return new
try:
vars=splitPaths(
changedVars(extractVariables(lines[lines.index("=== Export pre")+1:
lines.index("=== Alias pre")]),
extractVariables(lines[lines.index("=== Export post")+1:
lines.index("=== Alias post")])))
aliases=changedVars(extractAliases(lines[lines.index("=== Alias post")+1:
lines.index("=== Script")]),
extractAliases(lines[lines.index("=== Alias post")+1:
lines.index("=== End")]))
scriptOutput=lines[lines.index("=== Script")+1:
lines.index("=== Export post")]
except Exception:
e = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e'
err, detail, tb = sys.exc_info()
printDebug("Output of",cmd,"not successfully parsed")
import traceback
traceback.print_exception(err,detail,tb,file=sys.stderr)
sys.exit(-1)
# Pass output of the script to stderr for debugging
if len(scriptOutput)>0:
for l in scriptOutput:
print_(l,file=sys.stderr)
class ShellConvert(object):
def __call__(self,vars,aliases):
result=""
for v in sorted(vars.keys()):
result+=self.toVar(v,vars[v])+"\n"
for a in sorted(aliases.keys()):
result+=self.toAlias(a,aliases[a])+"\n"
return result
class BashConvert(ShellConvert):
def toVar(self,n,v):
if type(v)==list:
val=":".join(v)
else:
val=v
if val.find(" "):
return 'export %s="%s"' % (n,val)
else:
return 'export %s=%s' % (n,val)
def toAlias(self,n,v):
return "alias %s='%s'" % (n,v)
class CshConvert(ShellConvert):
def __init__(self,sName="csh"):
self.shellName=sName
def toVar(self,n,v):
if type(v)==list:
val=":".join(v)
else:
val=v
result='setenv %s "%s"' % (n,val)
if n=="PATH":
result+="\nset path=(%s)" % " ".join(v)
return result
def toAlias(self,n,v):
val=v.replace(" . ","source ").replace("bash",self.shellName)
if val.find("unset ")>=0:
val=val.replace("unset ","unsetenv ")
# Make sure that more than one export is possible and no wrong = is replaced
while val.find("export ")>=0:
pos=val.find("export ")
val=val.replace("export ","setenv ",1)
val=val[:pos]+val[pos:].replace("="," ",1)
# Prefix with a variable that tells the script that it is sourced from an alias
if val.find("source")>=0:
val=("setenv FOAM_SOURCED_FROM_ALIAS %s/tcshrc ; " % here)+val
return "alias %s '%s'" % (n,val)
class TcshConvert(CshConvert):
def __init__(self):
CshConvert.__init__(self,"tcsh")
class FishConvert(ShellConvert):
def toVar(self,n,v):
if type(v)==list:
val=":".join(v)
else:
val=v
if n=="PATH":
result="\nset -x PATH %s" % " ".join(v)
else:
result='set -x %s "%s"' % (n,val)
return result
def toAlias(self,n,v):
val=v.replace(" . ","source ").replace("bash","fish")
if val.find("unset ")>=0:
val=val.replace("unset ","set -e ")
# Make sure that more than one export is possible and no wrong = is replaced
while val.find("export ")>=0:
pos=val.find("export ")
val=val.replace("export ","set -x ",1)
val=val[:pos]+val[pos:].replace("="," ",1)
return "alias %s '%s'" % (n,val)
class ZshConvert(BashConvert):
def toAlias(self,n,v):
return BashConvert.toAlias(self,n,v).replace("bash","zsh")
shells={"bash" : BashConvert,
"zsh" : ZshConvert,
"fish" : FishConvert,
"csh" : CshConvert,
"tcsh" : TcshConvert}
try:
converter=shells[destShell]()
except KeyError:
printDebug("No converter for shell",destShell,
"Available:"," ".join(shells.keys()))
sys.exit(-1)
try:
result=converter(vars,aliases)
except Exception:
e = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e'
err, detail, tb = sys.exc_info()
printDebug("Problem while converting output for",destShell)
import traceback
traceback.print_exception(err,detail,tb,file=sys.stderr)
sys.exit(-1)
if PY3:
osException=OSError
else:
osException=IOError
try:
open(path.abspath(sys.argv[0])+"."+destShell,"w").write(result)
except osException:
# We are not allowed to write here. Try tmp
try:
open(path.join("/tmp",
path.basename(sys.argv[0])+"."+destShell),"w").write(result)
except osException:
# Nobody wants this
pass
# This is the only part that goes to stdout to be sourced by the calling script
print_(result)

69
etc/tcshrc Executable file
View file

@ -0,0 +1,69 @@
#! /usr/bin/env tcsh
#---------------------------------*-tcsh-*-------------------------------------
# ========= |
# \\ / F ield | foam-extend: Open Source CFD
# \\ / O peration |
# \\ / A nd | For copyright notice see file Copyright
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of foam-extend.
#
# foam-extend 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 3 of the License, or (at your
# option) any later version.
#
# foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# etc/zshrc
#
# Description
# Startup file for OpenFOAM
# Sourced from ~/.login or ~/.cshrc
#
#------------------------------------------------------------------------------
if ( $?FOAM_SOURCED_FROM_ALIAS ) then
# Sourced from an alias or .tcshrc
set sourced=($_)
set thisScript=$FOAM_SOURCED_FROM_ALIAS
if ( $?sourced ) then
# sourced from .tcshrc
set sourced=($FOAM_SOURCED_FROM_ALIAS)
endif
shift sourced
# Clear the variable to make sure regular sourcing still works
unsetenv FOAM_SOURCED_FROM_ALIAS
else
# regular sourcing
set sourced=($_)
if ( $#sourced == 0 ) then
echo "Seems you sourced this script (etc/tcshrc from your foam-extend-installation) from .tcshrc."
echo "In that case tcsh has no way of telling where this script is located and is not able to set up the environment correctly"
echo "So before sourcing it set the location with 'setenv FOAM_SOURCED_FROM_ALIAS <path to the script>'"
echo "Or consider using a different shell"
endif
set thisScript=($sourced[2])
shift sourced
shift sourced
endif
set thisDir=`python -c "from os.path import *;import sys;sys.stdout.write(dirname(abspath(join(curdir,'$thisScript'))))"`
$thisDir/getVariables.py tcsh $sourced | source /dev/stdin
unset thisScript thisDir sourced
# -----------------------------------------------------------------------------

43
etc/zshrc Executable file
View file

@ -0,0 +1,43 @@
#! /usr/bin/env zsh
#----------------------------------*-sh-*--------------------------------------
# ========= |
# \\ / F ield | foam-extend: Open Source CFD
# \\ / O peration |
# \\ / A nd | For copyright notice see file Copyright
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of foam-extend.
#
# foam-extend 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 3 of the License, or (at your
# option) any later version.
#
# foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# etc/zshrc
#
# Description
# Startup file for OpenFOAM
# Sourced from ~/.zprofile or ~/.zshrc
# Should be usable by any POSIX-compliant shell but actually used as a
# proof-of-concept for the new shell-scripts
#
#------------------------------------------------------------------------------
thisScript=$0
thisDir=`python -c "from os.path import *;import sys;sys.stdout.write(dirname(abspath(join(curdir,'$thisScript'))))"`
source <($thisDir/getVariables.py zsh $*)
unset thisScript
unset thisDir
# -----------------------------------------------------------------------------