Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. 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 from __future__ import with_statement | 5 from __future__ import with_statement |
| 6 | 6 |
| 7 import collections | 7 import collections |
| 8 import errno | 8 import errno |
| 9 import filecmp | 9 import filecmp |
| 10 import os.path | 10 import os.path |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 | 338 |
| 339 class Writer(object): | 339 class Writer(object): |
| 340 """Wrapper around file which only covers the target if it differs.""" | 340 """Wrapper around file which only covers the target if it differs.""" |
| 341 def __init__(self): | 341 def __init__(self): |
| 342 # Pick temporary file. | 342 # Pick temporary file. |
| 343 tmp_fd, self.tmp_path = tempfile.mkstemp( | 343 tmp_fd, self.tmp_path = tempfile.mkstemp( |
| 344 suffix='.tmp', | 344 suffix='.tmp', |
| 345 prefix=os.path.split(filename)[1] + '.gyp.', | 345 prefix=os.path.split(filename)[1] + '.gyp.', |
| 346 dir=os.path.split(filename)[0]) | 346 dir=os.path.split(filename)[0]) |
| 347 try: | 347 try: |
| 348 self.tmp_file = os.fdopen(tmp_fd, 'wb') | 348 self.tmp_file = os.fdopen(tmp_fd, 'w') |
|
Nico
2016/07/29 22:22:06
doesn't this change behavior on windows?
AWhetter
2016/11/05 23:59:49
Yes but we only ever write text so I think we shou
| |
| 349 except Exception: | 349 except Exception: |
| 350 # Don't leave turds behind. | 350 # Don't leave turds behind. |
| 351 os.unlink(self.tmp_path) | 351 os.unlink(self.tmp_path) |
| 352 raise | 352 raise |
| 353 | 353 |
| 354 def __getattr__(self, attrname): | 354 def __getattr__(self, attrname): |
| 355 # Delegate everything else to self.tmp_file | 355 # Delegate everything else to self.tmp_file |
| 356 return getattr(self.tmp_file, attrname) | 356 return getattr(self.tmp_file, attrname) |
| 357 | 357 |
| 358 def close(self): | 358 def close(self): |
| 359 try: | 359 try: |
| 360 # Close tmp file. | 360 # Close tmp file. |
| 361 self.tmp_file.close() | 361 self.tmp_file.close() |
| 362 # Determine if different. | 362 # Determine if different. |
| 363 same = False | 363 same = False |
| 364 try: | 364 try: |
| 365 same = filecmp.cmp(self.tmp_path, filename, False) | 365 same = filecmp.cmp(self.tmp_path, filename, False) |
| 366 except OSError, e: | 366 except OSError as e: |
| 367 if e.errno != errno.ENOENT: | 367 if e.errno != errno.ENOENT: |
| 368 raise | 368 raise |
| 369 | 369 |
| 370 if same: | 370 if same: |
| 371 # The new file is identical to the old one, just get rid of the new | 371 # The new file is identical to the old one, just get rid of the new |
| 372 # one. | 372 # one. |
| 373 os.unlink(self.tmp_path) | 373 os.unlink(self.tmp_path) |
| 374 else: | 374 else: |
| 375 # The new file is different from the old one, or there is no old one. | 375 # The new file is different from the old one, or there is no old one. |
| 376 # Rename the new file to the permanent name. | 376 # Rename the new file to the permanent name. |
| 377 # | 377 # |
| 378 # tempfile.mkstemp uses an overly restrictive mode, resulting in a | 378 # tempfile.mkstemp uses an overly restrictive mode, resulting in a |
| 379 # file that can only be read by the owner, regardless of the umask. | 379 # file that can only be read by the owner, regardless of the umask. |
| 380 # There's no reason to not respect the umask here, which means that | 380 # There's no reason to not respect the umask here, which means that |
| 381 # an extra hoop is required to fetch it and reset the new file's mode. | 381 # an extra hoop is required to fetch it and reset the new file's mode. |
| 382 # | 382 # |
| 383 # No way to get the umask without setting a new one? Set a safe one | 383 # No way to get the umask without setting a new one? Set a safe one |
| 384 # and then set it back to the old value. | 384 # and then set it back to the old value. |
| 385 umask = os.umask(077) | 385 umask = os.umask(0o77) |
| 386 os.umask(umask) | 386 os.umask(umask) |
| 387 os.chmod(self.tmp_path, 0666 & ~umask) | 387 os.chmod(self.tmp_path, 0o666 & ~umask) |
| 388 if sys.platform == 'win32' and os.path.exists(filename): | 388 if sys.platform == 'win32' and os.path.exists(filename): |
| 389 # NOTE: on windows (but not cygwin) rename will not replace an | 389 # NOTE: on windows (but not cygwin) rename will not replace an |
| 390 # existing file, so it must be preceded with a remove. Sadly there | 390 # existing file, so it must be preceded with a remove. Sadly there |
| 391 # is no way to make the switch atomic. | 391 # is no way to make the switch atomic. |
| 392 os.remove(filename) | 392 os.remove(filename) |
| 393 os.rename(self.tmp_path, filename) | 393 os.rename(self.tmp_path, filename) |
| 394 except Exception: | 394 except Exception: |
| 395 # Don't leave turds behind. | 395 # Don't leave turds behind. |
| 396 os.unlink(self.tmp_path) | 396 os.unlink(self.tmp_path) |
| 397 raise | 397 raise |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 460 header += "import os;\nos.environ['DEVELOPER_DIR']='%s'\n" \ | 460 header += "import os;\nos.environ['DEVELOPER_DIR']='%s'\n" \ |
| 461 % mac_toolchain_dir | 461 % mac_toolchain_dir |
| 462 | 462 |
| 463 # Add header and write it out. | 463 # Add header and write it out. |
| 464 tool_path = os.path.join(out_path, 'gyp-%s-tool' % prefix) | 464 tool_path = os.path.join(out_path, 'gyp-%s-tool' % prefix) |
| 465 with open(tool_path, 'w') as tool_file: | 465 with open(tool_path, 'w') as tool_file: |
| 466 tool_file.write( | 466 tool_file.write( |
| 467 ''.join([source[0], header] + source[1:])) | 467 ''.join([source[0], header] + source[1:])) |
| 468 | 468 |
| 469 # Make file executable. | 469 # Make file executable. |
| 470 os.chmod(tool_path, 0755) | 470 os.chmod(tool_path, 0o755) |
| 471 | 471 |
| 472 | 472 |
| 473 # From Alex Martelli, | 473 # From Alex Martelli, |
| 474 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560 | 474 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560 |
| 475 # ASPN: Python Cookbook: Remove duplicates from a sequence | 475 # ASPN: Python Cookbook: Remove duplicates from a sequence |
| 476 # First comment, dated 2001/10/13. | 476 # First comment, dated 2001/10/13. |
| 477 # (Also in the printed Python Cookbook.) | 477 # (Also in the printed Python Cookbook.) |
| 478 | 478 |
| 479 def uniquer(seq, idfun=None): | 479 def uniquer(seq, idfun=None): |
| 480 if idfun is None: | 480 if idfun is None: |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 def CrossCompileRequested(): | 606 def CrossCompileRequested(): |
| 607 # TODO: figure out how to not build extra host objects in the | 607 # TODO: figure out how to not build extra host objects in the |
| 608 # non-cross-compile case when this is enabled, and enable unconditionally. | 608 # non-cross-compile case when this is enabled, and enable unconditionally. |
| 609 return (os.environ.get('GYP_CROSSCOMPILE') or | 609 return (os.environ.get('GYP_CROSSCOMPILE') or |
| 610 os.environ.get('AR_host') or | 610 os.environ.get('AR_host') or |
| 611 os.environ.get('CC_host') or | 611 os.environ.get('CC_host') or |
| 612 os.environ.get('CXX_host') or | 612 os.environ.get('CXX_host') or |
| 613 os.environ.get('AR_target') or | 613 os.environ.get('AR_target') or |
| 614 os.environ.get('CC_target') or | 614 os.environ.get('CC_target') or |
| 615 os.environ.get('CXX_target')) | 615 os.environ.get('CXX_target')) |
| OLD | NEW |