Salome HOME
First environ command version
[tools/sat.git] / src / fileEnviron.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2013  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20
21 batch_header="""@echo off
22
23 rem The following variables are used only in case of a sat package
24 set out_dir_Path=%~dp0
25 set PRODUCT_OUT_DIR=%out_dir_Path%
26 set prereq_install_Path=%out_dir_Path%\PREREQUISITES\INSTALL
27 set prereq_build_Path=%out_dir_Path%\PREREQUISITES\BUILD
28 """
29
30
31 bash_header="""#!/bin/bash
32 ##########################################################################
33 #
34 #### cleandup ###
35 # cleanup a path (first parameter) from duplicated entries;
36 # second parameter is the separator
37 cleandup() {
38 out_var=`echo $1 | awk -v sep=$2 '{                      \\
39      na = split($1,a,sep);                               \\
40      k=0;                                                \\
41      for(i=0;i<=na;i++) {                                \\
42        found=0;                                          \\
43        for(j=0;j<k;j++) {                                \\
44          if(a[i]==aa[j])                                 \\
45          {                                               \\
46            found=1;                                      \\
47            break;                                        \\
48          };                                              \\
49        };                                                \\
50        if(found==0) {                                    \\
51          aa[k++]=a[i];                                   \\
52        };                                                \\
53      };                                                  \\
54      ORS=sep;                                            \\
55      for(i=0;i<k;i++) {                                  \\
56        print aa[i];                                      \\
57      }                                                   \\
58    }' | sed -e 's|\\(.*\\)$1|\\1|g' -e 's|^[:;]||' -e 's|[:;]$||'`
59 echo $out_var
60 }
61 ### clean ###
62 clean ()
63 {
64 xenv=`printenv $1`
65 out_var=`cleandup $xenv $2`
66 export $1=$out_var
67 }
68
69 # The 3 following variables are used only in case of a sat package
70 export out_dir_Path=`dirname "${BASH_SOURCE[0]}"`
71 export PRODUCT_OUT_DIR=${out_dir_Path}
72 export PRODUCT_ROOT_DIR=${PRODUCT_OUT_DIR}
73 export prereq_install_Path=${out_dir_Path}/PREREQUISITES/INSTALL
74 export prereq_build_Path=${out_dir_Path}/PREREQUISITES/BUILD
75
76 ###########################################################################
77 """
78
79
80 cfgForPy_header='''# a generated SALOME Configuration file in python syntax from "sat application %s"
81 '''
82
83 ##
84 # Instantiate correct FileEnvironment sub-class.
85 def get_file_environ(output, shell, environ=None, config=None):
86     if shell == "bash":
87         return BashFileEnviron(output, environ)
88     if shell == "batch":
89         return BatchFileEnviron(output, environ)
90     if shell == "cfgForPy":
91         return CfgForPyFileEnviron(output, environ, config)
92     raise Exception("FileEnviron: Unknown shell = %s" % shell)
93
94 ##
95 # Base class for shell environment.
96 class FileEnviron:
97     def __init__(self, output, environ=None):
98         self._do_init(output, environ)
99
100     def _do_init(self, output, environ=None):
101         self.output = output
102         self.toclean = []
103         if environ is not None:
104             self.environ = environ
105         else:
106             self.environ = os.environ
107
108     def add_line(self, number):
109         self.output.write("\n" * number)
110
111     def add_comment(self, comment):
112         self.output.write("# %s\n" % comment)
113
114     def add_echo(self, text):
115         self.output.write('echo %s"\n' % text)
116
117     def add_warning(self, warning):
118         self.output.write('echo "WARNING %s"\n' % warning)
119
120     def append_value(self, key, value, sep=os.pathsep):
121         self.set(key, self.get(key) + sep + value)
122         if (key, sep) not in self.toclean:
123             self.toclean.append((key, sep))
124
125     def append(self, key, value, sep=os.pathsep):
126         if isinstance(value, list):
127             self.append_value(key, sep.join(value), sep)
128         else:
129             self.append_value(key, value, sep)
130
131     def prepend_value(self, key, value, sep=os.pathsep):
132         self.set(key, value + sep + self.get(key))
133         if (key, sep) not in self.toclean:
134             self.toclean.append((key, sep))
135
136     def prepend(self, key, value, sep=os.pathsep):
137         if isinstance(value, list):
138             self.prepend_value(key, sep.join(value), sep)
139         else:
140             self.prepend_value(key, value, sep)
141
142     def is_defined(self, key):
143         return self.environ.has_key(key)
144
145     def set(self, key, value):
146         raise NotImplementedError("set is not implement for this shell!")
147
148     def get(self, key):
149         return '${%s}' % key
150
151     def command_value(self, key, command):
152         raise NotImplementedError("command_value is not implement for this shell!")
153
154     def finish(self, required=True):
155         for (key, sep) in self.toclean:
156             if sep != ' ':
157                 self.output.write('clean %s "%s"\n' % (key, sep))
158
159 ##
160 # Class for bash shell.
161 class BashFileEnviron(FileEnviron):
162     def __init__(self, output, environ=None):
163         self._do_init(output, environ)
164         self.output.write(bash_header)
165
166     def set(self, key, value):
167         self.output.write('export %s="%s"\n' % (key, value))
168         self.environ[key] = value
169
170     def command_value(self, key, command):
171         self.output.write('export %s=$(%s)\n' % (key, command))
172
173     def finish(self, required=True):
174         if not required:
175             return
176         FileEnviron.finish(self, required)
177         
178 ##
179 # Class for Windows batch shell.
180 class BatchFileEnviron(FileEnviron):
181     def __init__(self, output, environ=None):
182         self._do_init(output, environ)
183         self.output.write(batch_header)
184
185     def add_comment(self, comment):
186         self.output.write("rem %s\n" % comment)
187     
188     def get(self, key):
189         return '%%%s%%' % key
190     
191     def set(self, key, value):
192         self.output.write('set %s=%s\n' % (key, value))
193         self.environ[key] = value
194
195     def command_value(self, key, command):
196         self.output.write('%s > tmp.txt\n' % (command))
197         self.output.write('set /p %s =< tmp.txt\n' % (key))
198
199     def finish(self, required=True):
200         return
201
202 ##
203 # Base class for cfg environment file.
204 class FileCfg:
205     def __init__(self, output, environ=None):
206         self._do_init(output, environ)
207
208     def _do_init(self, output, environ=None):
209         self.output = output
210         self.toclean = []
211         if environ is not None:
212             self.environ = environ
213         else:
214             self.environ = os.environ
215         if not self.environ.has_key("PATH"):
216             self.environ["PATH"]=""
217         if not self.environ.has_key("LD_LIBRARY_PATH"):
218             self.environ["LD_LIBRARY_PATH"]=""
219         if not self.environ.has_key("PYTHONPATH"):
220             self.environ["PYTHONPATH"]=""
221         if not self.environ.has_key("TCLLIBPATH"):
222             self.environ["TCLLIBPATH"]=""
223         if not self.environ.has_key("TKLIBPATH"):
224             self.environ["TKLIBPATH"]=""
225
226
227     def add_line(self, number):
228         self.output.write("\n" * number)
229
230     def add_comment(self, comment):
231         self.output.write("# %s\n" % comment)
232
233     def add_echo(self, text):
234         self.output.write('# %s"\n' % text)
235
236     def add_warning(self, warning):
237         self.output.write('# "WARNING %s"\n' % warning)
238
239     def append_value(self, key, value, sep=":"):
240         if self.is_defined(key) :
241             self.add(key, value)
242         else :
243             self.set(key, value)
244
245     def append(self, key, value, sep=":"):
246         if isinstance(value, list):
247             self.append_value(key, sep.join(value), sep)
248         else:
249             self.append_value(key, value, sep)
250
251     def prepend_value(self, key, value, sep=":"):
252         if self.is_defined(key) :
253             self.add(key, value)
254         else :
255             self.set(key, value)
256
257     def prepend(self, key, value, sep=":"):
258         if isinstance(value, list):
259             self.prepend_value(key, sep.join(value), sep)
260         else:
261             self.prepend_value(key, value, sep)
262
263     def is_defined(self, key):
264         return self.environ.has_key(key)
265
266     def set(self, key, value):
267         raise NotImplementedError("set is not implement for file .cfg!")
268
269     def get(self, key):
270         return '${%s}' % key
271
272     def command_value(self, key, command):
273         raise NotImplementedError("command_value is not implement for file .cfg!")
274
275     def finish(self, required=True):
276         #for (key, sep) in self.toclean:
277         #   if sep != ' ':
278         #       self.output.write('clean %s "%s"\n' % (key, sep))
279         #self.output.write("# finish\n")
280         pass
281
282
283 def specialPathSeparator(name):
284     """TCLLIBPATH, TKLIBPATH, PV_PLUGIN_PATH environments variables needs some exotic path separator"""
285     specialBlanksKeys=["TCLLIBPATH", "TKLIBPATH"]
286     specialSemicolonKeys=["PV_PLUGIN_PATH"]
287     res=os.pathsep
288     if name in specialBlanksKeys: res=" "
289     if name in specialSemicolonKeys: res=";"
290     return res
291
292 ##
293 #
294 ##
295 # Class for generate a cfg file script (in python syntax) SalomeContext API.
296 class CfgForPyFileEnviron(FileCfg):
297     def __init__(self, output, environ=None, config=None):
298         self.config=config
299         self._do_init(output, environ)
300
301         self.indent="    " # four whitespaces for first indentation in a python script
302         self.prefix="context."
303         self.setVarEnv="setVariable"
304         
305         self.begin=self.indent+self.prefix
306         self.output.write((cfgForPy_header) % config['VARS']['product'])
307         self.specialKeys={"PATH": "Path", "LD_LIBRARY_PATH": "LdLibraryPath", "PYTHONPATH": "PythonPath"}
308
309     def changeToCfg(self, value):
310         res=value
311         return res
312
313     def set(self, key, value):
314         self.output.write(self.begin+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % (key, self.changeToCfg(value)))
315         self.environ[key] = value
316
317     def add(self, key, value):        
318         if key in self.specialKeys.keys():
319             self.output.write(self.begin+'addTo%s(r"%s")\n' % (self.specialKeys[key], self.changeToCfg(value)))
320             self.environ[key]+=":"+value
321             return
322         sep=specialPathSeparator(key)
323         self.output.write(self.indent+'#temporary solution!!! have to be defined in API a ?dangerous? addToSpecial(r"%s", r"%s")\n' % (key, value))
324         #pathsep not precised because do not know future os launch?
325         self.output.write(self.begin+'addToSpecial(r"%s", r"%s")\n' % (key, self.changeToCfg(value)))
326         self.environ[key]+=sep+value #here yes we know os for current execution
327
328     def command_value(self, key, command):
329         #self.output.write('%s=`%s`\n' % (key, command))
330         self.output.write(self.indent+'#`%s`\n' % command)
331
332         import shlex, subprocess
333         args = shlex.split(command)
334         res=subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
335         out, __ = res.communicate()
336         self.output.write(self.begin+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % (key, out))       
337         pass
338
339     def add_comment(self, comment):
340         if comment=="DISTENE license":
341             self.output.write(self.indent+"#"+self.prefix+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % ('DISTENE_LICENSE_FILE', self.changeToCfg('Use global envvar: DLIM8VAR')))
342             self.output.write(self.indent+"#"+self.prefix+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % ('DISTENE_LICENCE_FILE_FOR_MGCLEANER', self.changeToCfg('<path to your license>')))
343             self.output.write(self.indent+"#"+self.prefix+self.setVarEnv+'(r"%s", r"%s", overwrite=True)\n' % ('DISTENE_LICENCE_FILE_FOR_YAMS', self.changeToCfg('<path to your license>')))
344             return
345         if "setting environ for" in comment:
346             self.output.write(self.indent+"#[%s]\n" % comment.split("setting environ for ")[1])
347             return
348         if "PRODUCT environment" in comment:
349             self.output.write(self.indent+"#[SALOME Configuration]\n\n")
350             self.output.write(self.indent+"# PRODUCT environment\n")
351             tmp=","
352             for i in self.config['PRODUCT']['modules']: tmp+=i+','
353             self.output.write(self.indent+"#only for information:\n")
354             self.output.write(self.indent+'#'+self.setVarEnv+'("SALOME_MODULES", r"%s", overwrite=True)\n\n' % tmp[1:-1])
355             try:
356                 #tmp1=self.config['APPLI']['module_appli']
357                 #tmp2=self.config.TOOLS.common.module_info[tmp1].install_dir
358                 tmp3=self.config.APPLI.module_appli_install_dir
359                 relpath=os.path.relpath("/",os.getenv("HOME"))
360                 tmp=relpath[0:-1]+tmp3
361                 self.output.write(self.indent+"#only for information: ${APPLI} is preset and have to be relative to $HOME\n")
362                 self.output.write(self.indent+'#'+self.setVarEnv+'("APPLI", r"%s", overwrite=True)\n\n' % tmp)
363             except:
364                 self.output.write(self.indent+"#only for information: ${APPLI} is by default\n")
365             return
366         self.output.write(self.indent+"# %s\n" % comment)
367