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.
5 """Common utilities for all buildbot scripts that specifically don't rely
6 on having a full chromium checkout.
13 from build_paths import SDK_SRC_DIR, NACL_DIR
15 sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
20 """Returns True if this script is running on an SDK builder.
22 False means it is either running on a trybot, or a user's machine.
25 (win|mac|linux)_nacl_sdk
27 Build-only Trybot names:
28 (win|mac|linux)_nacl_sdk_build
31 (windows|mac|linux)-sdk-multi(rel)?"""
32 return '-sdk-multi' in os.getenv('BUILDBOT_BUILDERNAME', '')
36 """Returns True if this script is running on a build-only bot.
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.
42 See IsSDKBuilder above for trybot/buildbot names."""
43 return os.getenv('BUILDBOT_BUILDERNAME', '').endswith('build')
47 """Returns True if this script is running on an SDK trybot.
49 False means it is either running on an SDK builder, or a user's machine.
51 See IsSDKBuilder above for trybot/buildbot names."""
52 return '_nacl_sdk' in os.getenv('BUILDBOT_BUILDERNAME', '')
56 """Write and error to stderr, then exit with 1 signaling failure."""
57 sys.stderr.write(str(msg) + '\n')
61 def GetWindowsEnvironment():
62 sys.path.append(os.path.join(NACL_DIR, 'buildbot'))
63 import buildbot_standard
65 # buildbot_standard.SetupWindowsEnvironment expects a "context" object. We'll
66 # fake enough of that here to work.
67 class FakeContext(object):
71 def GetEnv(self, key):
74 def __getitem__(self, key):
77 def SetEnv(self, key, value):
80 def __setitem__(self, key, value):
83 context = FakeContext()
84 buildbot_standard.SetupWindowsEnvironment(context)
86 # buildbot_standard.SetupWindowsEnvironment adds the directory which contains
87 # vcvarsall.bat to the path, but not the directory which contains cl.exe,
89 # Running vcvarsall.bat adds the correct directories to the path, which we
91 process = subprocess.Popen('vcvarsall.bat x86 > NUL && set',
92 stdout=subprocess.PIPE, env=context.env, shell=True)
93 stdout, _ = process.communicate()
95 # Parse environment from "set" command above.
100 return dict(line.split('=') for line in stdout.split('\r\n')[:-1])
104 """Annotate a buildbot build step."""
106 print '\n@@@BUILD_STEP %s@@@' % name
110 def Run(args, cwd=None, env=None, shell=False):
111 """Start a process with the provided arguments.
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."""
118 # We need to modify the environment to build host on Windows.
119 if not env and getos.GetPlatform() == 'win':
120 env = GetWindowsEnvironment()
122 print 'Running: ' + ' '.join(args)
126 subprocess.check_call(args, cwd=cwd, env=env, shell=shell)
127 except subprocess.CalledProcessError as e:
130 ErrorExit('buildbot_common: %s' % e)
136 def CopyDir(src, dst, excludes=('.svn', '*/.svn')):
137 """Recursively copy a directory using."""
138 args = ['-r', src, dst]
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)
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)
156 """Remove the provided path."""
157 print 'rm -fr ' + dst
158 oshelpers.Remove(['-fr', dst])
162 """Create the path including all parent directories as needed."""
163 print 'mkdir -p ' + dst
164 oshelpers.Mkdir(['-p', dst])
168 """Move the path src to dst."""
169 print 'mv -f %s %s' % (src, dst)
170 oshelpers.Move(['-f', src, dst])
174 """Remove the provided file."""
176 oshelpers.Remove(['-f', dst])
179 BOT_GSUTIL = '/b/build/scripts/slave/gsutil'
180 # On Windows, the current working directory may be on a different drive than
182 WIN_BOT_GSUTIL = 'E:' + BOT_GSUTIL
183 LOCAL_GSUTIL = 'gsutil'
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
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)
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'
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)
211 print '@@@STEP_LINK@download@%s@@@' % url