Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 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())

Generated at Wed Dec 4 2013 14:33:06 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004