mirror of
https://github.com/ankitects/anki.git
synced 2025-11-06 12:47:11 -05:00
update ffl run impls
This commit is contained in:
parent
cea6263688
commit
2c018574e1
2 changed files with 9 additions and 81 deletions
|
|
@ -6,10 +6,9 @@ use std::ffi::CString;
|
||||||
use std::os::unix::prelude::OsStrExt;
|
use std::os::unix::prelude::OsStrExt;
|
||||||
|
|
||||||
use anki_io::ToUtf8Path;
|
use anki_io::ToUtf8Path;
|
||||||
use anyhow::anyhow;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::get_libpython_path;
|
use crate::get_python_env_info;
|
||||||
use crate::platform::PyFfi;
|
use crate::platform::PyFfi;
|
||||||
use crate::State;
|
use crate::State;
|
||||||
|
|
||||||
|
|
@ -72,44 +71,12 @@ impl PyFfi {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(state: &State) -> Result<()> {
|
pub fn run(state: &State) -> Result<()> {
|
||||||
let lib_path = get_libpython_path(state)?;
|
let (version, lib_path, exec) = get_python_env_info(state)?;
|
||||||
|
|
||||||
// NOTE: activate venv before loading lib
|
|
||||||
let path = std::env::var("PATH")?;
|
|
||||||
let paths = std::env::split_paths(&path);
|
|
||||||
let path = std::env::join_paths(std::iter::once(state.venv_folder.join("bin")).chain(paths))?;
|
|
||||||
std::env::set_var("PATH", path);
|
|
||||||
std::env::set_var("VIRTUAL_ENV", &state.venv_folder);
|
|
||||||
std::env::set_var("PYTHONHOME", "");
|
|
||||||
|
|
||||||
std::env::set_var("ANKI_LAUNCHER", std::env::current_exe()?.utf8()?.as_str());
|
std::env::set_var("ANKI_LAUNCHER", std::env::current_exe()?.utf8()?.as_str());
|
||||||
std::env::set_var("ANKI_LAUNCHER_UV", state.uv_path.utf8()?.as_str());
|
std::env::set_var("ANKI_LAUNCHER_UV", state.uv_path.utf8()?.as_str());
|
||||||
std::env::set_var("UV_PROJECT", state.uv_install_root.utf8()?.as_str());
|
std::env::set_var("UV_PROJECT", state.uv_install_root.utf8()?.as_str());
|
||||||
std::env::remove_var("SSLKEYLOGFILE");
|
std::env::remove_var("SSLKEYLOGFILE");
|
||||||
|
|
||||||
let ffi = PyFfi::load(lib_path)?;
|
PyFfi::load(lib_path, exec)?.run(&version, None)
|
||||||
|
|
||||||
// NOTE: sys.argv would normally be set via PyConfig, but we don't have it here
|
|
||||||
let args: String = std::env::args()
|
|
||||||
.skip(1)
|
|
||||||
.map(|s| format!(r#","{s}""#))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// NOTE:
|
|
||||||
// the venv activation script doesn't seem to be
|
|
||||||
// necessary for linux, only PATH and VIRTUAL_ENV
|
|
||||||
// but just call it anyway to have a standard setup
|
|
||||||
let venv_activate_path = state.venv_folder.join("bin/activate_this.py");
|
|
||||||
let venv_activate_path = venv_activate_path
|
|
||||||
.as_os_str()
|
|
||||||
.to_str()
|
|
||||||
.ok_or_else(|| anyhow!("failed to get venv activation script path"))?;
|
|
||||||
|
|
||||||
let preamble = std::ffi::CString::new(format!(
|
|
||||||
r#"import sys, runpy; sys.argv = ['Anki'{args}]; runpy.run_path("{venv_activate_path}")"#,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
ffi.run(preamble)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ use windows::Win32::System::Registry::REG_SZ;
|
||||||
use windows::Win32::System::SystemInformation::OSVERSIONINFOW;
|
use windows::Win32::System::SystemInformation::OSVERSIONINFOW;
|
||||||
use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID;
|
use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID;
|
||||||
|
|
||||||
use crate::get_libpython_path;
|
use crate::get_python_env_info;
|
||||||
use crate::platform::PyFfi;
|
use crate::platform::PyFfi;
|
||||||
use crate::State;
|
use crate::State;
|
||||||
|
|
||||||
|
|
@ -335,58 +335,19 @@ impl PyFfi {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(state: &State, console: bool) -> Result<()> {
|
pub fn run(state: &State, console: bool) -> Result<()> {
|
||||||
let lib_path = get_libpython_path(state)?;
|
let (version, lib_path, exec) = get_python_env_info(state)?;
|
||||||
|
|
||||||
// NOTE: needed for 3.9 on windows (not for 3.13)
|
|
||||||
std::env::set_current_dir(
|
|
||||||
lib_path
|
|
||||||
.parent()
|
|
||||||
.ok_or_else(|| anyhow!("expected parent dir for lib_path: {lib_path:?}"))?,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let path = std::env::var("PATH")?;
|
|
||||||
let paths = std::env::split_paths(&path);
|
|
||||||
let path =
|
|
||||||
std::env::join_paths(std::iter::once(state.venv_folder.join("Scripts")).chain(paths))?;
|
|
||||||
std::env::set_var("PATH", path);
|
|
||||||
std::env::set_var("VIRTUAL_ENV", &state.venv_folder);
|
|
||||||
std::env::set_var("PYTHONHOME", "");
|
|
||||||
|
|
||||||
std::env::set_var("ANKI_LAUNCHER", std::env::current_exe()?.utf8()?.as_str());
|
std::env::set_var("ANKI_LAUNCHER", std::env::current_exe()?.utf8()?.as_str());
|
||||||
std::env::set_var("ANKI_LAUNCHER_UV", state.uv_path.utf8()?.as_str());
|
std::env::set_var("ANKI_LAUNCHER_UV", state.uv_path.utf8()?.as_str());
|
||||||
std::env::set_var("UV_PROJECT", state.uv_install_root.utf8()?.as_str());
|
std::env::set_var("UV_PROJECT", state.uv_install_root.utf8()?.as_str());
|
||||||
std::env::remove_var("SSLKEYLOGFILE");
|
std::env::remove_var("SSLKEYLOGFILE");
|
||||||
|
|
||||||
let ffi = PyFfi::load(lib_path)?;
|
|
||||||
|
|
||||||
let args: String = std::env::args()
|
|
||||||
.skip(1)
|
|
||||||
.map(|s| format!(r#","{s}""#))
|
|
||||||
.collect::<String>()
|
|
||||||
.replace('\\', "\\\\");
|
|
||||||
|
|
||||||
let venv_activate_path = state.venv_folder.join("Scripts\\activate_this.py");
|
|
||||||
let venv_activate_path = venv_activate_path
|
|
||||||
.as_os_str()
|
|
||||||
.to_str()
|
|
||||||
.ok_or_else(|| anyhow!("failed to get venv activation script path"))?
|
|
||||||
.replace('\\', "\\\\");
|
|
||||||
|
|
||||||
// NOTE: without windows_subsystem=console or pythonw,
|
// NOTE: without windows_subsystem=console or pythonw,
|
||||||
// we need to reconnect stdin/stdout/stderr within the interp
|
// we need to reconnect stdin/stdout/stderr within the interp
|
||||||
// reconnect_stdio_to_console doesn't make a difference here
|
// reconnect_stdio_to_console doesn't make a difference here
|
||||||
let console_snippet = if console {
|
let preamble = console.then_some(
|
||||||
r#" sys.stdout = sys.stderr = open("CONOUT$", "w"); sys.stdin = open("CONIN$", "r");"#
|
cr#"import sys; sys.stdout = sys.stderr = open("CONOUT$", "w"); sys.stdin = open("CONIN$", "r");"#,
|
||||||
} else {
|
);
|
||||||
""
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE: windows needs the venv activation script
|
PyFfi::load(lib_path, exec)?.run(&version, preamble)
|
||||||
let preamble = CString::new(format!(
|
|
||||||
r#"import sys, runpy; sys.argv = ['Anki'{args}]; runpy.run_path("{venv_activate_path}");{console_snippet}"#,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
ffi.run(preamble)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue