Skip to content

Commit 352a031

Browse files
feat(core): optimize file copy with reflink/hardlink fallback
Use cp reflink/clonefile, then hardlink, then shutil.copy2 for plain template file copies (CNA parity). Hardlinks stay opt-out via CPA_COPY_HARDLINK=0 and are skipped when allow_hardlink is False. Closes #230 Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 6012c89 commit 352a031

2 files changed

Lines changed: 95 additions & 3 deletions

File tree

packages/create-python-app-core/src/create_python_app_core/loaders.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
from __future__ import annotations
44

5+
import os
56
import shutil
7+
import subprocess
68
from pathlib import Path
7-
from typing import Any
9+
from typing import Any, Literal
810

911
from jinja2 import Environment, StrictUndefined, TemplateError
1012

@@ -18,6 +20,54 @@
1820
autoescape=False,
1921
)
2022

23+
CopyMethod = Literal["reflink", "hardlink", "copy"]
24+
25+
26+
def copy_file_efficient(
27+
src: Path,
28+
dest: Path,
29+
*,
30+
allow_hardlink: bool = True,
31+
) -> CopyMethod:
32+
"""Copy a file using reflink → hardlink → ``shutil.copy2`` (CNA parity).
33+
34+
Hardlinks are skipped when ``allow_hardlink`` is False (e.g. files that will
35+
be mutated by template rendering) or when ``CPA_COPY_HARDLINK=0``.
36+
"""
37+
dest.parent.mkdir(parents=True, exist_ok=True)
38+
if dest.exists():
39+
dest.unlink()
40+
41+
hardlink_ok = allow_hardlink and os.environ.get("CPA_COPY_HARDLINK", "1") != "0"
42+
43+
if os.name != "nt":
44+
# 1) Reflink / clonefile (near-instant CoW on Btrfs/XFS/ZFS/APFS).
45+
for args in (
46+
["cp", "-c", "--", str(src), str(dest)], # macOS clonefile
47+
["cp", "--reflink=auto", "--", str(src), str(dest)], # GNU
48+
):
49+
try:
50+
subprocess.run(args, check=True, capture_output=True)
51+
if dest.is_file():
52+
shutil.copystat(src, dest, follow_symlinks=True)
53+
return "reflink"
54+
except (FileNotFoundError, subprocess.CalledProcessError, OSError):
55+
if dest.exists():
56+
dest.unlink(missing_ok=True)
57+
58+
# 2) Hardlink (same inode — avoided for rendered/mutated files).
59+
if hardlink_ok:
60+
try:
61+
os.link(src, dest)
62+
return "hardlink"
63+
except OSError:
64+
if dest.exists():
65+
dest.unlink(missing_ok=True)
66+
67+
# 3) Full recursive metadata-preserving copy.
68+
shutil.copy2(src, dest)
69+
return "copy"
70+
2171

2272
def _mode_from_path(rel: Path) -> str:
2373
name = rel.name
@@ -104,8 +154,9 @@ def process_file(
104154

105155
if target.exists() and not overwrite:
106156
return None
107-
target.parent.mkdir(parents=True, exist_ok=True)
108-
shutil.copy2(src, target)
157+
# Plain files: reflink → hardlink → copy2. Never hardlink .template
158+
# paths (handled above); allow_hardlink stays True for immutable copies.
159+
copy_file_efficient(src, target, allow_hardlink=True)
109160
return target
110161

111162

packages/create-python-app-core/tests/test_loaders.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,44 @@ def test_process_file_copy(tmp_path: Path) -> None:
7070
written = process_file(src, dest, Path("a.txt"), context={})
7171
assert written == dest / "a.txt"
7272
assert (dest / "a.txt").read_text() == "x"
73+
74+
75+
def test_copy_file_efficient_roundtrip(tmp_path: Path) -> None:
76+
from create_python_app_core.loaders import copy_file_efficient
77+
78+
src = tmp_path / "src.bin"
79+
src.write_bytes(b"hello-copy")
80+
dest = tmp_path / "nested" / "dest.bin"
81+
method = copy_file_efficient(src, dest)
82+
assert method in {"reflink", "hardlink", "copy"}
83+
assert dest.read_bytes() == b"hello-copy"
84+
85+
86+
def test_copy_file_efficient_skips_hardlink_when_disabled(
87+
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
88+
) -> None:
89+
from create_python_app_core.loaders import copy_file_efficient
90+
91+
monkeypatch.setenv("CPA_COPY_HARDLINK", "0")
92+
src = tmp_path / "src.txt"
93+
src.write_text("data")
94+
dest = tmp_path / "dest.txt"
95+
method = copy_file_efficient(src, dest, allow_hardlink=True)
96+
assert method in {"reflink", "copy"}
97+
assert dest.read_text() == "data"
98+
99+
100+
def test_copy_file_efficient_disallow_hardlink(
101+
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
102+
) -> None:
103+
from create_python_app_core.loaders import copy_file_efficient
104+
105+
# Force past reflink by stubbing subprocess failures if needed;
106+
# allow_hardlink=False must never return hardlink.
107+
monkeypatch.setenv("CPA_COPY_HARDLINK", "1")
108+
src = tmp_path / "src.txt"
109+
src.write_text("data")
110+
dest = tmp_path / "dest.txt"
111+
method = copy_file_efficient(src, dest, allow_hardlink=False)
112+
assert method != "hardlink"
113+
assert dest.read_text() == "data"

0 commit comments

Comments
 (0)