]> SALOME platform Git repositories - tools/sat.git/blob - src/system.py
Salome HOME
correction bug ecrasement codage architecture pour debian
[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   # git commands may fail sometimes for various raisons 
101   # (big module, network troubles, tuleap maintenance)
102   # therefore we give several tries
103   i_try = 0
104   max_number_of_tries = 3
105   sleep_delay = 30  # seconds
106   while (True):
107     i_try += 1
108     rc = UTS.Popen(cmd, cwd=str(where.dir()), env=environment.environ.environ, logger=logger)
109     if rc.isOk() or (i_try>=max_number_of_tries):
110       break
111     logger.write('\ngit command failed! Wait %d seconds and give an other try (%d/%d)\n' % \
112                  (sleep_delay, i_try + 1, max_number_of_tries), 3)
113     time.sleep(sleep_delay) # wait a little
114
115   return rc.isOk()
116
117
118 def git_extract_sub_dir(from_what, tag, where, sub_dir, logger, environment=None):
119   '''Extracts sources from a subtree sub_dir of a git repository.
120
121   :param from_what str: The remote git repository.
122   :param tag str: The tag.
123   :param where str: The path where to extract.
124   :param sub_dir str: The relative path of subtree to extract.
125   :param logger Logger: The logger instance to use.
126   :param environment src.environment.Environ: The environment to source when extracting.
127   :return: True if the extraction is successful
128   :rtype: boolean
129   '''
130   strWhere = str(where)
131   tmpWhere = strWhere + '_tmp'
132   parentWhere = os.path.dirname(strWhere)
133   if not os.path.exists(parentWhere):
134     logger.error("not existing directory: %s" % parentWhere)
135     return False
136   if os.path.isdir(strWhere):
137     logger.error("do not override existing directory: %s" % strWhere)
138     return False
139   aDict = {'remote': from_what,
140            'tag': tag,
141            'sub_dir': sub_dir,
142            'where': strWhere,
143            'parentWhere': parentWhere,
144            'tmpWhere': tmpWhere,
145            }
146   DBG.write("git_extract_sub_dir", aDict)
147
148   cmd = r"""
149 set -x
150 export tmpDir=%(tmpWhere)s && \
151 rm -rf $tmpDir
152 git clone %(remote)s $tmpDir && \
153 cd $tmpDir && \
154 git checkout %(tag)s && \
155 mv %(sub_dir)s %(where)s && \
156 git log -1 > %(where)s/README_git_log.txt && \
157 rm -rf $tmpDir
158 """ % aDict
159   DBG.write("cmd", cmd)
160
161   for nbtry in range(0,3): # retries case of network problem
162     rc = UTS.Popen(cmd, cwd=parentWhere, env=environment.environ.environ, logger=logger)
163     if rc.isOk(): break
164     time.sleep(30) # wait a little
165
166   return rc.isOk()
167
168 def archive_extract(from_what, where, logger):
169     '''Extracts sources from an archive.
170     
171     :param from_what str: The path to the archive.
172     :param where str: The path where to extract.
173     :param logger Logger: The logger instance to use.
174     :return: True if the extraction is successful
175     :rtype: boolean
176     '''
177     try:
178         archive = tarfile.open(from_what)
179         for i in archive.getmembers():
180             archive.extract(i, path=str(where))
181         return True, os.path.commonprefix(archive.getnames())
182     except Exception as exc:
183         logger.write("archive_extract: %s\n" % exc)
184         return False, None
185
186 def cvs_extract(protocol, user, server, base, tag, product, where,
187                 logger, checkout=False, environment=None):
188     '''Extracts sources from a cvs repository.
189     
190     :param protocol str: The cvs protocol.
191     :param user str: The user to be used.
192     :param server str: The remote cvs server.
193     :param base str: .
194     :param tag str: The tag.
195     :param product str: The product.
196     :param where str: The path where to extract.
197     :param logger Logger: The logger instance to use.
198     :param checkout boolean: If true use checkout cvs.
199     :param environment src.environment.Environ: The environment to source when
200                                                 extracting.
201     :return: True if the extraction is successful
202     :rtype: boolean
203     '''
204
205     opttag = ''
206     if tag is not None and len(tag) > 0:
207         opttag = '-r ' + tag
208
209     cmd = 'export'
210     if checkout:
211         cmd = 'checkout'
212     elif len(opttag) == 0:
213         opttag = '-DNOW'
214     
215     if len(protocol) > 0:
216         root = "%s@%s:%s" % (user, server, base)
217         command = "cvs -d :%(protocol)s:%(root)s %(command)s -d %(where)s %(tag)s %(product)s" % \
218             { 'protocol': protocol, 'root': root, 'where': str(where.base()),
219               'tag': opttag, 'product': product, 'command': cmd }
220     else:
221         command = "cvs -d %(root)s %(command)s -d %(where)s %(tag)s %(base)s/%(product)s" % \
222             { 'root': server, 'base': base, 'where': str(where.base()),
223               'tag': opttag, 'product': product, 'command': cmd }
224
225     logger.write(command + "\n", 5)
226
227     if not where.dir().exists():
228         where.dir().make()
229
230     logger.logTxtFile.write("\n" + command + "\n")
231     logger.logTxtFile.flush()        
232     res = subprocess.call(command,
233                           cwd=str(where.dir()),
234                           env=environment.environ.environ,
235                           shell=True,
236                           stdout=logger.logTxtFile,
237                           stderr=subprocess.STDOUT)
238     return (res == 0)
239
240 def svn_extract(user,
241                 from_what,
242                 tag,
243                 where,
244                 logger,
245                 checkout=False,
246                 environment=None):
247     '''Extracts sources from a svn repository.
248     
249     :param user str: The user to be used.
250     :param from_what str: The remote git repository.
251     :param tag str: The tag.
252     :param where str: The path where to extract.
253     :param logger Logger: The logger instance to use.
254     :param checkout boolean: If true use checkout svn.
255     :param environment src.environment.Environ: The environment to source when
256                                                 extracting.
257     :return: True if the extraction is successful
258     :rtype: boolean
259     '''
260     if not where.exists():
261         where.make()
262
263     if checkout:
264         command = "svn checkout --username %(user)s %(remote)s %(where)s" % \
265             { 'remote': from_what, 'user' : user, 'where': str(where) }
266     else:
267         command = ""
268         if os.path.exists(str(where)):
269             command = "/bin/rm -rf %(where)s && " % \
270                 { 'remote': from_what, 'where': str(where) }
271         
272         if tag == "master":
273             command += "svn export --username %(user)s %(remote)s %(where)s" % \
274                 { 'remote': from_what, 'user' : user, 'where': str(where) }       
275         else:
276             command += "svn export -r %(tag)s --username %(user)s %(remote)s %(where)s" % \
277                 { 'tag' : tag, 'remote': from_what, 'user' : user, 'where': str(where) }
278     
279     logger.logTxtFile.write(command + "\n")
280     
281     logger.write(command + "\n", 5)
282     logger.logTxtFile.write("\n" + command + "\n")
283     logger.logTxtFile.flush()
284     res = subprocess.call(command,
285                           cwd=str(where.dir()),
286                           env=environment.environ.environ,
287                           shell=True,
288                           stdout=logger.logTxtFile,
289                           stderr=subprocess.STDOUT)
290     return (res == 0)