Updated package list to match new versions / new packages.
[beastbuild.git] / buildutils.py
1 import utils
2 import urlparse
3 import os
4 import hashlib
5 import sys
6 import subprocess
7 import stat
8 from config import config
9 from Path import Path
10
11 def download_and_check (url, md5_hash):
12   scheme, host, path, params, qu, fr = urlparse.urlparse (url)
13   filename = os.path.basename (path)
14   download_dir = config.DOWNLOAD.native()
15   if (not os.path.exists (download_dir)):
16     os.makedirs (download_dir)
17   filename_full = os.path.join (download_dir, filename)
18   if (os.path.exists (filename_full)):
19     if (file_md5_hash (filename_full) == md5_hash):
20       return
21   print "downloading " + filename_full + " from " + url
22   sys.stdout.flush()
23   utils.getFile (url, download_dir)
24   local_hash = file_md5_hash (filename_full) 
25   if (local_hash == md5_hash):
26     print "md5 hash check ok."
27     return
28   else:
29     utils.die ("md5 hash of file " + filename_full + " does not match expected value\n"
30              + "expected md5 hash: " + md5_hash + "\n" + "   local md5 hash: " + local_hash)
31
32 def git_checkout (repo, project_git, branch):
33   if project_git.endswith (".git"):
34     project = project_git[:-4]
35   else:
36     project = project_git
37   bb_file_name = config.SRC_DIR.join (Path (project + "/.BEASTBUILD")).native()
38   if not os.path.exists (bb_file_name + "_CLONE_OK"):
39     os.chdir (config.SRC_DIR.native())
40     if repo.startswith ("http://"):
41       cmd = "git clone %s/%s" % (repo, project_git)
42     else:
43       cmd = "git clone %s/%s" % (config.REPOSITORY[repo], project_git)
44     print cmd
45     status = call_log (["sh", "-c", cmd ])
46     if (status != 0):
47       utils.die ("cannot clone git repository %s project %s" % (repo, project_git))
48     # create stamp file
49     file = open (bb_file_name + "_CLONE_OK", "w")
50     file.write ("stamp file needed by beastbuild")
51     file.close()
52   if not os.path.exists (bb_file_name + "_CHECKOUT_OK") and (branch != "master"):
53     os.chdir (os.path.join (config.SRC_DIR.native(), project))
54     cmd = "git checkout -b %s origin/%s" % (branch, branch)
55     print cmd
56     status = call_log (["sh", "-c", cmd ])
57     if (status != 0):
58       utils.die ("cannot checkout branch %s (project %s)" % (branch, project))
59     # create stamp file
60     file = open (bb_file_name + "_CHECKOUT_OK", "w")
61     file.write ("stamp file needed by beastbuild")
62     file.close()
63   os.chdir (os.path.join (config.SRC_DIR.native(), project))
64   cmd = "git pull"
65   print cmd
66   status = call_log (["sh", "-c", cmd ])
67   if (status != 0):
68     utils.die ("cannot pull from project %s" % project)
69  
70 def file_md5_hash (path):
71   m = hashlib.md5()
72   file = open (path, "rb")
73   block = file.read (65536)
74   while block != "":
75     m.update (block)
76     block = file.read (65536)
77   file.close()
78   return m.hexdigest()
79
80 def configure (cmd, dir):
81   if (dir != "."):
82     os.chdir (os.path.join (config.SRC_DIR.native(), dir))
83   cmd_string = ""
84   for i in cmd:
85     cmd_string += i + " ";
86   print "configure: " + cmd_string
87   sys.stdout.flush()
88   status = call_log (cmd)
89   if (status != 0):
90     utils.die ("error (%d) while configuring package" % status)
91
92 def make (cmd, dir):
93   if (dir != "."):
94     os.chdir (os.path.join (config.SRC_DIR.native(), dir))
95   cmd_string = ""
96   for i in cmd:
97     cmd_string += i + " ";
98   print "make: " + cmd_string
99   sys.stdout.flush()
100   status = call_log (cmd)
101   if (status != 0):
102     utils.die ("error (%d) while compiling package" % status)
103
104 ### patch file functions
105 def apply_patch(patch, dir, patch_depth):
106   if (dir != "."):
107     os.chdir (os.path.join (config.SRC_DIR.native(), dir))
108   cmd = "set -o pipefail ; stripm < %s | patch -p%d" % (config.BEASTBUILD.join (Path (patch)).unix(), patch_depth)
109   print "apply_patch: " + cmd
110   sys.stdout.flush()
111   status = call_log (["sh", "-c", cmd])
112   if (status != 0):
113     utils.die ("error: can not apply patch " + patch)
114
115 ### rm -rf
116 # shutil.rmtree (dir) fails with write protected files on windows
117 def rm_rf (path):
118   try:
119     mode = os.lstat(path).st_mode
120     if stat.S_ISDIR(mode):
121       for entry in os.listdir (path):
122         rm_rf (os.path.join (path, entry))
123       os.rmdir (path)
124     else:
125       try:
126         os.remove (path)
127       except:
128         os.chmod (path, 0777)
129         os.remove (path)
130   except OSError,e:
131     if e.errno != os.errno.ENOENT:  # ignore non-existant files
132       utils.die ("error: can not delete '" + path + "' from cwd=" + os.getcwd() + ":" + os.strerror (e.errno))
133
134 #--------------------------------------------------------------------------------------------
135 # subprocess with logfile output
136 #--------------------------------------------------------------------------------------------
137
138 from subprocess import Popen, PIPE
139 import thread, threading
140 import os, sys
141
142 thread_lock = threading.Lock()
143 log_file = False
144
145 def out_reader (file):
146   while True:
147     line = file.readline ()
148     if line == '':
149       return
150     thread_lock.acquire()
151     sys.stdout.write (line)
152     log_file.write (line)
153     log_file.flush()
154     thread_lock.release()
155
156
157 def call_log_file (file_name):
158   global log_file
159   try:
160     log_file = open (file_name, 'w')
161   except:
162     utils.die ("error: can't write log file: '" + file_name + "'")
163
164 def call_log (cmd):
165   proc = Popen(cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE)
166   t1 = thread.start_new_thread (out_reader, (proc.stdout,))
167   t2 = thread.start_new_thread (out_reader, (proc.stderr,))
168   return proc.wait()
169
170 ## platform specific code
171 #
172 def platform_is_win32():
173   return sys.platform == "win32"
174
175 def platform_is_unix():
176   return not platform_is_win32()
177
178 def prepend_path (path):
179   if platform_is_win32():
180     old_path = os.environ['Path']
181     new_path = path.win32() + ";" + old_path
182     os.environ['Path'] = new_path
183   else:
184     old_path = os.environ['PATH']
185     new_path = path.unix() + ":" + old_path
186     os.environ['PATH'] = new_path
187
188 # vim:set sw=2 sts=2: