diff options
| author | 魏曹先生 <1992414357@qq.com> | 2025-10-24 16:16:45 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2025-10-24 16:16:45 +0800 |
| commit | 1dd3c4abec5a84ae1bd8dd0a93670a5bef601ab3 (patch) | |
| tree | f37abdbe37957fa122aedb0954b5451007339f22 | |
| parent | c7a7785eda77e96a99c58291d08a091a5d8846eb (diff) | |
Add cli error handle.
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | locales/help_docs/en.yml | 46 | ||||
| -rw-r--r-- | locales/help_docs/zh-CN.yml | 111 | ||||
| -rw-r--r-- | src/bin/jv.rs | 180 |
4 files changed, 305 insertions, 33 deletions
@@ -844,6 +844,7 @@ dependencies = [ name = "just_enough_vcs" version = "0.0.0" dependencies = [ + "action_system", "cfg_file", "string_proc", "tcp_connection", diff --git a/locales/help_docs/en.yml b/locales/help_docs/en.yml index 6092873..db190e0 100644 --- a/locales/help_docs/en.yml +++ b/locales/help_docs/en.yml @@ -328,3 +328,49 @@ jv: jv docs collaboration -e | nano Built-in documentation includes JustEnoughVCS usage guides, collaboration paradigms, and best practices. + + fail: + parse: + str_to_sockaddr: | + Could not recognize *`%{str}`* as an IP address + This is a problem with your input syntax! Please check **the content you entered** + + action_operation_fail: + main: | + This error is from the JustEnoughVCS core component + **Error Message**: %{err} + + type_connection: | + Based on the returned error context, this is a **network connection** issue + **Please check**: + 1. Whether your network connection is working properly + 2. Whether you have permission to connect to this address + + type_auth: | + Based on the returned error context, this is a **permission** issue + This indicates you don't have sufficient permissions to perform this operation. + + type_fsio: | + Based on the returned error context, this is a **file read/write** related issue + **Please check**: + 1. Whether your disk has sufficient space and is operating normally + 2. Whether your Local Workspace files are being used by other processes + + type_serialize: | + Based on the returned error context, this is a **serialization or deserialization** related issue + **Please check** + 1. Whether the parameter format you passed meets the requirements for serialization/deserialization + 2. Whether this version of JustEnoughVCS client/server supports this type of serialization + + type_other: | + Unfortunately, based on the returned context information, + this is not an expected error. + Please submit an Issue at the JustEnoughVCS Git Repository + + JustEnoughVCS needs your feedback, which will make this project more "JustEnough" + + info_contact_admin: | + If necessary, please contact the **administrator** of the Upstream Vault. + If you are the **administrator** and confirm this issue affects server operation, please: + 1. Check if your JustEnoughVCS server is up to date + 2. Submit an Issue at the JustEnoughVCS Git Repository diff --git a/locales/help_docs/zh-CN.yml b/locales/help_docs/zh-CN.yml index 2025cbe..ea66095 100644 --- a/locales/help_docs/zh-CN.yml +++ b/locales/help_docs/zh-CN.yml @@ -84,10 +84,10 @@ jvv: ref_sheet_not_found: 未找到参照表 `ref`,该参照表理应存在! create: - not_empty: 禁止的操作!指定的目录已经存在。 + not_empty: 禁止的操作!指定的目录已经存在 init: - not_empty: 禁止的操作!该目录不为空。 + not_empty: 禁止的操作!该目录不为空 member: register: 创建成员失败!请检查是否存在同名的成员 @@ -123,7 +123,7 @@ jvv: jv: help: | **JustEnoughVCS 本地工作区命令** - 该程序将连接至上游库,用以同步、提交本地工作区文件的变化,以供协同创作。 + 该程序将连接至上游库,用以同步、提交本地工作区文件的变化,以供协同创作 **常用别名**: jv u 下载最新信息,jv t 追踪文件,jv mv -a 自动移动文件,jv in/out 导入或导出文件 @@ -181,8 +181,8 @@ jv: jv account remove <账户名称> - 删除该账户 jv account mvkey <账户名称> <私钥文件> - 移动私钥到指定账户 - 账户是本地计算机上的身份标识,每个账户可以关联不同的私钥。 - 您需要先设置账户才能与上游库进行交互。 + 账户是本地计算机上的身份标识,每个账户可以关联不同的私钥 + 您需要先设置账户才能与上游库进行交互 sheet: | @@ -192,8 +192,8 @@ jv: jv sheet use <表名称> - 使用指定的表开始当前工作(不存在则自动创建) jv sheet exit - 退出当前工作 - 表是 JustEnoughVCS 中的核心概念,每个表代表一个独立的文件集合。 - 您可以在不同的表之间切换工作,或者将文件从一个表导出到另一个表。 + 表是 JustEnoughVCS 中的核心概念,每个表代表一个独立的文件集合 + 您可以在不同的表之间切换工作,或者将文件从一个表导出到另一个表 create: | @@ -201,18 +201,18 @@ jv: **用法**:jv create <工作区名称> **例如**:jv create my_workspace - 上述操作会在当前目录创建名为 my_workspace 的目录,并在其中初始化工作区。 + 上述操作会在当前目录创建名为 my_workspace 的目录,并在其中初始化工作区 - 工作区是您本地的工作环境,用于与上游库进行文件同步和版本控制。 + 工作区是您本地的工作环境,用于与上游库进行文件同步和版本控制 init: | **在此目录创建工作区** **用法**:jv init - 该命令会在当前所在的目录创建工作区,工作区名称由当前所在目录名称决定。 + 该命令会在当前所在的目录创建工作区,工作区名称由当前所在目录名称决定 - 如果当前目录不为空,该操作将会失败。请确保在空目录中执行此命令。 + 如果当前目录不为空,该操作将会失败,请确保在空目录中执行此命令 here: | @@ -224,7 +224,7 @@ jv: - 文件当前的持有人 - 文件最新版本的提交信息 - 这是了解当前工作区目录状态的快速方式。 + 这是了解当前工作区目录状态的快速方式 track: | @@ -232,10 +232,10 @@ jv: **用法**:jv track <文件路径> **例如**:jv track src/main.rs - 第一次追踪文件时,会创建并上传 “第一版本”,然后自动持有该文件的编辑权。 - 后续追踪同一文件时,会更新文件的新版本。 + 第一次追踪文件时,会创建并上传 “第一版本”,然后自动持有该文件的编辑权 + 后续追踪同一文件时,会更新文件的新版本 - 追踪文件是版本控制的基础操作,确保您的更改能够同步到上游库。 + 追踪文件是版本控制的基础操作,确保您的更改能够同步到上游库 hold: | @@ -243,10 +243,10 @@ jv: **用法**:jv hold <文件路径> **例如**:jv hold src/lib.rs - 当您需要编辑某个文件时,必须先持有该文件的编辑权。 - 持有文件后,其他协作者将无法同时编辑该文件,避免冲突。 + 当您需要编辑某个文件时,必须先持有该文件的编辑权 + 持有文件后,其他协作者将无法同时编辑该文件,避免冲突 - 编辑完成后,请记得追踪文件以保存更改。 + 编辑完成后,请记得追踪文件以保存更改 throw: | @@ -254,10 +254,10 @@ jv: **用法**:jv throw <文件路径> **例如**:jv throw src/config.rs - 当您不再需要编辑某个文件时,可以丢弃该文件的编辑权。 - 丢弃后,其他协作者就可以持有并编辑该文件。 + 当您不再需要编辑某个文件时,可以丢弃该文件的编辑权 + 丢弃后,其他协作者就可以持有并编辑该文件 - 如果您对文件进行了更改但尚未追踪,丢弃操作会丢失这些更改。 + 如果您对文件进行了更改但尚未追踪,丢弃操作会丢失这些更改 move: | @@ -271,7 +271,7 @@ jv: jv move src/old_dir/file.rs src/new_dir/file.rs jv move auto - 安全移动操作会保持文件的版本历史,而自动移动会检测并处理所有重命名。 + 安全移动操作会保持文件的版本历史,而自动移动会检测并处理所有重命名 export: | @@ -279,9 +279,9 @@ jv: **用法**:jv export <文件> <目标表> -m <描述> -n <文件包名称> **例如**:jv export data.csv analytics -m "导出分析数据" -n "analysis_data" - 该操作会将指定的文件打包并发送到目标表的导入区。 + 该操作会将指定的文件打包并发送到目标表的导入区 - 其他协作者可以在目标表中使用 jv import 命令来导入这些文件。 + 其他协作者可以在目标表中使用 jv import 命令来导入这些文件 import: | @@ -294,7 +294,7 @@ jv: jv import Player_Import - 来自导入区定义的名称 jv import ref@Data/Player.csv - 来自参照表的路径 - 导入操作会将文件从其他表或导入区复制到当前工作区。 + 导入操作会将文件从其他表或导入区复制到当前工作区 direct: | @@ -302,28 +302,28 @@ jv: **用法**:jv direct <上游库地址> **例如**:jv direct your_vault.org - 该操作会将当前工作区连接到指定的上游库,并为工作区添加染色标识。 + 该操作会将当前工作区连接到指定的上游库,并为工作区添加染色标识 - 染色后,该工作区将只能与指定标识的库进行交互,确保数据一致性。 + 染色后,该工作区将只能与指定标识的库进行交互,确保数据一致性 unstain: | **为工作区祛色** **用法**:jv unstain - **危险操作**:该操作会移除工作区的染色标识,此后该工作区将与上游库断开连接。 + **危险操作**:该操作会移除工作区的染色标识,此后该工作区将与上游库断开连接 - 祛色后,工作区将不再与任何特定库关联,可以重新连接到其他库。 - 但请注意,这可能会导致数据同步问题,请谨慎使用。 + 祛色后,工作区将不再与任何特定库关联,可以重新连接到其他库 + 但请注意,这可能会导致数据同步问题,请谨慎使用 update: | **从上游库下载最新的信息** **用法**:jv update - 该操作会从上游库同步最新的文件状态、表信息和成员信息。 + 该操作会从上游库同步最新的文件状态、表信息和成员信息 - 建议在开始工作前先执行更新操作,确保您拥有最新的工作环境。 + 建议在开始工作前先执行更新操作,确保您拥有最新的工作环境 docs: | @@ -337,4 +337,49 @@ jv: jv docs get-started jv docs collaboration -e | nano - 内建文档包含 JustEnoughVCS 的使用指南、协作范式和最佳实践。 + 内建文档包含 JustEnoughVCS 的使用指南、协作范式和最佳实践 + + fail: + parse: + str_to_sockaddr: | + 无法将 *`%{str}`* 识别为IP地址 + 这是您的输入语法问题!请检查 **输入的内容** + + action_operation_fail: + main: | + 此错误来自 JustEnoughVCS 核心组件 + **错误信息**:%{err} + + type_connection: | + 根据返回的错误上下文,这是一个**网络连接**问题 + **请检查**: + 1. 您的网络连接是否通畅 + 2. 您是否有权限连接至该地址 + + type_auth: | + 根据返回的错误上下文,这是一个**权限**问题 + 这说明您没有足够的权限去做此项操作。 + + type_fsio: | + 根据返回的错误上下文,这是一个**文件读写**相关的问题 + **请检查**: + 1. 您的磁盘是否有足够的空间,并且能正常流畅地运转 + 2. 您的本地工作区文件是否被其他进程占用 + + type_serialize: | + 根据返回的错误上下文,这是一个**序列化或反序列化**相关的问题 + **请检查** + 1. 您传入的参数格式是否符合序列化或反序列化的要求 + 2. 该版本的 JustEnoughVCS 客户端/服务端 是否支持该类型的序列化 + + type_other: | + 很遗憾,根据返回的上下文信息,这并不是一个符合预期的错误。 + 请前往 JustEnoughVCS 所在的 Git 版本库提交 Issue + + JustEnoughVCS 需要您的反馈,这会让该项目变得更加 "JustEnough" + + info_contact_admin: | + 如有必要,请联系上游库的 **管理员**。 + 若您作为 **管理员**,在确认该问题影响服务器运作,请 + 1. 检查您的 JustEnoughVCS 服务端是否最新 + 2. 前往 JustEnoughVCS 所在的 Git 版本库提交 Issue diff --git a/src/bin/jv.rs b/src/bin/jv.rs index 9530203..f67b37b 100644 --- a/src/bin/jv.rs +++ b/src/bin/jv.rs @@ -1,4 +1,11 @@ +use std::{net::SocketAddr, str::FromStr}; + use clap::{Parser, Subcommand, arg, command}; +use just_enough_vcs::{ + system::action_system::action::ActionContext, + utils::tcp_connection::error::TcpTargetError, + vcs::{actions::local_actions::proc_set_upstream_vault_action, registry::client_registry}, +}; use just_enough_vcs_cli::utils::{lang_selector::current_locales, md_colored::md}; use rust_i18n::{set_locale, t}; @@ -84,6 +91,12 @@ enum AccountManage { /// Show help information #[command(alias = "--help", alias = "-h")] Help, + + /// Register a member to this computer + Add(AccountAddArgs), + + /// Remove a account from this computer + Remove(AccountRemoveArgs), } #[derive(Subcommand, Debug)] @@ -94,6 +107,18 @@ enum SheetManage { } #[derive(Parser, Debug)] +struct AccountAddArgs { + /// Member name + member_name: String, +} + +#[derive(Parser, Debug)] +struct AccountRemoveArgs { + /// Member name + member_name: String, +} + +#[derive(Parser, Debug)] struct CreateWorkspaceArgs { /// Show help information #[arg(short, long)] @@ -161,6 +186,9 @@ struct DirectArgs { /// Show help information #[arg(short, long)] help: bool, + + /// Upstream vault address + upstream: String, } #[derive(Parser, Debug)] @@ -196,24 +224,29 @@ async fn main() { AccountManage::Help => { println!("{}", md(t!("jv.account"))); } + AccountManage::Add(account_add_args) => todo!(), + AccountManage::Remove(account_remove_args) => todo!(), }, JustEnoughVcsWorkspaceCommand::Create(create_workspace_args) => { if create_workspace_args.help { println!("{}", md(t!("jv.create"))); return; } + jv_create(create_workspace_args).await; } JustEnoughVcsWorkspaceCommand::Init(init_workspace_args) => { if init_workspace_args.help { println!("{}", md(t!("jv.init"))); return; } + jv_init(init_workspace_args).await; } JustEnoughVcsWorkspaceCommand::Here(here_args) => { if here_args.help { println!("{}", md(t!("jv.here"))); return; } + jv_here(here_args).await; } JustEnoughVcsWorkspaceCommand::Sheet(sheet_manage) => match sheet_manage { SheetManage::Help => { @@ -226,54 +259,201 @@ async fn main() { println!("{}", md(t!("jv.track"))); return; } + jv_track(track_file_args).await; } JustEnoughVcsWorkspaceCommand::Hold(hold_file_args) => { if hold_file_args.help { println!("{}", md(t!("jv.hold"))); return; } + jv_hold(hold_file_args).await; } JustEnoughVcsWorkspaceCommand::Throw(throw_file_args) => { if throw_file_args.help { println!("{}", md(t!("jv.throw"))); return; } + jv_throw(throw_file_args).await; } JustEnoughVcsWorkspaceCommand::Move(move_file_args) => { if move_file_args.help { println!("{}", md(t!("jv.move"))); return; } + jv_move(move_file_args).await; } JustEnoughVcsWorkspaceCommand::Export(export_file_args) => { if export_file_args.help { println!("{}", md(t!("jv.export"))); return; } + jv_export(export_file_args).await; } JustEnoughVcsWorkspaceCommand::Import(import_file_args) => { if import_file_args.help { println!("{}", md(t!("jv.import"))); return; } + jv_import(import_file_args).await; } JustEnoughVcsWorkspaceCommand::Direct(direct_args) => { if direct_args.help { println!("{}", md(t!("jv.direct"))); return; } + jv_direct(direct_args).await; } JustEnoughVcsWorkspaceCommand::Unstain(unstain_args) => { if unstain_args.help { println!("{}", md(t!("jv.unstain"))); return; } + jv_unstain(unstain_args).await; } JustEnoughVcsWorkspaceCommand::Docs(docs_args) => { if docs_args.help { println!("{}", md(t!("jv.docs"))); return; } + jv_docs(docs_args).await; + } + } +} + +async fn jv_create(_args: CreateWorkspaceArgs) { + todo!() +} + +async fn jv_init(_args: InitWorkspaceArgs) { + todo!() +} + +async fn jv_here(_args: HereArgs) { + todo!() +} + +async fn jv_track(_args: TrackFileArgs) { + todo!() +} + +async fn jv_hold(_args: HoldFileArgs) { + todo!() +} + +async fn jv_throw(_args: ThrowFileArgs) { + todo!() +} + +async fn jv_move(_args: MoveFileArgs) { + todo!() +} + +async fn jv_export(_args: ExportFileArgs) { + todo!() +} + +async fn jv_import(_args: ImportFileArgs) { + todo!() +} + +async fn jv_direct(args: DirectArgs) { + let pool = client_registry::client_action_pool(); + let upstream = match SocketAddr::from_str(&args.upstream) { + Ok(result) => result, + Err(_) => { + eprintln!( + "{}", + md(t!( + "jv.fail.parse.str_to_sockaddr", + str = &args.upstream.trim() + )) + ); + return; + } + }; + let ctx = ActionContext::local(); + match proc_set_upstream_vault_action(&pool, ctx, upstream).await { + Err(e) => handle_err(e), + _ => {} + }; +} + +async fn jv_unstain(_args: UnstainArgs) { + todo!() +} + +async fn jv_docs(_args: DocsArgs) { + todo!() +} + +pub fn handle_err(err: TcpTargetError) { + let e: Option<(String, String, bool)> = match err { + TcpTargetError::Io(err) => Some(fsio(err)), + TcpTargetError::File(err) => Some(fsio(err)), + + TcpTargetError::Serialization(err) => Some(serialize(err)), + + TcpTargetError::Authentication(err) => Some(auth(err)), + + TcpTargetError::Network(err) => Some(connection(err)), + TcpTargetError::Timeout(err) => Some(connection(err)), + TcpTargetError::Protocol(err) => Some(connection(err)), + + _ => Some(( + err.to_string(), + md(t!("jv.fail.action_operation_fail.type_other")), + false, + )), + }; + + if let Some((err_text, err_tip, has_tip)) = e { + eprintln!( + "{}\n{}", + md(t!("jv.fail.action_operation_fail.main", err = err_text)), + err_tip, + ); + + if has_tip { + eprintln!( + "{}", + md(t!("jv.fail.action_operation_fail.info_contact_admin")) + ) } } } + +type ErrorText = String; +type ErrorTip = String; +type HasTip = bool; + +fn fsio(err: String) -> (ErrorText, ErrorTip, HasTip) { + ( + err, + md(t!("jv.fail.action_operation_fail.type_fsio")).to_string(), + true, + ) +} + +fn serialize(err: String) -> (ErrorText, ErrorTip, HasTip) { + ( + err, + md(t!("jv.fail.action_operation_fail.type_serialize")).to_string(), + true, + ) +} + +fn auth(err: String) -> (ErrorText, ErrorTip, HasTip) { + ( + err, + md(t!("jv.fail.action_operation_fail.type_auth")).to_string(), + true, + ) +} + +fn connection(err: String) -> (ErrorText, ErrorTip, HasTip) { + ( + err, + md(t!("jv.fail.action_operation_fail.type_connection")).to_string(), + true, + ) +} |
