1 __author__ =
"Marco Clemencic <marco.clemencic@cern.ch>"
6 assert sys.version_info >= (2, 6),
"Python 2.6 required"
10 from string
import Template
16 if 'ENVXMLPATH' in os.environ:
17 path.extend(os.environ[
'ENVXMLPATH'].split(os.pathsep))
23 Simple class to wrap errors in the environment configuration.
28 """split the "NAME=VALUE" string into the tuple ("NAME", "VALUE")
29 replacing '[:]' with os.pathsep in VALUE"""
30 if '=' not in name_value:
31 raise EnvError(
"Invalid variable argument '%s'." % name_value)
32 n, v = name_value.split(
'=', 1)
33 return n, v.replace(
'[:]', os.pathsep)
37 Environment Script class used to control the logic of the script and allow
40 __usage__ =
"Usage: %prog [OPTION]... [NAME=VALUE]... [COMMAND [ARG]...]"
41 __desc__ =
"Set each NAME to VALUE in the environment and run COMMAND."
42 __epilog__ = (
"The operations are performed in the order they appear on the "
43 "command line. If no COMMAND is provided, print the resulting "
44 "environment. (Note: this command is modeled after the Unix "
45 "command 'env', see \"man env\")")
48 Initializes the script instance parsing the command line arguments (or
49 the explicit arguments provided).
64 Prepare an OptionParser instance used to analyze the command line
65 options and arguments.
67 from optparse
import OptionParser, OptionValueError
68 parser = OptionParser(prog=os.path.basename(sys.argv[0]),
72 self.
log = logging.getLogger(parser.prog)
74 def addOperation(option, opt, value, parser, action):
76 Append to the list of actions the tuple (action, (<args>, ...)).
78 if action
not in (
'unset',
'loadXML'):
82 raise OptionValueError(
"Invalid value for option %s: '%s', it requires NAME=VALUE." % (opt, value))
85 parser.values.actions.append((action, value))
87 parser.add_option(
"-i",
"--ignore-environment",
89 help=
"start with an empty environment")
90 parser.add_option(
"-u",
"--unset",
92 action=
"callback", callback=addOperation,
93 type=
"str", nargs=1, callback_args=(
'unset',),
94 help=
"remove variable from the environment")
95 parser.add_option(
"-s",
"--set",
97 action=
"callback", callback=addOperation,
98 type=
"str", nargs=1, callback_args=(
'set',),
99 help=
"set the variable NAME to VALUE")
100 parser.add_option(
"-a",
"--append",
101 metavar=
"NAME=VALUE",
102 action=
"callback", callback=addOperation,
103 type=
"str", nargs=1, callback_args=(
'append',),
104 help=
"append VALUE to the variable NAME (with a '%s' as separator)" % os.pathsep)
105 parser.add_option(
"-p",
"--prepend",
106 metavar=
"NAME=VALUE",
107 action=
"callback", callback=addOperation,
108 type=
"str", nargs=1, callback_args=(
'prepend',),
109 help=
"prepend VALUE to the variable NAME (with a '%s' as separator)" % os.pathsep)
110 parser.add_option(
"-x",
"--xml",
111 action=
"callback", callback=addOperation,
112 type=
"str", nargs=1, callback_args=(
'loadXML',),
113 help=
"XML file describing the changes to the environment")
114 parser.add_option(
"--sh",
115 action=
"store_const", const=
"sh", dest=
"shell",
116 help=
"Print the environment as shell commands for 'sh'-derived shells.")
117 parser.add_option(
"--csh",
118 action=
"store_const", const=
"csh", dest=
"shell",
119 help=
"Print the environment as shell commands for 'csh'-derived shells.")
120 parser.add_option(
"--py",
121 action=
"store_const", const=
"py", dest=
"shell",
122 help=
"Print the environment as Python dictionary.")
124 parser.add_option(
'--verbose', action=
'store_const',
125 const=logging.INFO, dest=
'log_level',
126 help=
'print more information')
127 parser.add_option(
'--debug', action=
'store_const',
128 const=logging.DEBUG, dest=
'log_level',
129 help=
'print debug messages')
130 parser.add_option(
'--quiet', action=
'store_const',
131 const=logging.WARNING, dest=
'log_level',
132 help=
'print only warning messages (default)')
134 parser.disable_interspersed_args()
135 parser.set_defaults(actions=[],
136 ignore_environment=
False,
137 log_level=logging.WARNING)
143 Parse the command line arguments.
145 opts, args = self.parser.parse_args(args)
148 logging.basicConfig(level=opts.log_level)
154 for i, a
in enumerate(args):
159 self.
opts, self.
cmd = opts, cmd
163 Check consistency of command line options and arguments.
165 if self.opts.shell
and self.
cmd:
166 self.parser.error(
"Invalid arguments: --%s cannot be used with a command." % self.opts.shell)
170 Generate a dictionary of the environment variables after applying all
171 the required actions.
175 if not self.opts.ignore_environment:
176 control.presetFromSystem()
179 for action, args
in self.opts.actions:
180 apply(getattr(control, action), args)
186 if "LD_LIBRARY_PATH" in env:
188 if sys.platform.startswith(
"win"):
190 elif sys.platform.startswith(
"darwin"):
191 other =
"DYLD_LIBRARY_PATH"
196 env[other] = env[other] + os.pathsep + env[
"LD_LIBRARY_PATH"]
198 env[other] = env[
"LD_LIBRARY_PATH"]
199 del env[
"LD_LIBRARY_PATH"]
205 Print to standard output the final environment in the required format.
207 if self.opts.shell ==
'py':
208 from pprint
import pprint
211 template = {
'sh':
"export %s='%s'",
212 'csh':
"setenv %s '%s';"}.
get(self.opts.shell,
"%s=%s")
213 for nv
in sorted(self.env.items()):
218 Return a copy of iterable where all the elements have the environment
222 >>> s.env = {'A': '1', 'B': 'test'}
223 >>> s.expandEnvVars(['$A', '${B}-$A', '$DUMMY-$A', '$$B'])
224 ['1', 'test-1', '$DUMMY-1', '$B']
226 return [Template(elem).safe_substitute(self.
env)
for elem
in iterable]
230 Execute a command in the modified environment and return the exit code.
232 from subprocess
import Popen
234 rc = Popen(cmd, env=self.
env).wait()
244 Main function of the script.
def expandEnvVars(self, iterable)
def splitNameValue(name_value)
def _prepare_parser(self)