Add update command
CI / test (push) Successful in 35s

This commit is contained in:
2026-06-09 15:54:35 +09:00
parent 5110df995f
commit 921216e0d3
6 changed files with 162 additions and 1 deletions
-1
View File
@@ -26,7 +26,6 @@ impl KisApi {
token: None,
}
}
}
impl TraderApi for KisApi {
+2
View File
@@ -6,6 +6,7 @@ pub mod market;
pub mod order;
pub mod search;
pub mod universe;
pub mod update;
mod version;
pub use account::handle_account;
@@ -16,4 +17,5 @@ pub use market::handle_market;
pub use order::handle_order;
pub use search::handle_search;
pub use universe::handle_universe;
pub use update::handle_update;
pub use version::handle_version;
+113
View File
@@ -0,0 +1,113 @@
use crate::core::output;
use std::path::PathBuf;
use std::process::Command;
const DEFAULT_INSTALL_SCRIPT_URL: &str =
"https://git.hananakick.cc/Autotrade/openstock/raw/branch/main/scripts/install.sh";
pub fn handle_update() {
match update() {
Ok(result) => {
println!(
"{}",
output::explained(
"update",
"openstock 바이너리 업데이트 실행 결과",
vec![
output::field(
"installer_url",
"업데이트에 사용한 원격 설치 스크립트 URL",
serde_json::json!(result.installer_url),
),
output::field(
"install_dir",
"업데이트 대상 바이너리를 설치한 디렉터리",
serde_json::json!(result.install_dir.display().to_string()),
),
output::field(
"status",
"업데이트 명령 실행 결과",
serde_json::json!("updated"),
),
output::field(
"stdout",
"설치 스크립트 표준 출력",
serde_json::json!(result.stdout),
),
output::field(
"stderr",
"설치 스크립트 표준 오류 출력",
serde_json::json!(result.stderr),
),
],
)
);
}
Err(err) => eprintln!(
"{}",
output::error("update", "openstock 업데이트 실패", &err)
),
}
}
fn update() -> Result<UpdateResult, String> {
let install_dir = install_dir()?;
let installer_url = installer_url();
let command = format!("curl -fsSL {} | sh", shell_quote(&installer_url));
let output = Command::new("sh")
.arg("-c")
.arg(command)
.env("OPENSTOCK_INSTALL_DIR", &install_dir)
.output()
.map_err(|err| format!("업데이트 스크립트 실행 실패: {}", err))?;
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
if !output.status.success() {
return Err(format!(
"업데이트 스크립트가 실패했습니다. status={}, stdout={}, stderr={}",
output.status, stdout, stderr
));
}
Ok(UpdateResult {
installer_url,
install_dir,
stdout,
stderr,
})
}
fn install_dir() -> Result<PathBuf, String> {
if let Some(value) = std::env::var_os("OPENSTOCK_INSTALL_DIR") {
return Ok(PathBuf::from(value));
}
let exe =
std::env::current_exe().map_err(|err| format!("현재 실행 파일 경로 확인 실패: {}", err))?;
exe.parent().map(PathBuf::from).ok_or_else(|| {
format!(
"현재 실행 파일의 부모 디렉터리를 확인할 수 없습니다: {}",
exe.display()
)
})
}
fn installer_url() -> String {
std::env::var("OPENSTOCK_INSTALL_SCRIPT_URL")
.ok()
.filter(|value| !value.trim().is_empty())
.unwrap_or_else(|| DEFAULT_INSTALL_SCRIPT_URL.to_string())
}
fn shell_quote(value: &str) -> String {
format!("'{}'", value.replace('\'', "'\\''"))
}
struct UpdateResult {
installer_url: String,
install_dir: PathBuf,
stdout: String,
stderr: String,
}
+4
View File
@@ -29,6 +29,9 @@ enum Commands {
/// 애플리케이션 버젼 표시
Version,
/// 설치된 openstock 바이너리 업데이트
Update,
/// 증권사 API 리스트 조회 및 API 설정
Api {
#[command(subcommand)]
@@ -80,6 +83,7 @@ fn main() {
match &cli.command {
Some(Commands::Version) => commands::handle_version(),
Some(Commands::Update) => commands::handle_update(),
Some(Commands::Api { sub }) => commands::handle_api(sub),
Some(Commands::Dart { sub }) => commands::handle_dart(sub),
Some(Commands::Account { sub }) => commands::handle_account(sub),