Repository: mitsuhiko/rye
File: rye/src/cli/shell.rs (Rust)

Code before:
                "powershell.exe" => {
                    return Ok(String::from("powershell.exe"));
                }
                "pwsh.exe" => {
                    return Ok(String::from("pwsh.exe"));
                }
                &_ => {
                    pid = process.parent();
                    continue;
                }
            }
        }
        break;
    }

    Err(anyhow::anyhow!("don't know which shell is used"))
}

fn is_ms_shells(shell: &str) -> bool {
    matches!(shell, "cmd.exe" | "powershell.exe" | "pwsh.exe")
}

pub fn execute(cmd: Args) -> Result<(), Error> {
    if !cmd.allow_nested && env::var("__RYE_SHELL").ok().as_deref() == Some("1") {
        bail!("cannot invoke recursive rye shell");
    }

    let _guard = redirect_to_stderr(true);
    let pyproject = PyProject::load_or_discover(cmd.pyproject.as_deref())?;
    sync(SyncOptions::python_only().pyproject(cmd.pyproject))
        .context("failed to sync ahead of shell")?;

    let venv_path = pyproject.venv_path();
    let venv_bin = if env::consts::OS == "windows" {
        venv_path.join("Scripts")
    } else {
        venv_path.join("bin")
    };

    let s = get_shell()?;
    let sep = if is_ms_shells(s.as_str()) {
        ";"
    } else {
        ":"
    };
    let args = if !is_ms_shells(s.as_str()) {
        vec!["-l"]
    } else {
        vec![]
    };
    let mut shell = Command::new(s.as_str());

Review comment (suggestion):
I think it should be determined in runtime instead of compile time, so using `env::consts::OS == "windows"` instead of `cfg!(windows)`.

Maybe we will using binaries build in windows and runs on linux (wine?).

Code after:
                pid = process.parent();
                continue;
            }
        }
        break;
    }

    Err(anyhow::anyhow!("don't know which shell is used"))
}

fn is_ms_shells(shell: &str) -> bool {
    matches!(shell, "cmd.exe" | "powershell.exe" | "pwsh.exe")
}

pub fn execute(cmd: Args) -> Result<(), Error> {
    if !cmd.allow_nested && env::var("__RYE_SHELL").ok().as_deref() == Some("1") {
        bail!("cannot invoke recursive rye shell");
    }

    let _guard = redirect_to_stderr(true);
    let pyproject = PyProject::load_or_discover(cmd.pyproject.as_deref())?;
    sync(SyncOptions::python_only().pyproject(cmd.pyproject))
        .context("failed to sync ahead of shell")?;

    let venv_path = pyproject.venv_path();
    let venv_bin = if env::consts::OS == "windows" {
        venv_path.join("Scripts")
    } else {
        venv_path.join("bin")
    };

    let s = get_shell()?;
    let sep = if is_ms_shells(s.as_str()) { ";" } else { ":" };
    let args = if !is_ms_shells(s.as_str()) {
        vec!["-l"]
    } else {
        vec![]
    };
    let mut shell = Command::new(s.as_str());
    shell.args(args).env("VIRTUAL_ENV", &*venv_path);

    if let Some(path) = env::var_os("PATH") {
        let mut new_path = venv_bin.as_os_str().to_owned();
        new_path.push(sep);
        new_path.push(path);
        shell.env("PATH", new_path);
    } else {
        shell.env("PATH", &*venv_bin);
    }
    shell.env_remove("PYTHONHOME");
    shell.env("__RYE_SHELL", "1");