Skip to content

Commit a2b98f5

Browse files
committed
Use symlinks for demo workspace files on Linux
On Linux, create symlinks instead of copying files when setting up demo workspaces. This improves efficiency by saving disk space and reducing setup time. Directory structure is still created normally to allow users to add files without affecting the original demo data.
1 parent 3fa4498 commit a2b98f5

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

src/common/common.py

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,34 @@ def find_demo_workspace_path(demo_name: str) -> Path | None:
116116
return None
117117

118118

119+
def _symlink_tree(source: Path, target: Path) -> None:
120+
"""
121+
Recursively create directory structure and symlink files from source to target.
122+
123+
Creates real directories but symlinks individual files, allowing users to
124+
add new files to workspace directories without affecting the original.
125+
126+
Args:
127+
source: Source directory path.
128+
target: Target directory path.
129+
"""
130+
target.mkdir(parents=True, exist_ok=True)
131+
for item in source.iterdir():
132+
target_item = target / item.name
133+
if item.is_dir():
134+
_symlink_tree(item, target_item)
135+
else:
136+
# Create symlink to the source file
137+
target_item.symlink_to(item.resolve())
138+
139+
119140
def copy_demo_workspace(demo_name: str, target_path: Path) -> bool:
120141
"""
121142
Copy a demo workspace to the target path.
122143
144+
On Linux, creates symlinks to demo files instead of copying them.
145+
On other platforms, copies files normally.
146+
123147
Searches all configured source directories for the demo (first match wins).
124148
125149
Args:
@@ -137,7 +161,12 @@ def copy_demo_workspace(demo_name: str, target_path: Path) -> bool:
137161
try:
138162
if target_path.exists():
139163
shutil.rmtree(target_path)
140-
shutil.copytree(demo_path, target_path)
164+
165+
# Use symlinks on Linux for efficiency
166+
if OS_PLATFORM == "linux":
167+
_symlink_tree(demo_path, target_path)
168+
else:
169+
shutil.copytree(demo_path, target_path)
141170
return True
142171
except Exception:
143172
return False
@@ -567,15 +596,24 @@ def change_workspace():
567596
if st.button("Load Demo Data"):
568597
demo_path = find_demo_workspace_path(selected_demo)
569598
if demo_path:
570-
# Copy demo files to current workspace
599+
# Link or copy demo files to current workspace
571600
for item in demo_path.iterdir():
572601
target = st.session_state.workspace / item.name
573602
if item.is_dir():
574603
if target.exists():
575604
shutil.rmtree(target)
576-
shutil.copytree(item, target)
605+
# Use symlinks on Linux for efficiency
606+
if OS_PLATFORM == "linux":
607+
_symlink_tree(item, target)
608+
else:
609+
shutil.copytree(item, target)
577610
else:
578-
shutil.copy2(item, target)
611+
if target.exists():
612+
target.unlink()
613+
if OS_PLATFORM == "linux":
614+
target.symlink_to(item.resolve())
615+
else:
616+
shutil.copy2(item, target)
579617
st.success(f"Demo data '{selected_demo}' loaded!")
580618
time.sleep(1)
581619
st.rerun()

src/fileupload.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import streamlit as st
55

6-
from src.common.common import reset_directory
6+
from src.common.common import reset_directory, OS_PLATFORM
77

88

99
@st.cache_data
@@ -73,16 +73,24 @@ def load_example_mzML_files() -> None:
7373
"""
7474
Copies example mzML files to the mzML directory.
7575
76+
On Linux, creates symlinks to example files instead of copying them.
77+
7678
Args:
7779
None
7880
7981
Returns:
8082
None
8183
"""
8284
mzML_dir = Path(st.session_state.workspace, "mzML-files")
83-
# Copy files from example-data/mzML to workspace mzML directory, add to selected files
85+
# Copy or symlink files from example-data/mzML to workspace mzML directory
8486
for f in Path("example-data", "mzML").glob("*.mzML"):
85-
shutil.copy(f, mzML_dir)
87+
target = mzML_dir / f.name
88+
if OS_PLATFORM == "linux":
89+
if target.exists():
90+
target.unlink()
91+
target.symlink_to(f.resolve())
92+
else:
93+
shutil.copy(f, mzML_dir)
8694
st.success("Example mzML files loaded!")
8795

8896

0 commit comments

Comments
 (0)