Skip to content

Commit 7bf0ac9

Browse files
authored
Merge pull request #222 from OpenMined/madhava/mysys-paths
fix mysys paths
2 parents a63e77d + 9b8d007 commit 7bf0ac9

3 files changed

Lines changed: 72 additions & 11 deletions

File tree

.github/workflows/biovault-scenario-tests.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,11 @@ jobs:
137137
138138
- name: Setup workspace dependencies
139139
shell: bash
140+
env:
141+
BV_SKIP_SYQURE: "1"
140142
run: |
141143
chmod +x scripts/setup-workspace.sh
142144
./scripts/setup-workspace.sh
143-
- name: Init syqure submodules
144-
shell: bash
145-
run: |
146-
git -C syqure submodule update --init --recursive
147145
148146
- name: Install Rust
149147
uses: dtolnay/rust-toolchain@master

.github/workflows/biovault-syqure-tests.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,21 @@ jobs:
9191
9292
- name: Setup workspace dependencies
9393
shell: bash
94+
env:
95+
BV_INCLUDE_SYQURE: "1"
9496
run: |
9597
chmod +x scripts/setup-workspace.sh
9698
./scripts/setup-workspace.sh
9799
98100
- name: Init syqure submodules
99101
shell: bash
100102
run: |
101-
git -C syqure submodule update --init --recursive
103+
if [ -d syqure/.git ]; then
104+
git -C syqure submodule sync --recursive
105+
git -C syqure submodule update --init --recursive
106+
else
107+
echo "syqure directory not found; skipping submodule init"
108+
fi
102109
103110
- name: Install Rust
104111
uses: dtolnay/rust-toolchain@master

cli/src/cli/commands/run_dynamic.rs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ fn strip_extended_path_prefix(path: &str) -> String {
203203
path.to_string()
204204
}
205205

206-
/// Convert a Windows path to a container-compatible path for volume mounts.
206+
/// Convert a Windows path to a container-compatible path for use *inside* the container.
207207
/// - Docker Desktop: C:\Users\foo -> /c/Users/foo
208208
/// - Podman on WSL: C:\Users\foo -> /mnt/c/Users/foo
209209
#[cfg(target_os = "windows")]
@@ -247,11 +247,24 @@ fn windows_path_to_container(path: &Path, use_podman_format: bool) -> String {
247247
}
248248
}
249249

250+
/// Convert a Windows path to a host-side mount source.
251+
/// For Windows runtimes, the host side should be a Windows path.
252+
#[cfg(target_os = "windows")]
253+
fn windows_path_to_mount_source(path: &Path, _use_podman_format: bool) -> String {
254+
let canonical = path.canonicalize().unwrap_or_else(|_| path.to_path_buf());
255+
strip_extended_path_prefix(canonical.to_string_lossy().as_ref())
256+
}
257+
250258
#[cfg(not(target_os = "windows"))]
251259
fn windows_path_to_container(_path: &Path, _use_podman_format: bool) -> String {
252260
_path.to_string_lossy().to_string()
253261
}
254262

