summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--locales/help_docs/en.yml46
-rw-r--r--locales/help_docs/zh-CN.yml111
-rw-r--r--src/bin/jv.rs180
4 files changed, 305 insertions, 33 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ccc1187..359c4cb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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,
+ )
+}