From 56a6c39df722587622c1f29269ab807e7ebb9653 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Tue, 11 Feb 2025 22:06:57 +0800 Subject: [PATCH] add -env --- ica-rs/src/ica.rs | 2 +- ica-rs/src/main.rs | 2 + ica-rs/src/py/mod.rs | 119 ++++++++++++++++++++++++------------------- news.md | 5 ++ 4 files changed, 74 insertions(+), 54 deletions(-) diff --git a/ica-rs/src/ica.rs b/ica-rs/src/ica.rs index da0460b..601d0b9 100644 --- a/ica-rs/src/ica.rs +++ b/ica-rs/src/ica.rs @@ -1,7 +1,7 @@ pub mod client; pub mod events; -use std::sync::OnceLock; +// use std::sync::OnceLock; use rust_socketio::asynchronous::{Client, ClientBuilder}; use rust_socketio::{async_any_callback, async_callback}; diff --git a/ica-rs/src/main.rs b/ica-rs/src/main.rs index bcdc05b..d6c63e2 100644 --- a/ica-rs/src/main.rs +++ b/ica-rs/src/main.rs @@ -108,6 +108,8 @@ const CLI_HELP_MSG: &str = r#"{VERSION} trace 模式 -h 显示帮助信息 + -env + 指定虚拟环境路径 -c 指定配置文件路径 "#; diff --git a/ica-rs/src/py/mod.rs b/ica-rs/src/py/mod.rs index 6038629..36bb573 100644 --- a/ica-rs/src/py/mod.rs +++ b/ica-rs/src/py/mod.rs @@ -414,6 +414,52 @@ pub fn load_py_file(path: &PathBuf) -> std::io::Result { Ok((path.clone(), changed_time, content)) } +fn init_py_with_env_path(path: &str) { + unsafe { + #[cfg(target_os = "linux")] + use std::os::unix::ffi::OsStrExt; + #[cfg(target_os = "windows")] + use std::os::windows::ffi::OsStrExt; + + let mut config = std::mem::zeroed::(); + let config_ptr = &mut config as *mut pyo3::ffi::PyConfig; + // 初始化配置 + // pyo3::ffi::PyConfig_InitIsolatedConfig(config_ptr); + pyo3::ffi::PyConfig_InitPythonConfig(config_ptr); + + let wide_path = OsStr::new(path).encode_wide().chain(Some(0)).collect::>(); + + // 设置 prefix 和 exec_prefix + pyo3::ffi::PyConfig_SetString( + config_ptr, + &mut config.prefix as *mut _, + wide_path.as_slice().as_ptr(), + ); + pyo3::ffi::PyConfig_SetString( + config_ptr, + &mut config.exec_prefix as *mut _, + wide_path.as_slice().as_ptr(), + ); + + // 使用 Py_InitializeFromConfig 初始化 python + let status = pyo3::ffi::Py_InitializeFromConfig(&config as *const _); + // 清理配置 + pyo3::ffi::PyConfig_Clear(config_ptr); + match status._type { + pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_OK => { + event!(Level::INFO, "根据配置初始化 python 完成"); + } + pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_EXIT => { + event!(Level::ERROR, "初始化 python 时发生错误: EXIT"); + } + pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_ERROR => { + event!(Level::ERROR, "初始化 python 时发生错误: ERROR"); + pyo3::ffi::Py_ExitStatusException(status); + } + } + } +} + /// Python 侧初始化 pub fn init_py() { // 从 全局配置中获取 python 插件路径 @@ -422,60 +468,27 @@ pub fn init_py() { let plugin_path = MainStatus::global_config().py().plugin_path; - // 根据 VIRTUAL_ENV 环境变量 进行一些处理 - match std::env::var("VIRTUAL_ENV") { - Ok(virtual_env) => { - event!(Level::INFO, "找到 VIRTUAL_ENV 环境变量: {} 正在初始化", virtual_env); - // 使用 Py_InitializeFromConfig 初始化 python - unsafe { - let mut config = std::mem::zeroed::(); - let config_ptr = &mut config as *mut pyo3::ffi::PyConfig; - // 初始化配置 - // pyo3::ffi::PyConfig_InitIsolatedConfig(config_ptr); - pyo3::ffi::PyConfig_InitPythonConfig(config_ptr); - - #[cfg(target_os = "linux")] - use std::os::unix::ffi::OsStrExt; - #[cfg(target_os = "windows")] - use std::os::windows::ffi::OsStrExt; - - let wide_path = - OsStr::new(&virtual_env).encode_wide().chain(Some(0)).collect::>(); - - // 设置 prefix 和 exec_prefix - pyo3::ffi::PyConfig_SetString( - config_ptr, - &mut config.prefix as *mut _, - wide_path.as_slice().as_ptr(), - ); - pyo3::ffi::PyConfig_SetString( - config_ptr, - &mut config.exec_prefix as *mut _, - wide_path.as_slice().as_ptr(), - ); - - // init py - let status = pyo3::ffi::Py_InitializeFromConfig(&config as *const _); - // 清理配置 - pyo3::ffi::PyConfig_Clear(config_ptr); - match status._type { - pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_OK => { - event!(Level::INFO, "根据配置初始化 python 完成"); - } - pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_EXIT => { - event!(Level::ERROR, "初始化 python 时发生错误: EXIT"); - } - pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_ERROR => { - event!(Level::ERROR, "初始化 python 时发生错误: ERROR"); - pyo3::ffi::Py_ExitStatusException(status); - } - } - } + let cli_args = std::env::args().collect::>(); + if cli_args.contains(&"-env".to_string()) { + let env_path = cli_args.iter().find(|&arg| arg != "-env").expect("未找到 -env 参数的值"); + event!(Level::INFO, "找到 -env 参数: {} 正在初始化", env_path); + // 判断一下是否有 VIRTUAL_ENV 环境变量 + if let Ok(virtual_env) = std::env::var("VIRTUAL_ENV") { + event!(Level::WARN, "找到 VIRTUAL_ENV 环境变量: {} 将会被 -env 参数覆盖", virtual_env); } - Err(_) => { - event!(Level::INFO, "未找到 VIRTUAL_ENV 环境变量, 正常初始化"); - pyo3::prepare_freethreaded_python(); - event!(Level::INFO, "prepare_freethreaded_python 完成"); + init_py_with_env_path(env_path); + } else { + // 根据 VIRTUAL_ENV 环境变量 进行一些处理 + match std::env::var("VIRTUAL_ENV") { + Ok(virtual_env) => { + event!(Level::INFO, "找到 VIRTUAL_ENV 环境变量: {} 正在初始化", virtual_env); + init_py_with_env_path(&virtual_env); + } + Err(_) => { + event!(Level::INFO, "未找到 VIRTUAL_ENV 环境变量, 正常初始化"); + pyo3::prepare_freethreaded_python(); + event!(Level::INFO, "prepare_freethreaded_python 完成"); + } } } diff --git a/news.md b/news.md index 77b1492..08e3ab9 100644 --- a/news.md +++ b/news.md @@ -4,6 +4,11 @@ - 现在支持通过读取环境变量里的 `VIRTUAL_ENV` 来获取虚拟环境路径 - 用于在虚拟环境中运行插件 +- 添加了 `-h` 参数 + - 用于展示帮助信息 +- 添加了 `-env` 参数 + - 用于指定 python 插件的虚拟环境路径 + - 会覆盖环境变量中的 `VIRTUAL_ENV` - 现在加入了默认的配置文件路径 `./config.toml` ## 0.8.1