diff options
-rw-r--r-- | support/lib/util.py | 21 | ||||
-rw-r--r-- | support/openscad/__main__.py | 2 |
2 files changed, 21 insertions, 2 deletions
diff --git a/support/lib/util.py b/support/lib/util.py index f6d8f8a..3a852f4 100644 --- a/support/lib/util.py +++ b/support/lib/util.py @@ -5,6 +5,25 @@ class UserError(Exception): pass +def rename_atomic(source_path, target_path): + """ + Move the file at source_path to target_path. + + If both paths reside on the same device, os.rename() is used, otherwise the file is copied to a temporary name next to target_path and moved from there using os.rename(). + """ + + source_dir_stat = os.stat(os.path.dirname(source_path)) + target_dir_stat = os.stat(os.path.dirname(target_path)) + + if source_dir_stat.st_dev == target_dir_stat.st_dev: + os.rename(source_path, target_path) + else: + temp_path = target_path + '~' + + shutil.copyfile(source_path, temp_path) + os.rename(temp_path, target_path) + + @contextlib.contextmanager def TemporaryDirectory(): dir = tempfile.mkdtemp() @@ -32,7 +51,7 @@ def command(args, remove_env = [], set_env = { }): def bash_escape_string(string): - return "'{}'".format(re.sub("'", "'\"'\"'", string)) + return "'{}'".format(re.sub("'", "'\"'\"'", string)) def write_file(path, data): diff --git a/support/openscad/__main__.py b/support/openscad/__main__.py index 2042a65..28de2cf 100644 --- a/support/openscad/__main__.py +++ b/support/openscad/__main__.py @@ -42,7 +42,7 @@ def main(in_path, out_path, deps_path): # Write output files. _write_dependencies(deps_path, relpath(out_path), deps - ignored_files) - os.rename(temp_out_path, out_path) + util.rename_atomic(temp_out_path, out_path) try: |