diff --git a/internal/i18n/locales/en-US.json b/internal/i18n/locales/en-US.json index 0739395..8131a1f 100644 --- a/internal/i18n/locales/en-US.json +++ b/internal/i18n/locales/en-US.json @@ -34,12 +34,15 @@ "cmd.dataset.view.short": "View a repository's dataset", "cmd.doctor.long": "Run local diagnostics for gitlink-cli configuration, authentication, repository context and API connectivity.", "cmd.doctor.short": "Diagnose gitlink-cli environment problems", - "cmd.issue.batch_close.long": "Close filtered issues in bulk.\n\nThis command defaults to dry-run mode and only prints matching issues.\nPass --yes to execute remote close operations. Use restrictive filters and a small limit.\n\nExamples:\n gitlink-cli issue +batch-close --owner Gitlink --repo gitlink-cli --older-than-days 60 --limit 20\n gitlink-cli issue +batch-close --owner Gitlink --repo gitlink-cli --older-than-days 60 --limit 20 --yes", - "cmd.issue.batch_close.short": "Close filtered issues in bulk. Defaults to dry-run; pass --yes to execute.", - "cmd.issue.batch_label.long": "Add a label to filtered issues in bulk.\n\nThis command defaults to dry-run mode and only prints matching issues.\nPass --yes to execute remote label operations. The current implementation does not fake label writes when the API endpoint is unavailable.\n\nExamples:\n gitlink-cli issue +batch-label --owner Gitlink --repo gitlink-cli --add-label stale --older-than-days 30 --limit 50\n gitlink-cli issue +batch-label --owner Gitlink --repo gitlink-cli --add-label stale --older-than-days 30 --limit 50 --yes", - "cmd.issue.batch_label.short": "Add a label to filtered issues in bulk. Defaults to dry-run; pass --yes to execute.", - "cmd.issue.batch_list.long": "List issue batch maintenance candidates without changing remote data.\n\nExamples:\n gitlink-cli issue +batch-list --owner Gitlink --repo gitlink-cli --state open --older-than-days 30 --limit 50 --format table\n gitlink-cli issue +batch-list --owner Gitlink --repo gitlink-cli --label bug --format json", - "cmd.issue.batch_list.short": "List issue batch maintenance candidates without changing remote data", + "cmd.issue.batch_assign.short": "Assign issues to a user or via CSV", + "cmd.issue.batch_close.long": "Close multiple issues. Pass issue numbers via --numbers or read from a CSV via --from.\n\nDefaults to dry-run; pass --confirm to execute.", + "cmd.issue.batch_close.short": "Close multiple issues by issue numbers or a CSV file", + "cmd.issue.batch_create.short": "Create multiple issues from CSV", + "cmd.issue.batch_delete.short": "Batch delete multiple issues (use with caution)", + "cmd.issue.batch_label.long": "Batch add, remove, or set labels on multiple issues.\n\nDefaults to dry-run; pass --confirm to execute.", + "cmd.issue.batch_label.short": "Add, remove, or set labels on multiple issues", + "cmd.issue.batch_open.short": "Reopen multiple issues", + "cmd.issue.batch_update.short": "Update multiple issues via CSV or --ids", "cmd.issue.close.short": "Close an issue", "cmd.issue.comment.short": "Add a comment to an issue", "cmd.issue.create.short": "Create a new issue", @@ -90,12 +93,19 @@ "cmd.repo.tree.short": "List repository files and directories", "cmd.root.long": "Manage repositories, issues, pull requests, releases, CI and workflows on GitLink.", "cmd.root.short": "GitLink CLI - command-line tool for GitLink", + "cmd.search.issues.short": "Search issues in a repository", "cmd.search.repos.short": "Search repositories", "cmd.search.short": "Search operations", "cmd.search.users.short": "Search users", + "cmd.user.headmaps.short": "Show user contribution heatmap", "cmd.user.info.short": "Show user profile", "cmd.user.me.short": "Show current authenticated user", "cmd.user.short": "User operations", + "cmd.user.stats_activity.short": "Show user activity statistics", + "cmd.user.stats_develop.short": "Show user development capability", + "cmd.user.stats_major.short": "Show user major positioning", + "cmd.user.stats_role.short": "Show user role positioning", + "cmd.user.trends.short": "Show user project activity trends", "cmd.version.short": "Print version information", "cmd.webhook.create.short": "Create a repository webhook", "cmd.webhook.delete.short": "Delete a repository webhook", @@ -150,13 +160,36 @@ "flag.issue.assignee": "Assignee login", "flag.issue.assignee_id": "Assignee user ID", "flag.issue.author_id": "Author user ID", - "flag.issue.batch.reason": "Optional reason shown in the batch result", - "flag.issue.batch.yes": "Execute remote operations. Without this flag the command is dry-run only.", - "flag.issue.batch_close.older_than_days": "Required safety filter; must be at least 7", - "flag.issue.batch_close.state": "Filter by issue state before closing", - "flag.issue.batch_label.state": "Filter by issue state", - "flag.issue.batch_list.limit": "Maximum issues to return, capped at 100", - "flag.issue.batch_process.limit": "Maximum issues to process, capped at 100", + "flag.issue.batch.confirm": "Confirm batch operation", + "flag.issue.batch.delay": "Delay in milliseconds between requests", + "flag.issue.batch.dry_run": "Preview the issues that would be changed without making any changes", + "flag.issue.batch.from": "Read issue numbers from a CSV file. Supports a number/issue_number/project_issues_index column or first column without header", + "flag.issue.batch.label": "Filter by label name", + "flag.issue.batch.max": "Maximum number of issues to process", + "flag.issue.batch.numbers": "Comma-separated issue numbers from the web URL, for example: 1,2,3", + "flag.issue.batch.search": "Search issues by keyword", + "flag.issue.batch.state": "Filter by state: open, closed, all", + "flag.issue.batch_assign.assignee": "Assignee username or ID (uniform mode)", + "flag.issue.batch_assign.csv": "CSV file with number,assignee columns", + "flag.issue.batch_assign.numbers": "Comma-separated issue numbers", + "flag.issue.batch_close.state": "Filter by state before closing", + "flag.issue.batch_create.csv": "CSV file with issue data", + "flag.issue.batch_create.print_schema": "Print CSV header and exit", + "flag.issue.batch_delete.confirm": "Confirm deletion (required for safety)", + "flag.issue.batch_delete.dry_run": "Preview deletion without executing", + "flag.issue.batch_delete.ids": "Comma-separated issue IDs", + "flag.issue.batch_label.action": "Action: add, remove, or set", + "flag.issue.batch_label.csv": "CSV file path with issue numbers", + "flag.issue.batch_label.label_ids": "Comma-separated label IDs (mutually exclusive with --labels)", + "flag.issue.batch_label.labels": "Comma-separated label names", + "flag.issue.batch_label.numbers": "Comma-separated issue numbers", + "flag.issue.batch_update.assignees": "Comma-separated assignee user IDs", + "flag.issue.batch_update.csv": "CSV file path with updates", + "flag.issue.batch_update.ids": "Comma-separated issue IDs", + "flag.issue.batch_update.milestone": "Milestone ID", + "flag.issue.batch_update.priority": "Priority ID", + "flag.issue.batch_update.status": "New status: open or closed", + "flag.issue.batch_update.tags": "Comma-separated label/tag IDs", "flag.issue.body": "Issue description", "flag.issue.label": "Label ID", "flag.issue.label_filter": "Filter by existing label", @@ -214,6 +247,11 @@ "flag.repo.private": "Make repository private (true/false)", "flag.repo.tree.path": "Directory path to list (default: repository root)", "flag.repo.tree.ref": "Branch, tag, or commit ref", + "flag.search.issues.assignee": "Filter by assignee user ID", + "flag.search.issues.author": "Filter by author user ID", + "flag.search.issues.category": "Issue category: all, opened, closed", + "flag.search.issues.milestone": "Filter by milestone ID", + "flag.search.issues.tag": "Filter by tag IDs (comma-separated)", "flag.search.keyword": "Search keyword", "flag.sort_by": "Sort field", "flag.sort_direction": "Sort direction: asc, desc", diff --git a/internal/i18n/locales/zh-CN.json b/internal/i18n/locales/zh-CN.json index 2e6fc4d..d41273e 100644 --- a/internal/i18n/locales/zh-CN.json +++ b/internal/i18n/locales/zh-CN.json @@ -34,12 +34,15 @@ "cmd.dataset.view.short": "查看仓库数据集", "cmd.doctor.long": "诊断 gitlink-cli 的配置、认证、仓库上下文和 API 连通性问题。", "cmd.doctor.short": "诊断 gitlink-cli 环境问题", - "cmd.issue.batch_close.long": "批量关闭筛选后的议题。\n\n该命令默认处于 dry-run 模式,只打印匹配的议题。\n传入 --yes 后执行远端关闭操作。请使用严格筛选条件和较小 limit。\n\n示例:\n gitlink-cli issue +batch-close --owner Gitlink --repo gitlink-cli --older-than-days 60 --limit 20\n gitlink-cli issue +batch-close --owner Gitlink --repo gitlink-cli --older-than-days 60 --limit 20 --yes", - "cmd.issue.batch_close.short": "批量关闭筛选后的议题。默认 dry-run;传入 --yes 后执行。", - "cmd.issue.batch_label.long": "给筛选后的议题批量添加标签。\n\n该命令默认处于 dry-run 模式,只打印匹配的议题。\n传入 --yes 后执行远端标签操作。当前实现不会在 API 端点不可用时伪造写入结果。\n\n示例:\n gitlink-cli issue +batch-label --owner Gitlink --repo gitlink-cli --add-label stale --older-than-days 30 --limit 50\n gitlink-cli issue +batch-label --owner Gitlink --repo gitlink-cli --add-label stale --older-than-days 30 --limit 50 --yes", - "cmd.issue.batch_label.short": "给筛选后的议题批量添加标签。默认 dry-run;传入 --yes 后执行。", - "cmd.issue.batch_list.long": "列出议题批量维护候选项,不修改远端数据。\n\n示例:\n gitlink-cli issue +batch-list --owner Gitlink --repo gitlink-cli --state open --older-than-days 30 --limit 50 --format table\n gitlink-cli issue +batch-list --owner Gitlink --repo gitlink-cli --label bug --format json", - "cmd.issue.batch_list.short": "列出议题批量维护候选项,不修改远端数据", + "cmd.issue.batch_assign.short": "批量指派议题负责人", + "cmd.issue.batch_close.long": "批量关闭多个议题。支持 --numbers 直接传入编号,或 --from 从 CSV 读取。\n\n默认 dry-run,传入 --confirm 后执行。", + "cmd.issue.batch_close.short": "批量关闭多个议题(按编号或 CSV)", + "cmd.issue.batch_create.short": "从 CSV 批量创建议题", + "cmd.issue.batch_delete.short": "批量删除多个议题(谨慎使用)", + "cmd.issue.batch_label.long": "批量给多个议题添加、移除或设置标签。\n\n默认 dry-run,传入 --confirm 后执行。", + "cmd.issue.batch_label.short": "批量管理议题标签(添加/移除/设置)", + "cmd.issue.batch_open.short": "批量重新打开多个议题", + "cmd.issue.batch_update.short": "批量更新议题(按 CSV 或 ID)", "cmd.issue.close.short": "关闭议题", "cmd.issue.comment.short": "给议题添加评论", "cmd.issue.create.short": "创建新议题", @@ -90,12 +93,19 @@ "cmd.repo.tree.short": "列出仓库文件和目录", "cmd.root.long": "用于管理 GitLink 上的仓库、议题、拉取请求、发布、CI 和工作流。", "cmd.root.short": "GitLink CLI - GitLink 命令行工具", + "cmd.search.issues.short": "搜索仓库议题", "cmd.search.repos.short": "搜索仓库", "cmd.search.short": "搜索操作", "cmd.search.users.short": "搜索用户", + "cmd.user.headmaps.short": "显示用户贡献热力图", "cmd.user.info.short": "显示用户资料", "cmd.user.me.short": "显示当前认证用户", "cmd.user.short": "用户操作", + "cmd.user.stats_activity.short": "显示用户活动统计", + "cmd.user.stats_develop.short": "显示用户开发能力", + "cmd.user.stats_major.short": "显示用户专业/学科定位", + "cmd.user.stats_role.short": "显示用户角色定位", + "cmd.user.trends.short": "显示用户项目活动趋势", "cmd.version.short": "打印版本信息", "cmd.webhook.create.short": "创建仓库 Webhook", "cmd.webhook.delete.short": "删除仓库 Webhook", @@ -150,13 +160,36 @@ "flag.issue.assignee": "负责人登录名", "flag.issue.assignee_id": "负责人用户 ID", "flag.issue.author_id": "作者用户 ID", - "flag.issue.batch.reason": "批量结果中显示的可选原因", - "flag.issue.batch.yes": "执行远端操作。未传入该参数时仅 dry-run。", - "flag.issue.batch_close.older_than_days": "必需的安全筛选条件;至少为 7", + "flag.issue.batch.confirm": "确认执行批量操作", + "flag.issue.batch.delay": "请求间隔(毫秒)", + "flag.issue.batch.dry_run": "预览将被修改的议题,不实际执行", + "flag.issue.batch.from": "从 CSV 文件读取议题编号(支持 number/issue_number/project_issues_index 列)", + "flag.issue.batch.label": "按标签名筛选", + "flag.issue.batch.max": "最多处理的议题数", + "flag.issue.batch.numbers": "议题编号列表(逗号分隔),例如 1,2,3", + "flag.issue.batch.search": "按关键词搜索议题", + "flag.issue.batch.state": "按状态筛选:open、closed、all", + "flag.issue.batch_assign.assignee": "负责人用户名或 ID(统一模式)", + "flag.issue.batch_assign.csv": "CSV 文件(含 number,assignee 列)", + "flag.issue.batch_assign.numbers": "议题编号列表(逗号分隔)", "flag.issue.batch_close.state": "关闭前按议题状态筛选", - "flag.issue.batch_label.state": "按议题状态筛选", - "flag.issue.batch_list.limit": "最多返回的议题数,上限 100", - "flag.issue.batch_process.limit": "最多处理的议题数,上限 100", + "flag.issue.batch_create.csv": "含议题数据的 CSV 文件", + "flag.issue.batch_create.print_schema": "打印 CSV 表头并退出", + "flag.issue.batch_delete.confirm": "确认删除(安全必需)", + "flag.issue.batch_delete.dry_run": "预览删除,不实际执行", + "flag.issue.batch_delete.ids": "议题 ID 列表(逗号分隔)", + "flag.issue.batch_label.action": "操作类型:add、remove 或 set", + "flag.issue.batch_label.csv": "含议题编号的 CSV 文件路径", + "flag.issue.batch_label.label_ids": "标签 ID 列表(逗号分隔,与 --labels 互斥)", + "flag.issue.batch_label.labels": "标签名列表(逗号分隔)", + "flag.issue.batch_label.numbers": "议题编号列表(逗号分隔)", + "flag.issue.batch_update.assignees": "负责人用户 ID 列表(逗号分隔)", + "flag.issue.batch_update.csv": "含更新数据的 CSV 文件路径", + "flag.issue.batch_update.ids": "议题 ID 列表(逗号分隔)", + "flag.issue.batch_update.milestone": "里程碑 ID", + "flag.issue.batch_update.priority": "优先级 ID", + "flag.issue.batch_update.status": "新状态:open 或 closed", + "flag.issue.batch_update.tags": "标签/标记 ID 列表(逗号分隔)", "flag.issue.body": "议题描述", "flag.issue.label": "标签 ID", "flag.issue.label_filter": "按已有标签筛选", @@ -214,6 +247,11 @@ "flag.repo.private": "设为私有仓库(true/false)", "flag.repo.tree.path": "要列出的目录路径(默认:仓库根目录)", "flag.repo.tree.ref": "分支、标签或提交引用", + "flag.search.issues.assignee": "按负责人用户 ID 筛选", + "flag.search.issues.author": "按作者用户 ID 筛选", + "flag.search.issues.category": "议题分类:all、opened、closed", + "flag.search.issues.milestone": "按里程碑 ID 筛选", + "flag.search.issues.tag": "按标签 ID 筛选(逗号分隔)", "flag.search.keyword": "搜索关键词", "flag.sort_by": "排序字段", "flag.sort_direction": "排序方向:asc、desc", diff --git a/shortcuts/issue/batch.go b/shortcuts/issue/batch.go index c5021d7..c544053 100644 --- a/shortcuts/issue/batch.go +++ b/shortcuts/issue/batch.go @@ -1,16 +1,17 @@ package issue import ( + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) const closeIssueStatusID = 5 -func newBatchCloseShortcut() *common.Shortcut { +func newBatchCloseShortcut(tr *i18n.Translator) *common.Shortcut { return &common.Shortcut{ Name: "batch-close", - Description: "Close multiple issues by issue numbers or a CSV file", - Flags: batchStateFlags(), + Description: tr.T("cmd.issue.batch_close.short"), + Flags: batchStateFlags(tr), Run: func(ctx *common.RuntimeContext) error { return runBatchStateChange(ctx, "close", closeIssueStatusID) }, } } diff --git a/shortcuts/issue/batch_assign.go b/shortcuts/issue/batch_assign.go index bb3d8f6..87a87dc 100644 --- a/shortcuts/issue/batch_assign.go +++ b/shortcuts/issue/batch_assign.go @@ -3,28 +3,26 @@ package issue import ( "fmt" "os" - "strconv" "strings" + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) -func newBatchAssignShortcut() *common.Shortcut { +func newBatchAssignShortcut(tr *i18n.Translator) *common.Shortcut { + flags := []common.Flag{ + {Name: "numbers", Short: "n", Usage: tr.T("flag.issue.batch_assign.numbers")}, + {Name: "from", Usage: tr.T("flag.issue.batch_assign.csv")}, + {Name: "search", Usage: tr.T("flag.issue.batch.search")}, + {Name: "state", Usage: tr.T("flag.issue.batch.state")}, + {Name: "assignee", Short: "a", Usage: tr.T("flag.issue.batch_assign.assignee")}, + } + flags = append(flags, batchRuntimeFlags(tr)...) return &common.Shortcut{ Name: "batch-assign", - Description: "Assign issues to a user or via CSV", - Flags: []common.Flag{ - {Name: "numbers", Short: "n", Usage: "Comma-separated issue numbers"}, - {Name: "from", Usage: "CSV file with number,assignee columns"}, - {Name: "search", Usage: "Search keyword"}, - {Name: "state", Usage: "State filter for --search"}, - {Name: "assignee", Short: "a", Usage: "Assignee username or ID (uniform mode)"}, - {Name: "dry-run", Usage: "Preview", Bool: true, Default: "false"}, - {Name: "confirm", Usage: "Confirm", Bool: true, Default: "false"}, - {Name: "max", Usage: "Max items", Default: strconv.Itoa(defaultBatchMaxItems)}, - {Name: "delay", Usage: "Delay ms", Default: strconv.Itoa(defaultBatchDelayMs)}, - }, - Run: runBatchAssign, + Description: tr.T("cmd.issue.batch_assign.short"), + Flags: flags, + Run: runBatchAssign, } } diff --git a/shortcuts/issue/batch_common.go b/shortcuts/issue/batch_common.go index cdc3000..01be3af 100644 --- a/shortcuts/issue/batch_common.go +++ b/shortcuts/issue/batch_common.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) @@ -39,17 +40,27 @@ func parseBatchOptions(ctx *common.RuntimeContext) BatchOptions { } // batchStateFlags 返回 batch 状态变更命令(close、open)共用的 flag 列表。 -func batchStateFlags() []common.Flag { +func batchStateFlags(tr *i18n.Translator) []common.Flag { return []common.Flag{ - {Name: "numbers", Short: "n", Usage: "Comma-separated issue numbers from the web URL, for example: 1,2,3"}, - {Name: "from", Usage: "Read issue numbers from a CSV file. Supports a number/issue_number/project_issues_index column or first column without header"}, - {Name: "search", Usage: "Search issues by keyword"}, - {Name: "state", Usage: "Filter by state: open, closed, all"}, - {Name: "label", Usage: "Filter by label name"}, - {Name: "confirm", Usage: "Confirm batch operation", Bool: true, Default: "false"}, - {Name: "max", Usage: "Maximum number of issues to process", Default: strconv.Itoa(defaultBatchMaxItems)}, - {Name: "delay", Usage: "Delay in milliseconds between requests", Default: strconv.Itoa(defaultBatchDelayMs)}, - {Name: "dry-run", Usage: "Preview the issues that would be changed without making any changes", Bool: true, Default: "false"}, + {Name: "numbers", Short: "n", Usage: tr.T("flag.issue.batch.numbers")}, + {Name: "from", Usage: tr.T("flag.issue.batch.from")}, + {Name: "search", Usage: tr.T("flag.issue.batch.search")}, + {Name: "state", Usage: tr.T("flag.issue.batch.state")}, + {Name: "label", Usage: tr.T("flag.issue.batch.label")}, + {Name: "confirm", Usage: tr.T("flag.issue.batch.confirm"), Bool: true, Default: "false"}, + {Name: "max", Usage: tr.T("flag.issue.batch.max"), Default: strconv.Itoa(defaultBatchMaxItems)}, + {Name: "delay", Usage: tr.T("flag.issue.batch.delay"), Default: strconv.Itoa(defaultBatchDelayMs)}, + {Name: "dry-run", Usage: tr.T("flag.issue.batch.dry_run"), Bool: true, Default: "false"}, + } +} + +// batchRuntimeFlags 返回各 batch 命令共用的运行时 flag(dry-run/confirm/max/delay)。 +func batchRuntimeFlags(tr *i18n.Translator) []common.Flag { + return []common.Flag{ + {Name: "dry-run", Usage: tr.T("flag.issue.batch.dry_run"), Bool: true, Default: "false"}, + {Name: "confirm", Usage: tr.T("flag.issue.batch.confirm"), Bool: true, Default: "false"}, + {Name: "max", Usage: tr.T("flag.issue.batch.max"), Default: strconv.Itoa(defaultBatchMaxItems)}, + {Name: "delay", Usage: tr.T("flag.issue.batch.delay"), Default: strconv.Itoa(defaultBatchDelayMs)}, } } diff --git a/shortcuts/issue/batch_create.go b/shortcuts/issue/batch_create.go index 899aba3..60e39a2 100644 --- a/shortcuts/issue/batch_create.go +++ b/shortcuts/issue/batch_create.go @@ -7,22 +7,21 @@ import ( "strings" "time" + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) -func newBatchCreateShortcut() *common.Shortcut { +func newBatchCreateShortcut(tr *i18n.Translator) *common.Shortcut { + flags := []common.Flag{ + {Name: "from", Short: "f", Usage: tr.T("flag.issue.batch_create.csv"), Required: true}, + {Name: "print-schema", Usage: tr.T("flag.issue.batch_create.print_schema"), Bool: true, Default: "false"}, + } + flags = append(flags, batchRuntimeFlags(tr)...) return &common.Shortcut{ Name: "batch-create", - Description: "Create multiple issues from CSV", - Flags: []common.Flag{ - {Name: "from", Short: "f", Usage: "CSV file with issue data", Required: true}, - {Name: "print-schema", Usage: "Print CSV header and exit", Bool: true, Default: "false"}, - {Name: "dry-run", Usage: "Preview", Bool: true, Default: "false"}, - {Name: "confirm", Usage: "Confirm", Bool: true, Default: "false"}, - {Name: "max", Usage: "Max items", Default: strconv.Itoa(defaultBatchMaxItems)}, - {Name: "delay", Usage: "Delay ms", Default: strconv.Itoa(defaultBatchDelayMs)}, - }, - Run: runBatchCreate, + Description: tr.T("cmd.issue.batch_create.short"), + Flags: flags, + Run: runBatchCreate, } } diff --git a/shortcuts/issue/batch_delete.go b/shortcuts/issue/batch_delete.go index 80864c3..6f01229 100644 --- a/shortcuts/issue/batch_delete.go +++ b/shortcuts/issue/batch_delete.go @@ -5,17 +5,18 @@ import ( "strconv" "strings" + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) -func newBatchDeleteShortcut() *common.Shortcut { +func newBatchDeleteShortcut(tr *i18n.Translator) *common.Shortcut { return &common.Shortcut{ Name: "batch-delete", - Description: "Batch delete multiple issues (use with caution)", + Description: tr.T("cmd.issue.batch_delete.short"), Flags: []common.Flag{ - {Name: "ids", Short: "i", Usage: "Comma-separated issue IDs", Required: true}, - {Name: "dry-run", Usage: "Preview deletion without executing", Bool: true, Default: "false"}, - {Name: "confirm", Usage: "Confirm deletion (required for safety)", Bool: true, Default: "false"}, + {Name: "ids", Short: "i", Usage: tr.T("flag.issue.batch_delete.ids"), Required: true}, + {Name: "dry-run", Usage: tr.T("flag.issue.batch_delete.dry_run"), Bool: true, Default: "false"}, + {Name: "confirm", Usage: tr.T("flag.issue.batch_delete.confirm"), Bool: true, Default: "false"}, }, Run: runBatchDelete, } diff --git a/shortcuts/issue/batch_label.go b/shortcuts/issue/batch_label.go index 349b772..08c4ca3 100644 --- a/shortcuts/issue/batch_label.go +++ b/shortcuts/issue/batch_label.go @@ -5,27 +5,26 @@ import ( "strconv" "strings" + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) -func newBatchLabelShortcut() *common.Shortcut { +func newBatchLabelShortcut(tr *i18n.Translator) *common.Shortcut { + flags := []common.Flag{ + {Name: "numbers", Short: "n", Usage: tr.T("flag.issue.batch_label.numbers")}, + {Name: "from", Usage: tr.T("flag.issue.batch_label.csv")}, + {Name: "search", Usage: tr.T("flag.issue.batch.search")}, + {Name: "state", Usage: tr.T("flag.issue.batch.state")}, + {Name: "action", Short: "a", Usage: tr.T("flag.issue.batch_label.action"), Required: true}, + {Name: "labels", Short: "l", Usage: tr.T("flag.issue.batch_label.labels")}, + {Name: "label-ids", Usage: tr.T("flag.issue.batch_label.label_ids")}, + } + flags = append(flags, batchRuntimeFlags(tr)...) return &common.Shortcut{ Name: "batch-label", - Description: "Add, remove, or set labels on multiple issues", - Flags: []common.Flag{ - {Name: "numbers", Short: "n", Usage: "Comma-separated issue numbers"}, - {Name: "from", Usage: "CSV file path with issue numbers"}, - {Name: "search", Usage: "Search keyword"}, - {Name: "state", Usage: "State filter for --search"}, - {Name: "action", Short: "a", Usage: "Action: add, remove, or set", Required: true}, - {Name: "labels", Short: "l", Usage: "Comma-separated label names"}, - {Name: "label-ids", Usage: "Comma-separated label IDs (mutually exclusive with --labels)"}, - {Name: "dry-run", Usage: "Preview", Bool: true, Default: "false"}, - {Name: "confirm", Usage: "Confirm", Bool: true, Default: "false"}, - {Name: "max", Usage: "Max items", Default: strconv.Itoa(defaultBatchMaxItems)}, - {Name: "delay", Usage: "Delay ms", Default: strconv.Itoa(defaultBatchDelayMs)}, - }, - Run: runBatchLabel, + Description: tr.T("cmd.issue.batch_label.short"), + Flags: flags, + Run: runBatchLabel, } } diff --git a/shortcuts/issue/batch_open.go b/shortcuts/issue/batch_open.go index e568660..74fd55c 100644 --- a/shortcuts/issue/batch_open.go +++ b/shortcuts/issue/batch_open.go @@ -1,16 +1,17 @@ package issue import ( + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) const openIssueStatusID = 1 -func newBatchOpenShortcut() *common.Shortcut { +func newBatchOpenShortcut(tr *i18n.Translator) *common.Shortcut { return &common.Shortcut{ Name: "batch-open", - Description: "Reopen multiple issues", - Flags: batchStateFlags(), + Description: tr.T("cmd.issue.batch_open.short"), + Flags: batchStateFlags(tr), Run: func(ctx *common.RuntimeContext) error { return runBatchStateChange(ctx, "open", openIssueStatusID) }, } } diff --git a/shortcuts/issue/batch_update.go b/shortcuts/issue/batch_update.go index c624e9e..bb45a1e 100644 --- a/shortcuts/issue/batch_update.go +++ b/shortcuts/issue/batch_update.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/shortcuts/common" ) @@ -19,27 +20,24 @@ var updateFieldMapping = map[string]string{ "priority": "priority_id", } -func newBatchUpdateShortcut() *common.Shortcut { +func newBatchUpdateShortcut(tr *i18n.Translator) *common.Shortcut { + flags := []common.Flag{ + // --ids 统一模式参数 + {Name: "ids", Short: "i", Usage: tr.T("flag.issue.batch_update.ids"), Required: false}, + {Name: "status", Short: "s", Usage: tr.T("flag.issue.batch_update.status")}, + {Name: "priority", Short: "p", Usage: tr.T("flag.issue.batch_update.priority")}, + {Name: "milestone", Short: "m", Usage: tr.T("flag.issue.batch_update.milestone")}, + {Name: "labels", Short: "l", Usage: tr.T("flag.issue.batch_update.tags")}, + {Name: "assignees", Short: "a", Usage: tr.T("flag.issue.batch_update.assignees")}, + // CSV 模式参数 + {Name: "from", Usage: tr.T("flag.issue.batch_update.csv")}, + } + flags = append(flags, batchRuntimeFlags(tr)...) return &common.Shortcut{ Name: "batch-update", - Description: "Update multiple issues via CSV or --ids", - Flags: []common.Flag{ - // --ids 统一模式参数 - {Name: "ids", Short: "i", Usage: "Comma-separated issue IDs", Required: false}, - {Name: "status", Short: "s", Usage: "New status: open or closed"}, - {Name: "priority", Short: "p", Usage: "Priority ID"}, - {Name: "milestone", Short: "m", Usage: "Milestone ID"}, - {Name: "labels", Short: "l", Usage: "Comma-separated label/tag IDs"}, - {Name: "assignees", Short: "a", Usage: "Comma-separated assignee user IDs"}, - // CSV 模式参数 - {Name: "from", Usage: "CSV file path with updates"}, - // 共享参数 - {Name: "dry-run", Usage: "Preview", Bool: true, Default: "false"}, - {Name: "confirm", Usage: "Confirm", Bool: true, Default: "false"}, - {Name: "max", Usage: "Max items", Default: strconv.Itoa(defaultBatchMaxItems)}, - {Name: "delay", Usage: "Delay ms", Default: strconv.Itoa(defaultBatchDelayMs)}, - }, - Run: runBatchUpdate, + Description: tr.T("cmd.issue.batch_update.short"), + Flags: flags, + Run: runBatchUpdate, } } diff --git a/shortcuts/issue/issue.go b/shortcuts/issue/issue.go index ebf2b7b..55d9a7a 100644 --- a/shortcuts/issue/issue.go +++ b/shortcuts/issue/issue.go @@ -51,13 +51,13 @@ func normalizeIssueListState(state string) string { func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut { tr := shortcutTranslator(translators...) return []*common.Shortcut{ - newBatchCreateShortcut(), - newBatchCloseShortcut(), - newBatchOpenShortcut(), - newBatchAssignShortcut(), - newBatchLabelShortcut(), - newBatchUpdateShortcut(), - newBatchDeleteShortcut(), + newBatchCreateShortcut(tr), + newBatchCloseShortcut(tr), + newBatchOpenShortcut(tr), + newBatchAssignShortcut(tr), + newBatchLabelShortcut(tr), + newBatchUpdateShortcut(tr), + newBatchDeleteShortcut(tr), { Name: "list", Description: tr.T("cmd.issue.list.short"), diff --git a/shortcuts/search/search.go b/shortcuts/search/search.go index 820e1a9..5814783 100644 --- a/shortcuts/search/search.go +++ b/shortcuts/search/search.go @@ -55,18 +55,18 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut { }, { Name: "issues", - Description: "Search issues in a repository", + Description: tr.T("cmd.search.issues.short"), Flags: []common.Flag{ - {Name: "keyword", Short: "k", Usage: "Search keyword", Required: true}, - {Name: "category", Short: "c", Usage: "Issue category: all, opened, closed", Default: "all"}, - {Name: "assignee", Short: "a", Usage: "Filter by assignee user ID"}, - {Name: "author", Usage: "Filter by author user ID"}, - {Name: "milestone", Short: "m", Usage: "Filter by milestone ID"}, - {Name: "tag", Short: "t", Usage: "Filter by tag IDs (comma-separated)"}, - {Name: "sort-by", Usage: "Sort field: updated_on, created_on, priority", Default: "updated_on"}, - {Name: "sort-dir", Usage: "Sort direction: asc, desc", Default: "desc"}, - {Name: "page", Short: "p", Usage: "Page number", Default: "1"}, - {Name: "limit", Short: "l", Usage: "Items per page", Default: "20"}, + {Name: "keyword", Short: "k", Usage: tr.T("flag.search.keyword"), Required: true}, + {Name: "category", Short: "c", Usage: tr.T("flag.search.issues.category"), Default: "all"}, + {Name: "assignee", Short: "a", Usage: tr.T("flag.search.issues.assignee")}, + {Name: "author", Usage: tr.T("flag.search.issues.author")}, + {Name: "milestone", Short: "m", Usage: tr.T("flag.search.issues.milestone")}, + {Name: "tag", Short: "t", Usage: tr.T("flag.search.issues.tag")}, + {Name: "sort-by", Usage: tr.T("flag.sort_by"), Default: "updated_on"}, + {Name: "sort-dir", Usage: tr.T("flag.sort_direction"), Default: "desc"}, + {Name: "page", Short: "p", Usage: tr.T("flag.page"), Default: "1"}, + {Name: "limit", Short: "l", Usage: tr.T("flag.limit"), Default: "20"}, }, Run: func(ctx *common.RuntimeContext) error { if err := ctx.ResolveOwnerRepo(); err != nil { diff --git a/shortcuts/user/user.go b/shortcuts/user/user.go index 5870d33..7591f73 100644 --- a/shortcuts/user/user.go +++ b/shortcuts/user/user.go @@ -42,9 +42,9 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut { }, { Name: "headmaps", - Description: "Show user contribution heatmap", + Description: tr.T("cmd.user.headmaps.short"), Flags: []common.Flag{ - {Name: "login", Short: "l", Usage: "User login name", Required: true}, + {Name: "login", Short: "l", Usage: tr.T("flag.user.login"), Required: true}, }, Run: func(ctx *common.RuntimeContext) error { login, err := ctx.RequireArg("login") @@ -58,17 +58,17 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut { return ctx.Output(env) }, }, - newStatsShortcut("stats-activity", "Show user activity statistics", "activity"), - newStatsShortcut("stats-develop", "Show user development capability", "develop"), - newStatsShortcut("stats-role", "Show user role positioning", "role"), - newStatsShortcut("stats-major", "Show user major positioning", "major"), + newStatsShortcut(tr, "stats-activity", tr.T("cmd.user.stats_activity.short"), "activity"), + newStatsShortcut(tr, "stats-develop", tr.T("cmd.user.stats_develop.short"), "develop"), + newStatsShortcut(tr, "stats-role", tr.T("cmd.user.stats_role.short"), "role"), + newStatsShortcut(tr, "stats-major", tr.T("cmd.user.stats_major.short"), "major"), { Name: "trends", - Description: "Show user project activity trends", + Description: tr.T("cmd.user.trends.short"), Flags: []common.Flag{ - {Name: "login", Short: "l", Usage: "User login name", Required: true}, - {Name: "page", Short: "p", Usage: "Page number", Default: "1"}, - {Name: "limit", Usage: "Items per page", Default: "20"}, + {Name: "login", Short: "l", Usage: tr.T("flag.user.login"), Required: true}, + {Name: "page", Short: "p", Usage: tr.T("flag.page"), Default: "1"}, + {Name: "limit", Usage: tr.T("flag.limit"), Default: "20"}, }, Run: func(ctx *common.RuntimeContext) error { login, err := ctx.RequireArg("login") @@ -89,12 +89,12 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut { } // newStatsShortcut 生成用户统计类 shortcut,消除 stats-activity/develop/role/major 的重复代码。 -func newStatsShortcut(name, desc, subPath string) *common.Shortcut { +func newStatsShortcut(tr *i18n.Translator, name, desc, subPath string) *common.Shortcut { return &common.Shortcut{ Name: name, Description: desc, Flags: []common.Flag{ - {Name: "login", Short: "l", Usage: "User login name", Required: true}, + {Name: "login", Short: "l", Usage: tr.T("flag.user.login"), Required: true}, }, Run: func(ctx *common.RuntimeContext) error { login, err := ctx.RequireArg("login")