263+
#[cfg(not(target_os = "windows"))]
264+
fn windows_path_to_mount_source(path: &Path, _use_podman_format: bool) -> String {
265+
path.to_string_lossy().to_string()
266+
}
267+
255268
/// Recursively remap Windows paths in JSON values to container-compatible paths
256269
fn remap_json_paths_for_container(value: &JsonValue, use_podman_format: bool) -> JsonValue {
257270
match value {
@@ -321,6 +334,35 @@ fn normalize_windows_path_str(s: &str) -> String {
321334
.strip_prefix("\\\\?\\")
322335
.or_else(|| s.strip_prefix("//?/"))
323336
.unwrap_or(s);
337+
// Handle MSYS/Git Bash style paths like /c/Users/... or /mnt/c/Users/...
338+
if let Some(rest) = stripped.strip_prefix("/mnt/") {
339+
if rest.len() >= 3 && rest.as_bytes()[1] == b'/' {
340+
let drive = rest
341+
.chars()
342+
.next()
343+
.unwrap_or('c')
344+
.to_ascii_uppercase();
345+
let remainder = &rest[2..];
346+
return format!(
347+
"{}:\\{}",
348+
drive,
349+
remainder.replace('/', "\\").trim_start_matches("\\")
350+
);
351+
}
352+
}
353+
if stripped.len() >= 3 && stripped.starts_with('/') && stripped.as_bytes()[2] == b'/' {
354+
let drive = stripped
355+
.chars()
356+
.nth(1)
357+
.unwrap_or('c')
358+
.to_ascii_uppercase();
359+
let remainder = &stripped[3..];
360+
return format!(
361+
"{}:\\{}",
362+
drive,
363+
remainder.replace('/', "\\").trim_start_matches("\\")
364+
);
365+
}
324366
// Convert forward slashes to backslashes
325367
stripped.replace('/', "\\")
326368
}
@@ -492,6 +534,18 @@ fn looks_like_windows_absolute_path(s: &str) -> bool {
492534
.or_else(|| s.strip_prefix("//?/"))
493535
.unwrap_or(s);
494536

537+
// Accept MSYS/Git Bash style: /c/... or /mnt/c/...
538+
if let Some(rest) = stripped.strip_prefix("/mnt/") {
539+
if rest.len() >= 3 && rest.as_bytes()[1] == b'/' {
540+
let drive = rest.chars().next().unwrap_or('c');
541+
return drive.is_ascii_alphabetic();
542+
}
543+
}
544+
if stripped.len() >= 3 && stripped.starts_with('/') && stripped.as_bytes()[2] == b'/' {
545+
let drive = stripped.chars().nth(1).unwrap_or('c');
546+
return drive.is_ascii_alphabetic();
547+
}
548+
495549
if stripped.len() < 3 {
496550
return false;
497551
}
@@ -1913,35 +1967,37 @@ pub async fn execute_dynamic(
19131967
.arg("-v")
19141968
.arg(format!(
19151969
"{}:{}",
1916-
windows_path_to_container(&biovault_home, using_podman),
1970+
windows_path_to_mount_source(&biovault_home, using_podman),
19171971
docker_biovault_home
19181972
))
19191973
// Mount the project path (may be same as above, Docker handles duplicates)
19201974
.arg("-v")
19211975
.arg(format!(
19221976
"{}:{}",
1923-
windows_path_to_container(project_path, using_podman),
1977+
windows_path_to_mount_source(project_path, using_podman),
19241978
docker_project_path
19251979
));
19261980

19271981
// Mount additional data directories discovered from inputs
19281982
for mount_path in &mount_roots {
19291983
let container_mount = windows_path_to_container(mount_path, using_podman);
1984+
let host_mount = windows_path_to_mount_source(mount_path, using_podman);
19301985
append_desktop_log(&format!(
19311986
"[Pipeline] Adding mount: {} -> {}",
19321987
mount_path.display(),
19331988
container_mount
19341989
));
19351990
docker_cmd
19361991
.arg("-v")
1937-
.arg(format!("{}:{}", container_mount, container_mount));
1992+
.arg(format!("{}:{}", host_mount, container_mount));
19381993
}
19391994
}
19401995

19411996
// Generate runtime-specific Nextflow config (Docker vs Podman)
19421997
let runtime_config_path = if !dry_run {
1943-
let config_path =
1944-
generate_runtime_config(&project_abs, using_podman, hyperv_host_mount)?;
1998+
// On Windows with Podman, prefer copying inputs to avoid broken symlinks on /mnt/c mounts.
1999+
let stage_in_copy = hyperv_host_mount || (cfg!(target_os = "windows") && using_podman);
2000+
let config_path = generate_runtime_config(&project_abs, using_podman, stage_in_copy)?;
19452001
// For Hyper-V mode, the config file was copied to VM along with project
19462002
// Reference it via the VM project path
19472003
#[cfg(target_os = "windows")]

0 commit comments

Comments
 (0)