From e1f7bda5ab0c260c03d8789ed370d3adc89d5972 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Thu, 19 Mar 2026 21:38:00 +0800 Subject: Add workspace alias command for ID mapping management --- resources/helpdoc/commands/workspace/alias.en.md | 14 +++ .../helpdoc/commands/workspace/alias.zh-CN.md | 12 +++ resources/locales/jvn/cmds/workspace/alias/en.yml | 11 +++ .../locales/jvn/cmds/workspace/alias/zh-CN.yml | 11 +++ src/cmds/arg/workspace_alias.rs | 16 ++++ src/cmds/cmd/workspace_alias.rs | 105 +++++++++++++++++++++ src/cmds/comp/workspace_alias.rs | 25 +++++ src/cmds/in/workspace_alias.rs | 10 ++ src/cmds/out/alias_query.rs | 7 ++ src/cmds/renderer/alias_query.rs | 31 ++++++ 10 files changed, 242 insertions(+) create mode 100644 resources/helpdoc/commands/workspace/alias.en.md create mode 100644 resources/helpdoc/commands/workspace/alias.zh-CN.md create mode 100644 resources/locales/jvn/cmds/workspace/alias/en.yml create mode 100644 resources/locales/jvn/cmds/workspace/alias/zh-CN.yml create mode 100644 src/cmds/arg/workspace_alias.rs create mode 100644 src/cmds/cmd/workspace_alias.rs create mode 100644 src/cmds/comp/workspace_alias.rs create mode 100644 src/cmds/in/workspace_alias.rs create mode 100644 src/cmds/out/alias_query.rs create mode 100644 src/cmds/renderer/alias_query.rs diff --git a/resources/helpdoc/commands/workspace/alias.en.md b/resources/helpdoc/commands/workspace/alias.en.md new file mode 100644 index 0000000..50c9db9 --- /dev/null +++ b/resources/helpdoc/commands/workspace/alias.en.md @@ -0,0 +1,14 @@ +> Manage the `ID Aliases` for the _local workspace_ + +## Usage +jvn workspace alias +__ --insert # Map local ID +__ --to # to remote ID + +__ --erase # Delete mapping for local ID +__ --query # Query remote ID for local ID + +## Aliases +__ -i --to +__ -q +__ -e diff --git a/resources/helpdoc/commands/workspace/alias.zh-CN.md b/resources/helpdoc/commands/workspace/alias.zh-CN.md new file mode 100644 index 0000000..06efe7c --- /dev/null +++ b/resources/helpdoc/commands/workspace/alias.zh-CN.md @@ -0,0 +1,12 @@ +> 管理_本地工作区_的 `ID 映射表` + +## 使用 +jvn workspace alias <参数: ?> +__ --insert <本地ID> --to <远程ID> # 建立本地到远程ID的映射 +__ --erase <本地ID> # 擦除本地ID指向的映射 +__ --query <本地ID> # 查询本地ID指向的远程ID + +## 别名 +__ -i <本地ID> --to <远程ID> +__ -q <本地ID> +__ -e <本地ID> diff --git a/resources/locales/jvn/cmds/workspace/alias/en.yml b/resources/locales/jvn/cmds/workspace/alias/en.yml new file mode 100644 index 0000000..0fe993a --- /dev/null +++ b/resources/locales/jvn/cmds/workspace/alias/en.yml @@ -0,0 +1,11 @@ +workspace_alias: + error: + undeclared_input: | + Unclear input! + Use `jvn helpdoc commands/workspace/alias` to look up the usage + + render: + map: | + Local index `~%{local}` is mapped to `%{remote}` + no_map: | + Local index `~%{local}` has no mapping diff --git a/resources/locales/jvn/cmds/workspace/alias/zh-CN.yml b/resources/locales/jvn/cmds/workspace/alias/zh-CN.yml new file mode 100644 index 0000000..ee71845 --- /dev/null +++ b/resources/locales/jvn/cmds/workspace/alias/zh-CN.yml @@ -0,0 +1,11 @@ +workspace_alias: + error: + undeclared_input: | + 不明确的输入! + 使用 `jvn helpdoc commands/workspace/alias` 查询使用方式 + + render: + map: | + 本地索引 `~%{local}` 被指向 `%{remote}` + no_map: | + 本地索引 `~%{local}` 不存在指向 diff --git a/src/cmds/arg/workspace_alias.rs b/src/cmds/arg/workspace_alias.rs new file mode 100644 index 0000000..69286bd --- /dev/null +++ b/src/cmds/arg/workspace_alias.rs @@ -0,0 +1,16 @@ +#[derive(clap::Parser)] +pub struct JVWorkspaceAliasArgument { + pub id: u32, + + #[arg(long = "to")] + pub to: Option, + + #[arg(short = 'i', long = "insert")] + pub insert: bool, + + #[arg(short = 'q', long = "query")] + pub query: bool, + + #[arg(short = 'e', long = "erase")] + pub erase: bool, +} diff --git a/src/cmds/cmd/workspace_alias.rs b/src/cmds/cmd/workspace_alias.rs new file mode 100644 index 0000000..1c38bdf --- /dev/null +++ b/src/cmds/cmd/workspace_alias.rs @@ -0,0 +1,105 @@ +use crate::{ + cmd_output, + cmds::{ + arg::workspace_alias::JVWorkspaceAliasArgument, + collect::workspace::JVWorkspaceCollect, + converter::workspace_operation_error::JVWorkspaceOperationErrorConverter, + r#in::workspace_alias::{JVWorkspaceAliasInput, JVWorkspaceAliasInputMode}, + out::{alias_query::JVAliasQueryOutput, none::JVNoneOutput}, + }, + systems::{ + cmd::{ + cmd_system::{AnyOutput, JVCommandContext}, + errors::{CmdExecuteError, CmdPrepareError}, + }, + helpdoc::helpdoc_viewer, + }, +}; +use cmd_system_macros::exec; +use just_enough_vcs::system::workspace::workspace::manager::WorkspaceManager; +use log::trace; +use rust_i18n::t; + +pub struct JVWorkspaceAliasCommand; +type Cmd = JVWorkspaceAliasCommand; +type Arg = JVWorkspaceAliasArgument; +type In = JVWorkspaceAliasInput; +type Collect = JVWorkspaceCollect; + +async fn help_str() -> String { + helpdoc_viewer::display("commands/workspace/alias").await; + String::new() +} + +async fn prepare(args: &Arg, _ctx: &JVCommandContext) -> Result { + let mode = match (args.insert, args.erase, args.to) { + (false, true, _) => JVWorkspaceAliasInputMode::Erase(args.id), + (true, false, Some(to)) => JVWorkspaceAliasInputMode::Insert(args.id, to), + (false, false, _) => JVWorkspaceAliasInputMode::None(args.id), + _ => { + return Err(CmdPrepareError::Error( + t!("workspace_alias.error.undeclared_input").to_string(), + )); + } + }; + + Ok(JVWorkspaceAliasInput { + query: args.query, + mode: mode, + }) +} + +async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result { + Ok(JVWorkspaceCollect { + manager: WorkspaceManager::new(), + }) +} + +#[exec] +async fn exec(input: In, collect: Collect) -> Result { + let manager = collect.manager; + let index_source = match input.mode { + JVWorkspaceAliasInputMode::Insert(index, to) => { + trace!("Inserting alias for index: {}, to: {}", index, to); + manager + .write_id_alias(index, to) + .await + .map_err(JVWorkspaceOperationErrorConverter::to_exec_error)?; + index + } + JVWorkspaceAliasInputMode::Erase(index) => { + trace!("Erasing alias for index: {}", index); + manager + .delete_id_alias(index) + .await + .map_err(JVWorkspaceOperationErrorConverter::to_exec_error)?; + index + } + JVWorkspaceAliasInputMode::None(index) => { + trace!("No alias operation requested"); + // Do nothing + index + } + }; + + match (input.query, index_source) { + (true, index) => { + trace!("Querying alias for index: {}", index); + let remote = manager + .try_convert_to_remote(index) + .await + .map_err(JVWorkspaceOperationErrorConverter::to_exec_error)?; + trace!( + "Alias query result - local: {}, remote: {:?}", + index, remote + ); + cmd_output!(JVAliasQueryOutput => JVAliasQueryOutput { local: index, remote: remote }) + } + _ => { + trace!("No alias query requested or no index source available"); + cmd_output!(JVNoneOutput => JVNoneOutput) + } + } +} + +crate::command_template!(); diff --git a/src/cmds/comp/workspace_alias.rs b/src/cmds/comp/workspace_alias.rs new file mode 100644 index 0000000..c2fc234 --- /dev/null +++ b/src/cmds/comp/workspace_alias.rs @@ -0,0 +1,25 @@ +use cli_utils::string_vec; + +use crate::systems::comp::context::CompletionContext; + +pub fn comp(ctx: CompletionContext) -> Option> { + if ctx.all_words.contains(&"--insert".to_string()) { + if ctx.all_words.len() > 7 { + return None; + } + } else if ctx.all_words.len() > 5 { + return None; + } + + if ctx.current_word.starts_with('-') { + return Some(string_vec![ + "-i", "--insert", "-q", "--query", "-e", "--erase", "--to", + ]); + } + + if ctx.previous_word == "--to" { + return Some(vec![]); + } + + return None; +} diff --git a/src/cmds/in/workspace_alias.rs b/src/cmds/in/workspace_alias.rs new file mode 100644 index 0000000..ca9566a --- /dev/null +++ b/src/cmds/in/workspace_alias.rs @@ -0,0 +1,10 @@ +pub struct JVWorkspaceAliasInput { + pub query: bool, + pub mode: JVWorkspaceAliasInputMode, +} + +pub enum JVWorkspaceAliasInputMode { + Insert(u32, u32), + Erase(u32), + None(u32), +} diff --git a/src/cmds/out/alias_query.rs b/src/cmds/out/alias_query.rs new file mode 100644 index 0000000..2311741 --- /dev/null +++ b/src/cmds/out/alias_query.rs @@ -0,0 +1,7 @@ +use serde::Serialize; + +#[derive(Serialize)] +pub struct JVAliasQueryOutput { + pub local: u32, + pub remote: Option, +} diff --git a/src/cmds/renderer/alias_query.rs b/src/cmds/renderer/alias_query.rs new file mode 100644 index 0000000..8d6f8df --- /dev/null +++ b/src/cmds/renderer/alias_query.rs @@ -0,0 +1,31 @@ +use cli_utils::display::markdown::Markdown; +use render_system_macros::result_renderer; +use rust_i18n::t; + +use crate::{ + cmds::out::alias_query::JVAliasQueryOutput, + r_println, + systems::{cmd::errors::CmdRenderError, render::renderer::JVRenderResult}, +}; + +#[result_renderer(JVAliasQueryRenderer)] +pub async fn render(data: &JVAliasQueryOutput) -> Result { + let mut r = JVRenderResult::default(); + match (data.local, data.remote) { + (local, Some(remote)) => r_println!( + r, + "{}", + t!("workspace_alias.render.map", local = local, remote = remote) + .trim() + .markdown() + ), + (local, None) => r_println!( + r, + "{}", + t!("workspace_alias.render.no_map", local = local) + .trim() + .markdown() + ), + } + Ok(r) +} -- cgit