2 Created on Jun 27, 2011
8 from time
import gmtime, strftime
14 '''object to hold settings of environment'''
16 def __init__(self, loadFromSystem=True, useAsWriter=False, searchPath=None):
17 '''Initial variables to be pushed and setup
19 append switch between append and prepend for initial variables.
20 loadFromSystem causes variable`s system value to be loaded on first encounter.
21 If useAsWriter == True than every change to variables is recorded to XML file.
22 reportLevel sets the level of messaging.
24 self.
log = logging.getLogger(
'Environment')
29 if searchPath
is None:
38 self.
actions[
'set'] =
lambda n, v, _: self.
set(n, v)
44 self.
actions[
'search_path'] =
lambda n, _1, _2: self.searchPath.extend(n.split(self.
separator))
61 dot.expandVars =
False
66 def _locate(self, filename, caller=None, hints=None):
68 Find 'filename' in the internal search path.
70 from os.path
import isabs, isfile, join, dirname, normpath, abspath
74 self.log.debug(
'looking for %s', filename)
77 elif type(hints)
is str:
82 localfile = join(calldir, filename)
83 self.log.debug(
'trying %s', localfile)
85 self.log.debug(
'OK (local file)')
88 hints = [join(calldir, hint)
for hint
in hints]
93 f = normpath(join(d, filename))
94 self.log.debug(
'trying %s', f)
97 f = (abspath(f)
for f
in candidates()
if isfile(f)).next()
100 except StopIteration:
101 from errno
import ENOENT
102 raise OSError(ENOENT,
'cannot find file in %r' % sp, filename)
105 '''returns dictionary of all variables optionally converted to string'''
107 return dict([(n, v.value(
True))
for n, v
in self.variables.items()])
112 '''Gets a single variable. If not available then tries to load from system.'''
116 return os.environ[name]
118 def search(self, varName, expr, regExp=False):
119 '''Searches in a variable for a value.'''
124 Guess the type of the variable from its name: if the name contains
125 'PATH' or 'DIRS', then the variable is a list, otherwise it is a scalar.
127 varname = varname.upper()
128 if 'PATH' in varname
or 'DIRS' in varname:
134 '''Creates an instance of new variable. It loads values from the OS if the variable is not local.'''
138 if not isinstance(local, bool):
139 if str(local).lower() ==
'true':
144 if name
in self.variables.keys():
148 if vartype.lower() ==
"list":
155 if vartype.lower() ==
"list":
162 a.set(os.environ[name], os.pathsep, environment=self.
variables)
168 '''Appends to an existing variable.'''
177 '''Prepends to an existing variable, or create a new one.'''
185 def set(self, name, value):
186 '''Sets a single variable - overrides any previous value!'''
196 '''Sets a single variable only if it is not already set!'''
210 v.set(os.environ[name], os.pathsep, environment=self.
variables)
220 '''Unsets a single variable to an empty value - overrides any previous value!'''
227 def remove(self, name, value, regexp=False):
228 '''Remove value from variable.'''
237 self.
remove(name, value,
True)
241 '''Searches for appearance of variable in a file.'''
243 variable = XMLFile.variable(filename, name=varName)
246 def loadXML(self, fileName=None, namespace='EnvSchema'):
247 '''Loads XML file for input variables.'''
249 fileName = self.
_locate(fileName)
252 self.loadedFiles.add(fileName)
255 self._fileDirStack.append(dot.value())
257 dot.set(os.path.dirname(fileName))
258 variables = XMLfile.variable(fileName, namespace=namespace)
259 for i, (action, args)
in enumerate(variables):
261 self.log.error(
'Node {0}: No action taken with var "{1}". Probably wrong action argument: "{2}".'.
format(i, args[0], action))
265 dot.set(self._fileDirStack.pop())
270 '''Renew writer for new input.'''
271 self.writer.resetWriter()
275 '''Finishes input of XML file and closes the file.'''
276 self.writer.writeToFile(outputFile)
280 '''Creates an output file with a specified name to be used for setting variables by sourcing this file'''
281 f = open(fileName,
'w')
283 f.write(
'#!/bin/bash\n')
285 if not self[variable].local:
286 f.write(
'export ' +variable+
'='+self[variable].value(
True, os.pathsep)+
'\n')
288 f.write(
'#!/bin/csh\n')
290 if not self[variable].local:
291 f.write(
'setenv ' +variable+
' '+self[variable].value(
True, os.pathsep)+
'\n')
294 f.write(
'REM This is an enviroment settings file generated on '+strftime(
"%a, %d %b %Y %H:%M:%S\n", gmtime()))
296 if not self[variable].local:
297 f.write(
'set '+variable+
'='+self[variable].value(
True, os.pathsep)+
'\n')
303 '''Writes the current state of environment to a XML file.
305 NOTE: There is no trace of actions taken, variables are written with a set action only.
312 writer.writeToFile(fileName)
316 '''Loads all variables from the current system settings.'''
317 for k, v
in os.environ.items():
323 Call the variable processors on all the variables.
325 for v
in self.variables.values():
329 '''Returns a variable string with separator separator from the values list'''
333 stri = stri[0:len(stri)-1]
338 '''Writes single variable to XML file.'''
339 if isinstance(value, list):
341 self.writer.writeVar(name, action, value, vartype, local)
348 if key
in self.variables.keys():
349 self.log.warning(
'Addition canceled because of duplicate entry. Var: "%s" value: "%s".', key, value)
361 return item
in self.variables.keys()
364 return len(self.variables.keys())