summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--support/lib/util.py21
-rw-r--r--support/openscad/__main__.py2
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: