Salome HOME
9d0f28556de2c4b72b98b6f12c3d3cba89d517fd
[tools/sat.git] / src / system.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 '''
20 In this file : all functions that do a system call, 
21 like open a browser or an editor, or call a git command
22 '''
23
24 import os
25 import subprocess
26 import time
27 import tarfile
28
29 import debug as DBG
30 import utilsSat as UTS
31
32 from . import printcolors
33
34 def show_in_editor(editor, filePath, logger):
35     '''open filePath using editor.
36     
37     :param editor str: The editor to use.
38     :param filePath str: The path to the file to open.
39     '''
40     # default editor is vi
41     if editor is None or len(editor) == 0:
42         editor = 'vi'
43     
44     if '%s' not in editor:
45         editor += ' %s'
46
47     try:
48         # launch cmd using subprocess.Popen
49         cmd = editor % filePath
50         logger.write('Launched command:\n' + cmd + '\n', 5)
51         p = subprocess.Popen(cmd, shell=True)
52         p.communicate()
53     except:
54         logger.write(printcolors.printcError(_("Unable to edit file %s\n") 
55                                              % filePath), 1)
56
57
58 def git_extract(from_what, tag, where, logger, environment=None):
59   '''Extracts sources from a git repository.
60
61   :param from_what str: The remote git repository.
62   :param tag str: The tag.
63   :param where str: The path where to extract.
64   :param logger Logger: The logger instance to use.
65   :param environment src.environment.Environ: The environment to source when extracting.
66   :return: True if the extraction is successful
67   :rtype: boolean
68   '''
69   DBG.write("git_extract", [from_what, tag, str(where)])
70   if not where.exists():
71     where.make()
72   if tag == "master" or tag == "HEAD":
73     cmd = r"""
74 set -x
75 git clone %(remote)s %(where)s
76 """
77     cmd = cmd % {'remote': from_what, 'tag': tag, 'where': str(where)}
78   else:
79     # NOTICE: this command only works with recent version of git
80     #         because --work-tree does not work with an absolute path
81     where_git = os.path.join(str(where), ".git")
82
83     cmd = r"""
84 set -x
85 rmdir %(where)s
86 git clone %(remote)s %(where)s && \
87 git --git-dir=%(where_git)s --work-tree=%(where)s checkout %(tag)s
88 """
89     cmd = cmd % {'remote': from_what,
90                  'tag': tag,
91                  'where': str(where),
92                  'where_git': where_git}
93
94
95   logger.logTxtFile.write("\n" + cmd + "\n")
96   logger.logTxtFile.flush()
97
98   DBG.write("cmd", cmd)
99
100   for nbtry in range(0,3): # retries case of network problem
101     rc = UTS.Popen(cmd, cwd=str(where.dir()), env=environment.environ.environ, logger=logger)
102     if rc.isOk(): break
103     time.sleep(30) # wait a little
104
105   return rc.isOk()
106
107   """
108   res = subprocess.call(command,
109                         cwd=str(where.dir()),
110                         env=environment.environ.environ,
111                         shell=True,
112                         stdout=logger.logTxtFile,
113                         stderr=subprocess.STDOUT)
114   return (res == 0)
115   """
116
117
118
119 def git_extract_sub_dir(from_what, tag, where, sub_dir, logger, environment=None):
120   '''Extracts sources from a subtree sub_dir of a git repository.
121
122   :param from_what str: The remote git repository.
123   :param tag str: The tag.
124   :param where str: The path where to extract.
125   :param sub_dir str: The relative path of subtree to extract.
126   :param logger Logger: The logger instance to use.
127   :param environment src.environment.Environ: The environment to source when extracting.
128   :return: True if the extraction is successful
129   :rtype: boolean
130   '''
131   strWhere = str(where)
132   tmpWhere = strWhere + '_tmp'
133   parentWhere = os.path.dirname(strWhere)
134   if not os.path.exists(parentWhere):
135     logger.error("not existing directory: %s" % parentWhere)
136     return False
137   if os.path.isdir(strWhere):
138     logger.error("do not override existing directory: %s" % strWhere)
139     return False
140   aDict = {'remote': from_what,
141            'tag': tag,
142            'sub_dir': sub_dir,
143            'where': strWhere,
144            'parentWhere': parentWhere,
145            'tmpWhere': tmpWhere,
146            }
147   DBG.write("git_extract_sub_dir", aDict)
148
149   cmd = r"""
150 set -x
151 export tmpDir=%(tmpWhere)s && \
152 rm -rf $tmpDir
153 git clone %(remote)s $tmpDir && \
154 cd $tmpDir && \
155 git checkout %(tag)s && \
156 mv %(sub_dir)s %(where)s && \
157 git log -1 > %(where)s/README_git_log.txt && \
158 rm -rf $tmpDir
159 """ % aDict
160   DBG.write("cmd", cmd)
161
162   for nbtry in range(0,3): # retries case of network problem
163     rc = UTS.Popen(cmd, cwd=parentWhere, env=environment.environ.environ, logger=logger)
164     if rc.isOk(): break
165     time.sleep(30) # wait a little
166
167   return rc.isOk()
168
169 def archive_extract(from_what, where, logger):
170     '''Extracts sources from an archive.
171     
172     :param from_what str: The path to the archive.
173     :param where str: The path where to extract.
174     :param logger Logger: The logger instance to use.
175     :return: True if the extraction is successful
176     :rtype: boolean
177     '''
178     try:
179         archive = tarfile.open(from_what)
180         for i in archive.getmembers():
181             archive.extract(i, path=str(where))
182         return True, os.path.commonprefix(archive.getnames())
183     except Exception as exc:
184         logger.write("archive_extract: %s\n" % exc)
185         return False, None
186
187 def cvs_extract(protocol, user, server, base, tag, product, where,
188                 logger, checkout=False, environment=None):
189     '''Extracts sources from a cvs repository.
190     
191     :param protocol str: The cvs protocol.
192     :param user str: The user to be used.
193     :param server str: The remote cvs server.
194     :param base str: .
195     :param tag str: The tag.
196     :param product str: The product.
197     :param where str: The path where to extract.
198     :param logger Logger: The logger instance to use.
199     :param checkout boolean: If true use checkout cvs.
200     :param environment src.environment.Environ: The environment to source when
201                                                 extracting.
202     :return: True if the extraction is successful
203     :rtype: boolean
204     '''
205
206     opttag = ''
207     if tag is not None and len(tag) > 0:
208         opttag = '-r ' + tag
209
210     cmd = 'export'
211     if checkout:
212         cmd = 'checkout'
213     elif len(opttag) == 0:
214         opttag = '-DNOW'
215     
216     if len(protocol) > 0:
217         root = "%s@%s:%s" % (user, server, base)
218         command = "cvs -d :%(protocol)s:%(root)s %(command)s -d %(where)s %(tag)s %(product)s" % \
219             { 'protocol': protocol, 'root': root, 'where': str(where.base()),
220               'tag': opttag, 'product': product, 'command': cmd }
221     else:
222         command = "cvs -d %(root)s %(command)s -d %(where)s %(tag)s %(base)s/%(product)s" % \
223             { 'root': server, 'base': base, 'where': str(where.base()),
224               'tag': opttag, 'product': product, 'command': cmd }
225
226     logger.write(command + "\n", 5)
227
228     if not where.dir().exists():
229         where.dir().make()
230
231     logger.logTxtFile.write("\n" + command + "\n")
232     logger.logTxtFile.flush()        
233     res = subprocess.call(command,
234                           cwd=str(where.dir()),
235                           env=environment.environ.environ,
236                           shell=True,
237                           stdout=logger.logTxtFile,
238                           stderr=subprocess.STDOUT)
239     return (res == 0)
240
241 def svn_extract(user,
242                 from_what,
243                 tag,
244                 where,
245                 logger,
246                 checkout=False,
247                 environment=None):
248     '''Extracts sources from a svn repository.
249     
250     :param user str: The user to be used.
251     :param from_what str: The remote git repository.
252     :param tag str: The tag.
253     :param where str: The path where to extract.
254     :param logger Logger: The logger instance to use.
255     :param checkout boolean: If true use checkout svn.
256     :param environment src.environment.Environ: The environment to source when
257                                                 extracting.
258     :return: True if the extraction is successful
259     :rtype: boolean
260     '''
261     if not where.exists():
262         where.make()
263
264     if checkout:
265         command = "svn checkout --username %(user)s %(remote)s %(where)s" % \
266             { 'remote': from_what, 'user' : user, 'where': str(where) }
267     else:
268         command = ""
269         if os.path.exists(str(where)):
270             command = "/bin/rm -rf %(where)s && " % \
271                 { 'remote': from_what, 'where': str(where) }
272         
273         if tag == "master":
274             command += "svn export --username %(user)s %(remote)s %(where)s" % \
275                 { 'remote': from_what, 'user' : user, 'where': str(where) }       
276         else:
277             command += "svn export -r %(tag)s --username %(user)s %(remote)s %(where)s" % \
278                 { 'tag' : tag, 'remote': from_what, 'user' : user, 'where': str(where) }
279     
280     logger.logTxtFile.write(command + "\n")
281     
282     logger.write(command + "\n", 5)
283     logger.logTxtFile.write("\n" + command + "\n")
284     logger.logTxtFile.flush()
285     res = subprocess.call(command,
286                           cwd=str(where.dir()),
287                           env=environment.environ.environ,
288                           shell=True,
289                           stdout=logger.logTxtFile,
290                           stderr=subprocess.STDOUT)
291     return (res == 0)