| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
__init__.py
Go to the documentation of this file.
1 __author__ = "Marco Clemencic <marco.clemencic@cern.ch>"
2
3 import os
4 import sys
5 assert sys.version_info >= (2, 6), "Python 2.6 required"
6
7 import logging
8
9 __all__ = []
10
11 # Prepare the search path for environment XML files
12 path = ['.']
13 if 'ENVXMLPATH' in os.environ:
14 path.extend(os.environ['ENVXMLPATH'].split(os.pathsep))
15
16 import Control
17
18 class EnvError(RuntimeError):
19 '''
20 Simple class to wrap errors in the environment configuration.
21 '''
22 pass
23
24 def splitNameValue(name_value):
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)
31
32 class Script(object):
33 '''
34 Environment Script class used to control the logic of the script and allow
35 extensions.
36 '''
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\")")
43 def __init__(self, args=None):
44 '''
45 Initializes the script instance parsing the command line arguments (or
46 the explicit arguments provided).
47 '''
48 self.parser = None
49 self.opts = None
50 self.cmd = None
51 self.control = None
52 self.log = None
53 self.env = {}
54 # Run the core code of the script
55 self._prepare_parser()
56 self._parse_args(args)
57 self._check_args()
58
59 def _prepare_parser(self):
60 '''
61 Prepare an OptionParser instance used to analyze the command line
62 options and arguments.
63 '''
64 from optparse import OptionParser, OptionValueError
65 parser = OptionParser(prog=os.path.basename(sys.argv[0]),
66 usage=self.__usage__,
67 description=self.__desc__,
68 epilog=self.__epilog__)
69 self.log = logging.getLogger(parser.prog)
70
71 def addOperation(option, opt, value, parser, action):
72 '''
73 Append to the list of actions the tuple (action, (<args>, ...)).
74 '''
75 if action not in ('unset', 'loadXML'):
76 try:
77 value = splitNameValue(value)
78 except EnvError:
79 raise OptionValueError("Invalid value for option %s: '%s', it requires NAME=VALUE." % (opt, value))
80 else:
81 value = (value,)
82 parser.values.actions.append((action, value))
83
84 parser.add_option("-i", "--ignore-environment",
85 action="store_true",
86 help="start with an empty environment")
87 parser.add_option("-u", "--unset",
88 metavar="NAME",
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",
93 metavar="NAME=VALUE",
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",
98 metavar="NAME=VALUE",
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.")
120
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)')
130
131 parser.disable_interspersed_args()
132 parser.set_defaults(actions=[],
133 ignore_environment=False,
134 log_level=logging.WARNING)
135
136 self.parser = parser
137
138 def _parse_args(self, args=None):
139 '''
140 Parse the command line arguments.
141 '''
142 opts, args = self.parser.parse_args(args)
143
144 # set the logging level
145 logging.basicConfig(level=opts.log_level)
146
147 cmd = []
148 # find the (implicit) 'set' arguments in the list of arguments
149 # and put the rest in the command
150 try:
151 for i, a in enumerate(args):
152 opts.actions.append(('set', splitNameValue(a)))
153 except EnvError:
154 cmd = args[i:]
155
156 self.opts, self.cmd = opts, cmd
157
158 def _check_args(self):
159 '''
160 Check consistency of command line options and arguments.
161 '''
162 if self.opts.shell and self.cmd:
163 self.parser.error("Invalid arguments: --%s cannot be used with a command." % self.opts.shell)
164
165 def _makeEnv(self):
166 '''
167 Generate a dictionary of the environment variables after applying all
168 the required actions.
169 '''
170 # prepare the environment control instance
171 control = Control.Environment()
172 if not self.opts.ignore_environment:
173 control.presetFromSystem()
174
175 # apply all the actions
176 for action, args in self.opts.actions:
177 apply(getattr(control, action), args)
178
179 # extract the result env dictionary
180 env = control.vars()
181
182 # set the library search path correctly for the non-Linux platforms
183 if "LD_LIBRARY_PATH" in env:
184 # replace LD_LIBRARY_PATH with the corresponding one on other systems
185 if sys.platform.startswith("win"):
186 other = "PATH"
187 elif sys.platform.startswith("darwin"):
188 other = "DYLD_LIBRARY_PATH"
189 else:
190 other = None
191 if other:
192 if other in env:
193 env[other] = env[other] + os.pathsep + env["LD_LIBRARY_PATH"]
194 else:
195 env[other] = env["LD_LIBRARY_PATH"]
196 del env["LD_LIBRARY_PATH"]
197
198 self.env = env
199
200 def dump(self):
201 '''
202 Print to standard output the final environment in the required format.
203 '''
204 if self.opts.shell == 'py':
205 from pprint import pprint
206 pprint(self.env)
207 else:
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()):
211 print template % nv
212
213 def runCmd(self):
214 '''
215 Execute a command in the modified environment and return the exit code.
216 '''
217 from subprocess import Popen
218 return Popen(self.cmd, env=self.env).wait()
219
220 def main(self):
221 '''
222 Main function of the script.
223 '''
224 self._makeEnv()
225 if not self.cmd:
226 self.dump()
227 else:
228 sys.exit(self.runCmd())