From fea63eb6a723c01be00593236b78d54c5319e52f Mon Sep 17 00:00:00 2001 From: hitalin Date: Thu, 18 Jun 2026 15:48:23 +0900 Subject: [PATCH] refactor: expose doctor checks as a library API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit doctor の診断ロジックを CLI 表示から分離し、Report を返す pub async fn diagnose() として公開する。notedeck の healthcheck が 同じチェック群 (db/keychain/accounts/network/auth) を再利用できるようにするため。 - Status / Check / Report を pub 化し specta feature で specta::Type を導出 - diagnose() を抽出 (print も std::process::exit もしない) - run_doctor() は diagnose() を呼ぶ CLI ラッパーに変更 (出力・終了コードは不変) - commands::doctor を pub mod に Co-Authored-By: Claude Opus 4.6 --- src/commands/doctor.rs | 46 +++++++++++++++++++++++++++--------------- src/commands/mod.rs | 4 +++- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/commands/doctor.rs b/src/commands/doctor.rs index 7f8a413..a241f9f 100644 --- a/src/commands/doctor.rs +++ b/src/commands/doctor.rs @@ -10,25 +10,27 @@ use crate::keychain; use crate::models::Account; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[cfg_attr(feature = "specta", derive(specta::Type))] #[serde(rename_all = "lowercase")] -enum Status { +pub enum Status { Ok, Warn, Fail, } -#[derive(Serialize)] -struct Check { +#[derive(Debug, Clone, Serialize)] +#[cfg_attr(feature = "specta", derive(specta::Type))] +pub struct Check { /// チェック項目名 (database, keychain, credentials, network, auth) - name: String, - status: Status, - message: String, + pub name: String, + pub status: Status, + pub message: String, /// アカウント別チェックの場合の対象 (@user@host)。環境チェックは None。 #[serde(skip_serializing_if = "Option::is_none")] - account: Option, + pub account: Option, /// 失敗・警告時にユーザーが実行すべき修復コマンド/手順。 #[serde(skip_serializing_if = "Option::is_none")] - fix: Option, + pub fix: Option, } impl Check { @@ -44,18 +46,21 @@ impl Check { } } -#[derive(Serialize)] -struct Report { - ok: bool, - checks: Vec, +#[derive(Debug, Clone, Serialize)] +#[cfg_attr(feature = "specta", derive(specta::Type))] +pub struct Report { + pub ok: bool, + pub checks: Vec, } -pub async fn run_doctor( +/// 環境・アカウントの診断を実行し、結果を [`Report`] として返す。 +/// 出力やプロセス終了は行わない — CLI 表示は [`run_doctor`] が、GUI (notedeck の +/// healthcheck) はこの [`Report`] を直接消費する。 +pub async fn diagnose( db: &Database, db_path: &Path, account_spec: Option<&str>, - fmt: OutputFormat, -) -> Result<(), NoteDeckError> { +) -> Result { let mut checks = vec![check_database(db, db_path), check_keychain()]; let accounts = db.load_accounts().unwrap_or_default(); @@ -92,7 +97,16 @@ pub async fn run_doctor( } let ok = checks.iter().all(|c| c.status != Status::Fail); - let report = Report { ok, checks }; + Ok(Report { ok, checks }) +} + +pub async fn run_doctor( + db: &Database, + db_path: &Path, + account_spec: Option<&str>, + fmt: OutputFormat, +) -> Result<(), NoteDeckError> { + let report = diagnose(db, db_path, account_spec).await?; print_report(&report, fmt); // 出力は済んでいるので、fail があればここで終了コード 1 を返す diff --git a/src/commands/mod.rs b/src/commands/mod.rs index b358255..560461d 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,5 +1,7 @@ mod auth; -mod doctor; +/// Public so embedders (notedeck の healthcheck) can call [`doctor::diagnose`] +/// to reuse the same checks the `doctor` CLI subcommand runs. +pub mod doctor; mod notes; mod users;