| #!/usr/bin/env python3 | |
| # Copyright 2013 The Flutter Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """Emulation of `rm -f out && cp -af` in out. This is necessary on Mac in order | |
| to preserve nanoseconds of mtime. See https://fxbug.dev/56376#c5.""" | |
| import os | |
| import shutil | |
| import sys | |
| def main(): | |
| if len(sys.argv) != 3: | |
| print('usage: copy.py source dest', file=sys.stderr) | |
| return 1 | |
| source = sys.argv[1] | |
| dest = sys.argv[2] | |
| if os.path.isdir(source): | |
| print( | |
| f'{source} is a directory, tool "copy" does not support directory copies' | |
| ) | |
| return 1 | |
| if os.path.exists(dest): | |
| if os.path.isdir(dest): | |
| def _on_error(fn, path, dummy_excinfo): | |
| # The operation failed, possibly because the file is set to | |
| # read-only. If that's why, make it writable and try the op | |
| # again. | |
| if not os.access(path, os.W_OK): | |
| os.chmod(path, stat.S_IWRITE) | |
| fn(path) | |
| shutil.rmtree(dest, onerror=_on_error) | |
| else: | |
| if not os.access(dest, os.W_OK): | |
| # Attempt to make the file writable before deleting it. | |
| os.chmod(dest, stat.S_IWRITE) | |
| os.unlink(dest) | |
| shutil.copy2(source, dest) | |
| if __name__ == '__main__': | |
| main() |