| 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 |
| 11 import tempfile | 11 import tempfile |
| 12 import time | 12 import time |
| 13 import urlparse | 13 import urlparse |
| 14 | 14 |
| 15 from naclports import binary_package | 15 from naclports import binary_package |
| 16 from naclports import configuration | 16 from naclports import configuration |
| 17 from naclports import package | 17 from naclports import package |
| 18 from naclports import package_index | 18 from naclports import package_index |
| 19 from naclports import util | 19 from naclports import util |
| 20 from naclports import paths | 20 from naclports import paths |
| 21 from naclports.util import Log, Trace | 21 from naclports.util import Log, LogVerbose |
| 22 from naclports.error import Error, DisabledError, PkgFormatError | 22 from naclports.error import Error, DisabledError, PkgFormatError |
| 23 | 23 |
| 24 | 24 |
| 25 class PkgConflictError(Error): | 25 class PkgConflictError(Error): |
| 26 pass | 26 pass |
| 27 | 27 |
| 28 | 28 |
| 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.""" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 | 67 |
| 68 | 68 |
| 69 def ExtractArchive(archive, destination): | 69 def ExtractArchive(archive, destination): |
| 70 ext = os.path.splitext(archive)[1] | 70 ext = os.path.splitext(archive)[1] |
| 71 if ext in ('.gz', '.tgz', '.bz2', '.xz'): | 71 if ext in ('.gz', '.tgz', '.bz2', '.xz'): |
| 72 cmd = ['tar', 'xf', archive, '-C', destination] | 72 cmd = ['tar', 'xf', archive, '-C', destination] |
| 73 elif ext in ('.zip',): | 73 elif ext in ('.zip',): |
| 74 cmd = ['unzip', '-q', '-d', destination, archive] | 74 cmd = ['unzip', '-q', '-d', destination, archive] |
| 75 else: | 75 else: |
| 76 raise Error('unhandled extension: %s' % ext) | 76 raise Error('unhandled extension: %s' % ext) |
| 77 Trace(cmd) | 77 LogVerbose(cmd) |
| 78 subprocess.check_call(cmd) | 78 subprocess.check_call(cmd) |
| 79 | 79 |
| 80 | 80 |
| 81 def RunGitCmd(directory, cmd, error_ok=False): | 81 def RunGitCmd(directory, cmd, error_ok=False): |
| 82 cmd = ['git'] + cmd | 82 cmd = ['git'] + cmd |
| 83 Trace('%s' % ' '.join(cmd)) | 83 LogVerbose('%s' % ' '.join(cmd)) |
| 84 p = subprocess.Popen(cmd, | 84 p = subprocess.Popen(cmd, |
| 85 cwd=directory, | 85 cwd=directory, |
| 86 stderr=subprocess.PIPE, | 86 stderr=subprocess.PIPE, |
| 87 stdout=subprocess.PIPE) | 87 stdout=subprocess.PIPE) |
| 88 stdout, stderr = p.communicate() | 88 stdout, stderr = p.communicate() |
| 89 if not error_ok and p.returncode != 0: | 89 if not error_ok and p.returncode != 0: |
| 90 if stdout: | 90 if stdout: |
| 91 Log(stdout) | 91 Log(stdout) |
| 92 if stderr: | 92 if stderr: |
| 93 Log(stderr) | 93 Log(stderr) |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 | 275 |
| 276 if not force and self.IsBuilt(): | 276 if not force and self.IsBuilt(): |
| 277 self.LogStatus('Already built') | 277 self.LogStatus('Already built') |
| 278 return | 278 return |
| 279 | 279 |
| 280 log_root = os.path.join(paths.OUT_DIR, 'logs') | 280 log_root = os.path.join(paths.OUT_DIR, 'logs') |
| 281 util.Makedirs(log_root) | 281 util.Makedirs(log_root) |
| 282 | 282 |
| 283 self.LogStatus('Building') | 283 self.LogStatus('Building') |
| 284 | 284 |
| 285 if util.verbose: | 285 if util.log_level > util.LOG_MESSAGE: |
| 286 log_filename = None | 286 log_filename = None |
| 287 else: | 287 else: |
| 288 log_filename = os.path.join(log_root, '%s_%s.log' % (self.NAME, | 288 log_filename = os.path.join(log_root, '%s_%s.log' % (self.NAME, |
| 289 str(self.config).replace('/', '_'))) | 289 str(self.config).replace('/', '_'))) |
| 290 if os.path.exists(log_filename): | 290 if os.path.exists(log_filename): |
| 291 os.remove(log_filename) | 291 os.remove(log_filename) |
| 292 | 292 |
| 293 start = time.time() | 293 start = time.time() |
| 294 with util.BuildLock(): | 294 with util.BuildLock(): |
| 295 try: | 295 try: |
| 296 with RedirectStdoutStderr(log_filename): | 296 with RedirectStdoutStderr(log_filename): |
| 297 old_verbose = util.verbose | 297 old_log_level = util.log_level |
| 298 util.log_level = util.LOG_VERBOSE |
| 298 try: | 299 try: |
| 299 util.verbose = True | |
| 300 self.Download() | 300 self.Download() |
| 301 self.Extract() | 301 self.Extract() |
| 302 self.Patch() | 302 self.Patch() |
| 303 self.RunBuildSh() | 303 self.RunBuildSh() |
| 304 finally: | 304 finally: |
| 305 util.verbose = old_verbose | 305 util.log_level = old_log_level |
| 306 except: | 306 except: |
| 307 if log_filename: | 307 if log_filename: |
| 308 with open(log_filename) as log_file: | 308 with open(log_filename) as log_file: |
| 309 sys.stdout.write(log_file.read()) | 309 sys.stdout.write(log_file.read()) |
| 310 raise | 310 raise |
| 311 | 311 |
| 312 duration = FormatTimeDelta(time.time() - start) | 312 duration = FormatTimeDelta(time.time() - start) |
| 313 util.LogHeading('Build complete', ' [took %s]' % duration) | 313 util.LogHeading('Build complete', ' [took %s]' % duration) |
| 314 | 314 |
| 315 def RunBuildSh(self): | 315 def RunBuildSh(self): |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 "Please remove existing checkout and try again: '%s'" % dest) | 390 "Please remove existing checkout and try again: '%s'" % dest) |
| 391 | 391 |
| 392 util.LogHeading('Extracting') | 392 util.LogHeading('Extracting') |
| 393 util.Makedirs(paths.OUT_DIR) | 393 util.Makedirs(paths.OUT_DIR) |
| 394 tmp_output_path = tempfile.mkdtemp(dir=paths.OUT_DIR) | 394 tmp_output_path = tempfile.mkdtemp(dir=paths.OUT_DIR) |
| 395 try: | 395 try: |
| 396 ExtractArchive(archive, tmp_output_path) | 396 ExtractArchive(archive, tmp_output_path) |
| 397 src = os.path.join(tmp_output_path, new_foldername) | 397 src = os.path.join(tmp_output_path, new_foldername) |
| 398 if not os.path.isdir(src): | 398 if not os.path.isdir(src): |
| 399 raise Error('Archive contents not found: %s' % src) | 399 raise Error('Archive contents not found: %s' % src) |
| 400 Trace("renaming '%s' -> '%s'" % (src, dest)) | 400 LogVerbose("renaming '%s' -> '%s'" % (src, dest)) |
| 401 os.rename(src, dest) | 401 os.rename(src, dest) |
| 402 finally: | 402 finally: |
| 403 shutil.rmtree(tmp_output_path) | 403 shutil.rmtree(tmp_output_path) |
| 404 | 404 |
| 405 self.RemoveStamps() | 405 self.RemoveStamps() |
| 406 WriteStamp(stamp_file, stamp_contents) | 406 WriteStamp(stamp_file, stamp_contents) |
| 407 | 407 |
| 408 def RunCmd(self, cmd, **args): | 408 def RunCmd(self, cmd, **args): |
| 409 try: | 409 try: |
| 410 subprocess.check_call(cmd, | 410 subprocess.check_call(cmd, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 426 | 426 |
| 427 def Patch(self): | 427 def Patch(self): |
| 428 stamp_file = os.path.join(self.GetStampDir(), 'nacl_patch') | 428 stamp_file = os.path.join(self.GetStampDir(), 'nacl_patch') |
| 429 src_dir = self.GetBuildLocation() | 429 src_dir = self.GetBuildLocation() |
| 430 if self.URL is None: | 430 if self.URL is None: |
| 431 return | 431 return |
| 432 | 432 |
| 433 if os.path.exists(stamp_file): | 433 if os.path.exists(stamp_file): |
| 434 self.Log('Skipping patch step (cleaning source tree)') | 434 self.Log('Skipping patch step (cleaning source tree)') |
| 435 cmd = ['git', 'clean', '-f', '-d'] | 435 cmd = ['git', 'clean', '-f', '-d'] |
| 436 if not util.verbose: | 436 if not util.log_level > util.LOG_MESSAGE: |
| 437 cmd.append('-q') | 437 cmd.append('-q') |
| 438 self.RunCmd(cmd) | 438 self.RunCmd(cmd) |
| 439 return | 439 return |
| 440 | 440 |
| 441 util.LogHeading('Patching') | 441 util.LogHeading('Patching') |
| 442 Log('Init git repo: %s' % src_dir) | 442 Log('Init git repo: %s' % src_dir) |
| 443 try: | 443 try: |
| 444 InitGitRepo(src_dir) | 444 InitGitRepo(src_dir) |
| 445 except subprocess.CalledProcessError as e: | 445 except subprocess.CalledProcessError as e: |
| 446 raise Error(e) | 446 raise Error(e) |
| 447 if os.path.exists(self.GetPatchFile()): | 447 if os.path.exists(self.GetPatchFile()): |
| 448 Trace('applying patch to: %s' % src_dir) | 448 LogVerbose('applying patch to: %s' % src_dir) |
| 449 cmd = ['patch', '-p1', '-g0', '--no-backup-if-mismatch'] | 449 cmd = ['patch', '-p1', '-g0', '--no-backup-if-mismatch'] |
| 450 with open(self.GetPatchFile()) as f: | 450 with open(self.GetPatchFile()) as f: |
| 451 self.RunCmd(cmd, stdin=f) | 451 self.RunCmd(cmd, stdin=f) |
| 452 self.RunCmd(['git', 'add', '.']) | 452 self.RunCmd(['git', 'add', '.']) |
| 453 self.RunCmd(['git', 'commit', '-m', 'Apply naclports patch']) | 453 self.RunCmd(['git', 'commit', '-m', 'Apply naclports patch']) |
| 454 | 454 |
| 455 WriteStamp(stamp_file, '') | 455 WriteStamp(stamp_file, '') |
| 456 | 456 |
| 457 def GetExtractStamp(self): | 457 def GetExtractStamp(self): |
| 458 return os.path.join(self.GetStampDir(), 'extract') | 458 return os.path.join(self.GetStampDir(), 'extract') |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 if os.path.isdir(package_name): | 703 if os.path.isdir(package_name): |
| 704 return SourcePackage(package_name, config) | 704 return SourcePackage(package_name, config) |
| 705 | 705 |
| 706 for subdir in DEFAULT_LOCATIONS: | 706 for subdir in DEFAULT_LOCATIONS: |
| 707 pkg_root = os.path.join(paths.NACLPORTS_ROOT, subdir, package_name) | 707 pkg_root = os.path.join(paths.NACLPORTS_ROOT, subdir, package_name) |
| 708 info = os.path.join(pkg_root, 'pkg_info') | 708 info = os.path.join(pkg_root, 'pkg_info') |
| 709 if os.path.exists(info): | 709 if os.path.exists(info): |
| 710 return SourcePackage(pkg_root, config) | 710 return SourcePackage(pkg_root, config) |
| 711 | 711 |
| 712 raise Error("Package not found: %s" % package_name) | 712 raise Error("Package not found: %s" % package_name) |
| OLD | NEW |