Skip to main content

xchecker_runner/claude/
wsl.rs

1use crate::command_spec::CommandSpec;
2use std::env;
3
4use super::exec::Runner;
5
6impl Runner {
7    /// Get the WSL distro name from `wsl -l -q` or `$WSL_DISTRO_NAME`
8    #[must_use]
9    pub fn get_wsl_distro_name(&self) -> Option<String> {
10        // First try the configured distro
11        if let Some(distro) = &self.wsl_options.distro {
12            return Some(distro.clone());
13        }
14
15        // Try WSL_DISTRO_NAME environment variable
16        if let Ok(distro_name) = env::var("WSL_DISTRO_NAME")
17            && !distro_name.is_empty()
18        {
19            return Some(distro_name);
20        }
21
22        // Try to get default distro using CommandSpec
23        if let Ok(output) = CommandSpec::new("wsl")
24            .args(["-l", "-q"])
25            .to_command()
26            .output()
27            && output.status.success()
28        {
29            let distros = String::from_utf8_lossy(&output.stdout);
30            // Get the first non-empty line (default distro)
31            for line in distros.lines() {
32                let line = line.trim();
33                if !line.is_empty() {
34                    return Some(line.to_string());
35                }
36            }
37        }
38
39        None
40    }
41
42    pub(super) fn wsl_command_spec(&self, args: &[String]) -> CommandSpec {
43        // Get the claude path (default to "claude" if not specified)
44        let claude_path = self.wsl_options.claude_path.as_deref().unwrap_or("claude");
45
46        // Build WSL command: wsl.exe --exec <claude_path> <args...>
47        // Use CommandSpec to ensure secure argument passing
48        let mut spec = CommandSpec::new("wsl");
49
50        // Add distro specification if provided
51        if let Some(distro) = &self.wsl_options.distro {
52            spec = spec.args(["-d", distro]);
53        }
54
55        spec.arg("--exec").arg(claude_path).args(args)
56    }
57}