1 __author__ =
"Marco Clemencic <marco.clemencic@cern.ch>"
5 assert sys.version_info >= (2, 6),
"Python 2.6 required"
13 if 'ENVXMLPATH' in os.environ:
14 path.extend(os.environ[
'ENVXMLPATH'].split(os.pathsep))
20 Simple class to wrap errors in the environment configuration.
25 """split the "NAME=VALUE" string into the tuple ("NAME", "VALUE")
26 replacing '[:]' with os.pathsep in VALUE"""
27 if '=' not in name_value:
28 raise EnvError(
"Invalid variable argument '%s'." % name_value)
29 n, v = name_value.split(
'=', 1)
30 return n, v.replace(
'[:]', os.pathsep)
34 Environment Script class used to control the logic of the script and allow
37 __usage__ =
"Usage: %prog [OPTION]... [NAME=VALUE]... [COMMAND [ARG]...]"
38 __desc__ =
"Set each NAME to VALUE in the environment and run COMMAND."
39 __epilog__ = (
"The operations are performed in the order they appear on the "
40 "command line. If no COMMAND is provided, print the resulting "
41 "environment. (Note: this command is modeled after the Unix "
42 "command 'env', see \"man env\")")
45 Initializes the script instance parsing the command line arguments (or
46 the explicit arguments provided).
61 Prepare an OptionParser instance used to analyze the command line
62 options and arguments.
64 from optparse
import OptionParser, OptionValueError
65 parser = OptionParser(prog=os.path.basename(sys.argv[0]),
69 self.
log = logging.getLogger(parser.prog)
71 def addOperation(option, opt, value, parser, action):
73 Append to the list of actions the tuple (action, (<args>, ...)).
75 if action
not in (
'unset',
'loadXML'):
79 raise OptionValueError(
"Invalid value for option %s: '%s', it requires NAME=VALUE." % (opt, value))
82 parser.values.actions.append((action, value))
84 parser.add_option(
"-i",
"--ignore-environment",
86 help=
"start with an empty environment")
87 parser.add_option(
"-u",
"--unset",
89 action=
"callback", callback=addOperation,
90 type=
"str", nargs=1, callback_args=(
'unset',),
91 help=
"remove variable from the environment")
92 parser.add_option(
"-s",
"--set",
94 action=
"callback", callback=addOperation,
95 type=
"str", nargs=1, callback_args=(
'set',),
96 help=
"set the variable NAME to VALUE")
97 parser.add_option(
"-a",
"--append",
99 action=
"callback", callback=addOperation,
100 type=
"str", nargs=1, callback_args=(
'append',),
101 help=
"append VALUE to the variable NAME (with a '%s' as separator)" % os.pathsep)
102 parser.add_option(
"-p",
"--prepend",
103 metavar=
"NAME=VALUE",
104 action=
"callback", callback=addOperation,
105 type=
"str", nargs=1, callback_args=(
'prepend',),
106 help=
"prepend VALUE to the variable NAME (with a '%s' as separator)" % os.pathsep)
107 parser.add_option(
"-x",
"--xml",
108 action=
"callback", callback=addOperation,
109 type=
"str", nargs=1, callback_args=(
'loadXML',),
110 help=
"XML file describing the changes to the environment")
111 parser.add_option(
"--sh",
112 action=
"store_const", const=
"sh", dest=
"shell",
113 help=
"Print the environment as shell commands for 'sh'-derived shells.")
114 parser.add_option(
"--csh",
115 action=
"store_const", const=
"csh", dest=
"shell",
116 help=
"Print the environment as shell commands for 'csh'-derived shells.")
117 parser.add_option(
"--py",
118 action=
"store_const", const=
"py", dest=
"shell",
119 help=
"Print the environment as Python dictionary.")
121 parser.add_option(
'--verbose', action=
'store_const',
122 const=logging.INFO, dest=
'log_level',
123 help=
'print more information')
124 parser.add_option(
'--debug', action=
'store_const',
125 const=logging.DEBUG, dest=
'log_level',
126 help=
'print debug messages')
127 parser.add_option(
'--quiet', action=
'store_const',
128 const=logging.WARNING, dest=
'log_level',
129 help=
'print only warning messages (default)')
131 parser.disable_interspersed_args()
132 parser.set_defaults(actions=[],
133 ignore_environment=
False,
134 log_level=logging.WARNING)
140 Parse the command line arguments.
142 opts, args = self.parser.parse_args(args)
145 logging.basicConfig(level=opts.log_level)
151 for i, a
in enumerate(args):
156 self.
opts, self.
cmd = opts, cmd
160 Check consistency of command line options and arguments.
162 if self.opts.shell
and self.
cmd:
163 self.parser.error(
"Invalid arguments: --%s cannot be used with a command." % self.opts.shell)
167 Generate a dictionary of the environment variables after applying all
168 the required actions.
172 if not self.opts.ignore_environment:
173 control.presetFromSystem()
176 for action, args
in self.opts.actions:
177 apply(getattr(control, action), args)
183 if "LD_LIBRARY_PATH" in env:
185 if sys.platform.startswith(
"win"):
187 elif sys.platform.startswith(
"darwin"):
188 other =
"DYLD_LIBRARY_PATH"
193 env[other] = env[other] + os.pathsep + env[
"LD_LIBRARY_PATH"]
195 env[other] = env[
"LD_LIBRARY_PATH"]
196 del env[
"LD_LIBRARY_PATH"]
202 Print to standard output the final environment in the required format.
204 if self.opts.shell ==
'py':
205 from pprint
import pprint
208 template = {
'sh':
"export %s='%s'",
209 'csh':
"setenv %s '%s'"}.
get(self.opts.shell,
"%s=%s")
210 for nv
in sorted(self.env.items()):
215 Execute a command in the modified environment and return the exit code.
217 from subprocess
import Popen
218 return Popen(self.
cmd, env=self.
env).wait()
222 Main function of the script.