Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2014 The Native Client Authors. All rights reserved. | 1 # Copyright (c) 2014 The Native Client Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import contextlib | 5 import contextlib |
| 6 import os | 6 import os |
| 7 import re | 7 import re |
| 8 import shutil | 8 import shutil |
| 9 import subprocess | 9 import subprocess |
| 10 import sys | 10 import sys |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 @contextlib.contextmanager | 29 @contextlib.contextmanager |
| 30 def RedirectStdoutStderr(filename): | 30 def RedirectStdoutStderr(filename): |
| 31 """Context manager that replaces stdout and stderr streams.""" | 31 """Context manager that replaces stdout and stderr streams.""" |
| 32 if filename is None: | 32 if filename is None: |
| 33 yield | 33 yield |
| 34 return | 34 return |
| 35 | 35 |
| 36 with open(filename, 'a') as stream: | 36 with open(filename, 'a') as stream: |
| 37 sys.stdout = stream | 37 sys.stdout = stream |
| 38 sys.stderr = stream | 38 sys.stderr = stream |
| 39 util.CheckForColorSupport() | |
|
binji
2015/01/09 18:24:59
hmm... maybe CheckForColorSupport should be rename
Sam Clegg
2015/01/09 22:14:54
Done.
| |
| 39 try: | 40 try: |
| 40 yield | 41 yield |
| 41 finally: | 42 finally: |
| 42 sys.stdout = sys.__stdout__ | 43 sys.stdout = sys.__stdout__ |
| 43 sys.stderr = sys.__stdout__ | 44 sys.stderr = sys.__stdout__ |
| 45 util.CheckForColorSupport() | |
| 44 | 46 |
| 45 | 47 |
| 46 def FormatTimeDelta(delta): | 48 def FormatTimeDelta(delta): |
| 47 """Converts a duration in seconds to a human readable string. | 49 """Converts a duration in seconds to a human readable string. |
| 48 | 50 |
| 49 Args: | 51 Args: |
| 50 delta: the amount of time in seconds. | 52 delta: the amount of time in seconds. |
| 51 | 53 |
| 52 Returns: A string desribing the ammount of time passed in. | 54 Returns: A string desribing the ammount of time passed in. |
| 53 """ | 55 """ |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 index = package_index.GetCurrentIndex() | 249 index = package_index.GetCurrentIndex() |
| 248 if index.Installable(self.NAME, self.config): | 250 if index.Installable(self.NAME, self.config): |
| 249 package_file = index.Download(self.NAME, self.config) | 251 package_file = index.Download(self.NAME, self.config) |
| 250 else: | 252 else: |
| 251 from_source = True | 253 from_source = True |
| 252 | 254 |
| 253 if from_source: | 255 if from_source: |
| 254 self.Build(build_deps, force) | 256 self.Build(build_deps, force) |
| 255 | 257 |
| 256 if self.IsAnyVersionInstalled(): | 258 if self.IsAnyVersionInstalled(): |
| 257 Log('Uninstalling existing %s' % self.InfoString()) | 259 self.LogStatus('Uninstalling existing') |
| 258 self.GetInstalledPackage().DoUninstall() | 260 self.GetInstalledPackage().DoUninstall() |
| 259 | 261 |
| 260 binary_package.BinaryPackage(package_file).Install() | 262 binary_package.BinaryPackage(package_file).Install() |
| 261 | 263 |
| 262 def GetInstalledPackage(self): | 264 def GetInstalledPackage(self): |
| 263 return package.CreateInstalledPackage(self.NAME, self.config) | 265 return package.CreateInstalledPackage(self.NAME, self.config) |
| 264 | 266 |
| 265 def Build(self, build_deps, force=None): | 267 def Build(self, build_deps, force=None): |
| 266 self.CheckBuildable() | 268 self.CheckBuildable() |
| 267 | 269 |
| 268 if build_deps: | 270 if build_deps: |
| 269 self.InstallDeps(force) | 271 self.InstallDeps(force) |
| 270 | 272 |
| 271 if not force and self.IsBuilt(): | 273 if not force and self.IsBuilt(): |
| 272 Log('Already built %s' % self.InfoString()) | 274 self.LogStatus('Already built') |
| 273 return | 275 return |
| 274 | 276 |
| 275 log_root = os.path.join(paths.OUT_DIR, 'logs') | 277 log_root = os.path.join(paths.OUT_DIR, 'logs') |
| 276 util.Makedirs(log_root) | 278 util.Makedirs(log_root) |
| 277 | 279 |
| 278 if util.verbose: | 280 self.LogStatus('Building') |
| 279 prefix = '*** ' | |
| 280 else: | |
| 281 prefix = '' | |
| 282 Log('%sBuilding %s' % (prefix, self.InfoString())) | |
| 283 | 281 |
| 284 if util.verbose: | 282 if util.verbose: |
| 285 log_filename = None | 283 log_filename = None |
| 286 else: | 284 else: |
| 287 log_filename = os.path.join(log_root, '%s_%s.log' % (self.NAME, | 285 log_filename = os.path.join(log_root, '%s_%s.log' % (self.NAME, |
| 288 str(self.config).replace('/', '_'))) | 286 str(self.config).replace('/', '_'))) |
| 289 if os.path.exists(log_filename): | 287 if os.path.exists(log_filename): |
| 290 os.remove(log_filename) | 288 os.remove(log_filename) |
| 291 | 289 |
| 292 start = time.time() | 290 start = time.time() |
| 293 with util.BuildLock(): | 291 with util.BuildLock(): |
| 294 with RedirectStdoutStderr(log_filename): | 292 with RedirectStdoutStderr(log_filename): |
| 295 old_verbose = util.verbose | 293 old_verbose = util.verbose |
| 296 try: | 294 try: |
| 297 util.verbose = True | 295 util.verbose = True |
| 298 self.Download() | 296 self.Download() |
| 299 self.Extract() | 297 self.Extract() |
| 300 self.Patch() | 298 self.Patch() |
| 301 self.RunBuildSh() | 299 self.RunBuildSh() |
| 302 finally: | 300 finally: |
| 303 util.verbose = old_verbose | 301 util.verbose = old_verbose |
| 304 | 302 |
| 305 duration = FormatTimeDelta(time.time() - start) | 303 duration = FormatTimeDelta(time.time() - start) |
| 306 Log('Build complete %s [took %s]' % (self.InfoString(), duration)) | 304 util.LogHeading('Build complete', ' [took %s]' % duration) |
| 307 | 305 |
| 308 def RunBuildSh(self): | 306 def RunBuildSh(self): |
| 309 build_port = os.path.join(paths.TOOLS_DIR, 'build_port.sh') | 307 build_port = os.path.join(paths.TOOLS_DIR, 'build_port.sh') |
| 310 cmd = [build_port] | 308 cmd = [build_port] |
| 311 | 309 |
| 312 env = os.environ.copy() | 310 env = os.environ.copy() |
| 313 env['TOOLCHAIN'] = self.config.toolchain | 311 env['TOOLCHAIN'] = self.config.toolchain |
| 314 env['NACL_ARCH'] = self.config.arch | 312 env['NACL_ARCH'] = self.config.arch |
| 315 env['NACL_DEBUG'] = self.config.debug and '1' or '0' | 313 env['NACL_DEBUG'] = self.config.debug and '1' or '0' |
| 316 rtn = subprocess.call(cmd, | 314 rtn = subprocess.call(cmd, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 stamp_file = self.GetExtractStamp() | 372 stamp_file = self.GetExtractStamp() |
| 375 stamp_contents = self.GetExtractStampContent() | 373 stamp_contents = self.GetExtractStampContent() |
| 376 if os.path.exists(dest): | 374 if os.path.exists(dest): |
| 377 if StampContentsMatch(stamp_file, stamp_contents): | 375 if StampContentsMatch(stamp_file, stamp_contents): |
| 378 Log('Already up-to-date: %s' % util.RelPath(dest)) | 376 Log('Already up-to-date: %s' % util.RelPath(dest)) |
| 379 return | 377 return |
| 380 | 378 |
| 381 raise Error("Upstream archive or patch has changed.\n" + | 379 raise Error("Upstream archive or patch has changed.\n" + |
| 382 "Please remove existing checkout and try again: '%s'" % dest) | 380 "Please remove existing checkout and try again: '%s'" % dest) |
| 383 | 381 |
| 384 self.Banner('Extracting') | 382 util.LogHeading('Extracting') |
| 385 util.Makedirs(paths.OUT_DIR) | 383 util.Makedirs(paths.OUT_DIR) |
| 386 tmp_output_path = tempfile.mkdtemp(dir=paths.OUT_DIR) | 384 tmp_output_path = tempfile.mkdtemp(dir=paths.OUT_DIR) |
| 387 try: | 385 try: |
| 388 ExtractArchive(archive, tmp_output_path) | 386 ExtractArchive(archive, tmp_output_path) |
| 389 src = os.path.join(tmp_output_path, new_foldername) | 387 src = os.path.join(tmp_output_path, new_foldername) |
| 390 if not os.path.isdir(src): | 388 if not os.path.isdir(src): |
| 391 raise Error('Archive contents not found: %s' % src) | 389 raise Error('Archive contents not found: %s' % src) |
| 392 Trace("renaming '%s' -> '%s'" % (src, dest)) | 390 Trace("renaming '%s' -> '%s'" % (src, dest)) |
| 393 os.rename(src, dest) | 391 os.rename(src, dest) |
| 394 finally: | 392 finally: |
| 395 shutil.rmtree(tmp_output_path) | 393 shutil.rmtree(tmp_output_path) |
| 396 | 394 |
| 397 self.RemoveStamps() | 395 self.RemoveStamps() |
| 398 WriteStamp(stamp_file, stamp_contents) | 396 WriteStamp(stamp_file, stamp_contents) |
| 399 | 397 |
| 400 def RunCmd(self, cmd, **args): | 398 def RunCmd(self, cmd, **args): |
| 401 try: | 399 try: |
| 402 subprocess.check_call(cmd, | 400 subprocess.check_call(cmd, |
| 403 stdout=sys.stdout, | 401 stdout=sys.stdout, |
| 404 stderr=sys.stderr, | 402 stderr=sys.stderr, |
| 405 cwd=self.GetBuildLocation(), | 403 cwd=self.GetBuildLocation(), |
| 406 **args) | 404 **args) |
| 407 except subprocess.CalledProcessError as e: | 405 except subprocess.CalledProcessError as e: |
| 408 raise Error(e) | 406 raise Error(e) |
| 409 | 407 |
| 410 def Log(self, message): | 408 def Log(self, message): |
| 411 Log('%s: %s' % (message, self.InfoString())) | 409 Log('%s: %s' % (message, self.InfoString())) |
| 412 | 410 |
| 413 def Banner(self, message): | |
| 414 Log("#####################################################################") | |
| 415 self.Log(message) | |
| 416 Log("#####################################################################") | |
| 417 | |
| 418 def GetStampDir(self): | 411 def GetStampDir(self): |
| 419 return os.path.join(paths.STAMP_DIR, self.NAME) | 412 return os.path.join(paths.STAMP_DIR, self.NAME) |
| 420 | 413 |
| 421 def RemoveStamps(self): | 414 def RemoveStamps(self): |
| 422 util.RemoveTree(self.GetStampDir()) | 415 util.RemoveTree(self.GetStampDir()) |
| 423 | 416 |
| 424 def Patch(self): | 417 def Patch(self): |
| 425 stamp_file = os.path.join(self.GetStampDir(), 'nacl_patch') | 418 stamp_file = os.path.join(self.GetStampDir(), 'nacl_patch') |
| 426 src_dir = self.GetBuildLocation() | 419 src_dir = self.GetBuildLocation() |
| 427 if self.URL is None: | 420 if self.URL is None: |
| 428 return | 421 return |
| 429 | 422 |
| 430 if os.path.exists(stamp_file): | 423 if os.path.exists(stamp_file): |
| 431 self.Log('Skipping patch step (cleaning source tree)') | 424 self.Log('Skipping patch step (cleaning source tree)') |
| 432 cmd = ['git', 'clean', '-f', '-d'] | 425 cmd = ['git', 'clean', '-f', '-d'] |
| 433 if not util.verbose: | 426 if not util.verbose: |
| 434 cmd.append('-q') | 427 cmd.append('-q') |
| 435 self.RunCmd(cmd) | 428 self.RunCmd(cmd) |
| 436 return | 429 return |
| 437 | 430 |
| 438 self.Banner('Patching') | 431 util.LogHeading('Patching') |
| 439 Log('Init git repo: %s' % src_dir) | 432 Log('Init git repo: %s' % src_dir) |
| 440 try: | 433 try: |
| 441 InitGitRepo(src_dir) | 434 InitGitRepo(src_dir) |
| 442 except subprocess.CalledProcessError as e: | 435 except subprocess.CalledProcessError as e: |
| 443 raise Error(e) | 436 raise Error(e) |
| 444 if os.path.exists(self.GetPatchFile()): | 437 if os.path.exists(self.GetPatchFile()): |
| 445 Trace('applying patch to: %s' % src_dir) | 438 Trace('applying patch to: %s' % src_dir) |
| 446 cmd = ['patch', '-p1', '-g0', '--no-backup-if-mismatch'] | 439 cmd = ['patch', '-p1', '-g0', '--no-backup-if-mismatch'] |
| 447 with open(self.GetPatchFile()) as f: | 440 with open(self.GetPatchFile()) as f: |
| 448 self.RunCmd(cmd, stdin=f) | 441 self.RunCmd(cmd, stdin=f) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 564 stamp_content += '\n' | 557 stamp_content += '\n' |
| 565 | 558 |
| 566 dest = self.GetBuildLocation() | 559 dest = self.GetBuildLocation() |
| 567 if os.path.exists(self.GetBuildLocation()): | 560 if os.path.exists(self.GetBuildLocation()): |
| 568 if StampContentsMatch(stamp_file, stamp_content): | 561 if StampContentsMatch(stamp_file, stamp_content): |
| 569 return | 562 return |
| 570 | 563 |
| 571 raise Error('Upstream archive or patch has changed.\n' + | 564 raise Error('Upstream archive or patch has changed.\n' + |
| 572 "Please remove existing checkout and try again: '%s'" % dest) | 565 "Please remove existing checkout and try again: '%s'" % dest) |
| 573 | 566 |
| 574 self.Banner('Cloning') | 567 util.LogHeading('Cloning') |
| 575 # Ensure local mirror is up-to-date | 568 # Ensure local mirror is up-to-date |
| 576 git_mirror, git_commit = self.GitCloneToMirror() | 569 git_mirror, git_commit = self.GitCloneToMirror() |
| 577 # Clone from the local mirror. | 570 # Clone from the local mirror. |
| 578 RunGitCmd(None, ['clone', git_mirror, dest]) | 571 RunGitCmd(None, ['clone', git_mirror, dest]) |
| 579 RunGitCmd(dest, ['reset', '--hard', git_commit]) | 572 RunGitCmd(dest, ['reset', '--hard', git_commit]) |
| 580 | 573 |
| 581 # Set the origing to the original URL so it is possible to push directly | 574 # Set the origing to the original URL so it is possible to push directly |
| 582 # from the build tree. | 575 # from the build tree. |
| 583 RunGitCmd(dest, ['remote', 'set-url', 'origin', '${GIT_URL}']) | 576 RunGitCmd(dest, ['remote', 'set-url', 'origin', '${GIT_URL}']) |
| 584 | 577 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 692 if os.path.isdir(package_name): | 685 if os.path.isdir(package_name): |
| 693 return SourcePackage(package_name, config) | 686 return SourcePackage(package_name, config) |
| 694 | 687 |
| 695 for subdir in DEFAULT_LOCATIONS: | 688 for subdir in DEFAULT_LOCATIONS: |
| 696 pkg_root = os.path.join(paths.NACLPORTS_ROOT, subdir, package_name) | 689 pkg_root = os.path.join(paths.NACLPORTS_ROOT, subdir, package_name) |
| 697 info = os.path.join(pkg_root, 'pkg_info') | 690 info = os.path.join(pkg_root, 'pkg_info') |
| 698 if os.path.exists(info): | 691 if os.path.exists(info): |
| 699 return SourcePackage(pkg_root, config) | 692 return SourcePackage(pkg_root, config) |
| 700 | 693 |
| 701 raise Error("Package not found: %s" % package_name) | 694 raise Error("Package not found: %s" % package_name) |
| OLD | NEW |