- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / build_tools / buildbot_common.py
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Common utilities for all buildbot scripts that specifically don't rely
6 on having a full chromium checkout.
7 """
8
9 import os
10 import subprocess
11 import sys
12
13 from build_paths import SDK_SRC_DIR, NACL_DIR
14
15 sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
16 import oshelpers
17 import getos
18
19 def IsSDKBuilder():
20   """Returns True if this script is running on an SDK builder.
21
22   False means it is either running on a trybot, or a user's machine.
23
24   Trybot names:
25     (win|mac|linux)_nacl_sdk
26
27   Build-only Trybot names:
28     (win|mac|linux)_nacl_sdk_build
29
30   Builder names:
31     (windows|mac|linux)-sdk-multi(rel)?"""
32   return '-sdk-multi' in os.getenv('BUILDBOT_BUILDERNAME', '')
33
34
35 def IsBuildOnlyBot():
36   """Returns True if this script is running on a build-only bot.
37
38   Build only bots are designed to be fast and non-flaky.  Currently
39   this means they don't build chrome, and don't run any browser-based
40   tests.  Currently the only build-only bots are trybots.
41
42   See IsSDKBuilder above for trybot/buildbot names."""
43   return os.getenv('BUILDBOT_BUILDERNAME', '').endswith('build')
44
45
46 def IsSDKTrybot():
47   """Returns True if this script is running on an SDK trybot.
48
49   False means it is either running on an SDK builder, or a user's machine.
50
51   See IsSDKBuilder above for trybot/buildbot names."""
52   return '_nacl_sdk' in os.getenv('BUILDBOT_BUILDERNAME', '')
53
54
55 def ErrorExit(msg):
56   """Write and error to stderr, then exit with 1 signaling failure."""
57   sys.stderr.write(str(msg) + '\n')
58   sys.exit(1)
59
60
61 def GetWindowsEnvironment():
62   sys.path.append(os.path.join(NACL_DIR, 'buildbot'))
63   import buildbot_standard
64
65   # buildbot_standard.SetupWindowsEnvironment expects a "context" object. We'll
66   # fake enough of that here to work.
67   class FakeContext(object):
68     def __init__(self):
69       self.env = os.environ
70
71     def GetEnv(self, key):
72       return self.env[key]
73
74     def __getitem__(self, key):
75       return self.env[key]
76
77     def SetEnv(self, key, value):
78       self.env[key] = value
79
80     def __setitem__(self, key, value):
81       self.env[key] = value
82
83   context = FakeContext()
84   buildbot_standard.SetupWindowsEnvironment(context)
85
86   # buildbot_standard.SetupWindowsEnvironment adds the directory which contains
87   # vcvarsall.bat to the path, but not the directory which contains cl.exe,
88   # link.exe, etc.
89   # Running vcvarsall.bat adds the correct directories to the path, which we
90   # extract below.
91   process = subprocess.Popen('vcvarsall.bat x86 > NUL && set',
92       stdout=subprocess.PIPE, env=context.env, shell=True)
93   stdout, _ = process.communicate()
94
95   # Parse environment from "set" command above.
96   # It looks like this:
97   # KEY1=VALUE1\r\n
98   # KEY2=VALUE2\r\n
99   # ...
100   return dict(line.split('=') for line in stdout.split('\r\n')[:-1])
101
102
103 def BuildStep(name):
104   """Annotate a buildbot build step."""
105   sys.stdout.flush()
106   print '\n@@@BUILD_STEP %s@@@' % name
107   sys.stdout.flush()
108
109
110 def Run(args, cwd=None, env=None, shell=False):
111   """Start a process with the provided arguments.
112
113   Starts a process in the provided directory given the provided arguments. If
114   shell is not False, the process is launched via the shell to provide shell
115   interpretation of the arguments.  Shell behavior can differ between platforms
116   so this should be avoided when not using platform dependent shell scripts."""
117
118   # We need to modify the environment to build host on Windows.
119   if not env and getos.GetPlatform() == 'win':
120     env = GetWindowsEnvironment()
121
122   print 'Running: ' + ' '.join(args)
123   sys.stdout.flush()
124   sys.stderr.flush()
125   try:
126     subprocess.check_call(args, cwd=cwd, env=env, shell=shell)
127   except subprocess.CalledProcessError as e:
128     sys.stdout.flush()
129     sys.stderr.flush()
130     ErrorExit('buildbot_common: %s' % e)
131
132   sys.stdout.flush()
133   sys.stderr.flush()
134
135
136 def CopyDir(src, dst, excludes=('.svn', '*/.svn')):
137   """Recursively copy a directory using."""
138   args = ['-r', src, dst]
139   for exc in excludes:
140     args.append('--exclude=' + exc)
141   print 'cp -r %s %s' % (src, dst)
142   if os.path.abspath(src) == os.path.abspath(dst):
143     ErrorExit('ERROR: Copying directory onto itself: ' + src)
144   oshelpers.Copy(args)
145
146
147 def CopyFile(src, dst):
148   print 'cp %s %s' % (src, dst)
149   if os.path.abspath(src) == os.path.abspath(dst):
150     ErrorExit('ERROR: Copying file onto itself: ' + src)
151   args = [src, dst]
152   oshelpers.Copy(args)
153
154
155 def RemoveDir(dst):
156   """Remove the provided path."""
157   print 'rm -fr ' + dst
158   oshelpers.Remove(['-fr', dst])
159
160
161 def MakeDir(dst):
162   """Create the path including all parent directories as needed."""
163   print 'mkdir -p ' + dst
164   oshelpers.Mkdir(['-p', dst])
165
166
167 def Move(src, dst):
168   """Move the path src to dst."""
169   print 'mv -f %s %s' % (src, dst)
170   oshelpers.Move(['-f', src, dst])
171
172
173 def RemoveFile(dst):
174   """Remove the provided file."""
175   print 'rm ' + dst
176   oshelpers.Remove(['-f', dst])
177
178
179 BOT_GSUTIL = '/b/build/scripts/slave/gsutil'
180 # On Windows, the current working directory may be on a different drive than
181 # gsutil.
182 WIN_BOT_GSUTIL = 'E:' + BOT_GSUTIL
183 LOCAL_GSUTIL = 'gsutil'
184
185
186 def GetGsutil():
187   if os.environ.get('BUILDBOT_BUILDERNAME') \
188      and not os.environ.get('BUILDBOT_FAKE'):
189     if getos.GetPlatform() == 'win':
190       return WIN_BOT_GSUTIL
191     return BOT_GSUTIL
192   else:
193     return LOCAL_GSUTIL
194
195
196 def Archive(filename, bucket_path, cwd=None, step_link=True):
197   """Upload the given filename to Google Store."""
198   full_dst = 'gs://%s/%s' % (bucket_path, filename)
199
200   # Since GetGsutil() might just return 'gsutil' and expect it to be looked
201   # up in the PATH, we must pass shell=True on windows.
202   # Without shell=True the windows implementation of subprocess.call will not
203   # search the PATH for the executable: http://bugs.python.org/issue8557
204   shell = getos.GetPlatform() == 'win'
205
206   cmd = [GetGsutil(), 'cp', '-a', 'public-read', filename, full_dst]
207   Run(cmd, shell=shell, cwd=cwd)
208   url = 'https://commondatastorage.googleapis.com/'\
209         '%s/%s' % (bucket_path, filename)
210   if step_link:
211     print '@@@STEP_LINK@download@%s@@@' % url
212     sys.stdout.flush()