refactor(go): use i18n grammar engine instead of translation keys

Replace hardcoded i18n.T() key lookups with grammar helpers:
- i18n.Label("test") → "Test:"
- i18n.Progress("install") → "Installing..."
- i18n.ProgressSubject("run", "tests") → "Running tests..."
- i18n.T("i18n.done.pass") → "Passed"
- i18n.T("i18n.fail.install", "binary") → "Failed to install binary"
- i18n.T("i18n.count.check", n) → "5 checks"

The grammar engine computes verb forms (past tense, gerund) and
noun forms (plurals) automatically from built-in tables, eliminating
the need for hundreds of individual translation keys.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-01-30 22:43:39 +00:00
parent 0fd76d86b4
commit 3dd61b5ac7
4 changed files with 89 additions and 88 deletions

View file

@ -17,8 +17,8 @@ var (
func addGoFmtCommand(parent *cobra.Command) {
fmtCmd := &cobra.Command{
Use: "fmt",
Short: i18n.T("cmd.go.fmt.short"),
Long: i18n.T("cmd.go.fmt.long"),
Short: "Format Go code",
Long: "Format Go code using goimports or gofmt",
RunE: func(cmd *cobra.Command, args []string) error {
fmtArgs := []string{}
if fmtFix {
@ -46,9 +46,9 @@ func addGoFmtCommand(parent *cobra.Command) {
},
}
fmtCmd.Flags().BoolVar(&fmtFix, "fix", false, i18n.T("cmd.go.fmt.flag.fix"))
fmtCmd.Flags().BoolVar(&fmtDiff, "diff", false, i18n.T("common.flag.diff"))
fmtCmd.Flags().BoolVar(&fmtCheck, "check", false, i18n.T("cmd.go.fmt.flag.check"))
fmtCmd.Flags().BoolVar(&fmtFix, "fix", false, i18n.T("common.flag.fix"))
fmtCmd.Flags().BoolVar(&fmtDiff, "diff", false, "Show diff of changes")
fmtCmd.Flags().BoolVar(&fmtCheck, "check", false, "Check if formatted (exit 1 if not)")
parent.AddCommand(fmtCmd)
}
@ -58,8 +58,8 @@ var lintFix bool
func addGoLintCommand(parent *cobra.Command) {
lintCmd := &cobra.Command{
Use: "lint",
Short: i18n.T("cmd.go.lint.short"),
Long: i18n.T("cmd.go.lint.long"),
Short: "Run golangci-lint",
Long: "Run golangci-lint for comprehensive static analysis",
RunE: func(cmd *cobra.Command, args []string) error {
lintArgs := []string{"run"}
if lintFix {
@ -73,7 +73,7 @@ func addGoLintCommand(parent *cobra.Command) {
},
}
lintCmd.Flags().BoolVar(&lintFix, "fix", false, i18n.T("cmd.go.lint.flag.fix"))
lintCmd.Flags().BoolVar(&lintFix, "fix", false, i18n.T("common.flag.fix"))
parent.AddCommand(lintCmd)
}

View file

@ -27,20 +27,20 @@ var (
func addGoTestCommand(parent *cobra.Command) {
testCmd := &cobra.Command{
Use: "test",
Short: i18n.T("cmd.go.test.short"),
Long: i18n.T("cmd.go.test.long"),
Short: "Run Go tests",
Long: "Run Go tests with optional coverage, filtering, and race detection",
RunE: func(cmd *cobra.Command, args []string) error {
return runGoTest(testCoverage, testPkg, testRun, testShort, testRace, testJSON, testVerbose)
},
}
testCmd.Flags().BoolVar(&testCoverage, "coverage", false, i18n.T("common.flag.coverage"))
testCmd.Flags().StringVar(&testPkg, "pkg", "", i18n.T("common.flag.pkg"))
testCmd.Flags().StringVar(&testRun, "run", "", i18n.T("cmd.go.test.flag.run"))
testCmd.Flags().BoolVar(&testShort, "short", false, i18n.T("cmd.go.test.flag.short"))
testCmd.Flags().BoolVar(&testRace, "race", false, i18n.T("cmd.go.test.flag.race"))
testCmd.Flags().BoolVar(&testJSON, "json", false, i18n.T("cmd.go.test.flag.json"))
testCmd.Flags().BoolVarP(&testVerbose, "verbose", "v", false, i18n.T("common.flag.verbose"))
testCmd.Flags().BoolVar(&testCoverage, "coverage", false, "Generate coverage report")
testCmd.Flags().StringVar(&testPkg, "pkg", "", "Package to test")
testCmd.Flags().StringVar(&testRun, "run", "", "Run only tests matching pattern")
testCmd.Flags().BoolVar(&testShort, "short", false, "Run only short tests")
testCmd.Flags().BoolVar(&testRace, "race", false, "Enable race detector")
testCmd.Flags().BoolVar(&testJSON, "json", false, "Output as JSON")
testCmd.Flags().BoolVarP(&testVerbose, "verbose", "v", false, "Verbose output")
parent.AddCommand(testCmd)
}
@ -74,8 +74,8 @@ func runGoTest(coverage bool, pkg, run string, short, race, jsonOut, verbose boo
args = append(args, pkg)
if !jsonOut {
fmt.Printf("%s %s\n", dimStyle.Render(i18n.T("common.label.test")), i18n.T("common.progress.running", map[string]any{"Task": "tests"}))
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.T("common.label.package")), pkg)
fmt.Printf("%s %s\n", dimStyle.Render(i18n.Label("test")), i18n.ProgressSubject("run", "tests"))
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.Label("package")), pkg)
fmt.Println()
}
@ -114,19 +114,21 @@ func runGoTest(coverage bool, pkg, run string, short, race, jsonOut, verbose boo
// Summary
if err == nil {
fmt.Printf(" %s %s\n", successStyle.Render("✓"), i18n.T("common.count.passed", map[string]interface{}{"Count": passed}))
fmt.Printf(" %s %s\n", successStyle.Render(cli.SymbolCheck), i18n.T("i18n.count.test", passed)+" "+i18n.T("i18n.done.pass"))
} else {
fmt.Printf(" %s %s\n", errorStyle.Render("✗"), i18n.T("cmd.go.test.passed_failed", map[string]interface{}{"Passed": passed, "Failed": failed}))
fmt.Printf(" %s %s, %s\n", errorStyle.Render(cli.SymbolCross),
i18n.T("i18n.count.test", passed)+" "+i18n.T("i18n.done.pass"),
i18n.T("i18n.count.test", failed)+" "+i18n.T("i18n.done.fail"))
}
if cov > 0 {
fmt.Printf("\n %s %s\n", cli.ProgressLabel(i18n.T("cmd.go.test.coverage")), cli.FormatCoverage(cov))
fmt.Printf("\n %s %s\n", cli.ProgressLabel(i18n.Label("coverage")), cli.FormatCoverage(cov))
}
if err == nil {
fmt.Printf("\n%s\n", successStyle.Render(i18n.T("cmd.go.test.all_passed")))
fmt.Printf("\n%s\n", successStyle.Render(i18n.T("i18n.done.pass")))
} else {
fmt.Printf("\n%s\n", errorStyle.Render(i18n.T("cmd.go.test.some_failed")))
fmt.Printf("\n%s\n", errorStyle.Render(i18n.T("i18n.done.fail")))
}
return err
@ -169,18 +171,18 @@ var (
func addGoCovCommand(parent *cobra.Command) {
covCmd := &cobra.Command{
Use: "cov",
Short: i18n.T("cmd.go.cov.short"),
Long: i18n.T("cmd.go.cov.long"),
Short: "Run tests with coverage report",
Long: "Run tests with detailed coverage reports, HTML output, and threshold checking",
RunE: func(cmd *cobra.Command, args []string) error {
pkg := covPkg
if pkg == "" {
// Auto-discover packages with tests
pkgs, err := findTestPackages(".")
if err != nil {
return fmt.Errorf("%s: %w", i18n.T("common.error.failed", map[string]any{"Action": "discover test packages"}), err)
return fmt.Errorf("%s: %w", i18n.T("i18n.fail.find", "test packages"), err)
}
if len(pkgs) == 0 {
return errors.New(i18n.T("cmd.go.cov.error.no_packages"))
return errors.New("no test packages found")
}
pkg = strings.Join(pkgs, " ")
}
@ -188,19 +190,19 @@ func addGoCovCommand(parent *cobra.Command) {
// Create temp file for coverage data
covFile, err := os.CreateTemp("", "coverage-*.out")
if err != nil {
return fmt.Errorf("%s: %w", i18n.T("common.error.failed", map[string]any{"Action": "create coverage file"}), err)
return fmt.Errorf("%s: %w", i18n.T("i18n.fail.create", "coverage file"), err)
}
covPath := covFile.Name()
covFile.Close()
defer os.Remove(covPath)
fmt.Printf("%s %s\n", dimStyle.Render(i18n.T("common.label.coverage")), i18n.T("common.progress.running", map[string]any{"Task": "tests with coverage"}))
fmt.Printf("%s %s\n", dimStyle.Render(i18n.Label("coverage")), i18n.ProgressSubject("run", "tests"))
// Truncate package list if too long for display
displayPkg := pkg
if len(displayPkg) > 60 {
displayPkg = displayPkg[:57] + "..."
}
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.T("common.label.package")), displayPkg)
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.Label("package")), displayPkg)
fmt.Println()
// Run tests with coverage
@ -222,7 +224,7 @@ func addGoCovCommand(parent *cobra.Command) {
if testErr != nil {
return testErr
}
return fmt.Errorf("%s: %w", i18n.T("common.error.failed", map[string]any{"Action": "get coverage"}), err)
return fmt.Errorf("%s: %w", i18n.T("i18n.fail.get", "coverage"), err)
}
// Parse total coverage from last line
@ -242,16 +244,16 @@ func addGoCovCommand(parent *cobra.Command) {
// Print coverage summary
fmt.Println()
fmt.Printf(" %s %s\n", cli.ProgressLabel(i18n.T("label.total")), cli.FormatCoverage(totalCov))
fmt.Printf(" %s %s\n", cli.ProgressLabel(i18n.Label("total")), cli.FormatCoverage(totalCov))
// Generate HTML if requested
if covHTML || covOpen {
htmlPath := "coverage.html"
htmlCmd := exec.Command("go", "tool", "cover", "-html="+covPath, "-o="+htmlPath)
if err := htmlCmd.Run(); err != nil {
return fmt.Errorf("%s: %w", i18n.T("common.error.failed", map[string]any{"Action": "generate HTML"}), err)
return fmt.Errorf("%s: %w", i18n.T("i18n.fail.generate", "HTML"), err)
}
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.T("cmd.go.cov.html_label")), htmlPath)
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.Label("html")), htmlPath)
if covOpen {
// Open in browser
@ -262,7 +264,7 @@ func addGoCovCommand(parent *cobra.Command) {
case exec.Command("which", "xdg-open").Run() == nil:
openCmd = exec.Command("xdg-open", htmlPath)
default:
fmt.Printf(" %s\n", dimStyle.Render(i18n.T("cmd.go.cov.open_manually")))
fmt.Printf(" %s\n", dimStyle.Render("Open coverage.html in your browser"))
}
if openCmd != nil {
openCmd.Run()
@ -272,26 +274,23 @@ func addGoCovCommand(parent *cobra.Command) {
// Check threshold
if covThreshold > 0 && totalCov < covThreshold {
fmt.Printf("\n%s\n", errorStyle.Render(i18n.T("cmd.go.cov.below_threshold", map[string]interface{}{
"Actual": fmt.Sprintf("%.1f", totalCov),
"Threshold": fmt.Sprintf("%.1f", covThreshold),
})))
return errors.New(i18n.T("cmd.go.cov.error.below_threshold"))
fmt.Printf("\n%s %.1f%% < %.1f%%\n", errorStyle.Render(i18n.T("i18n.fail.meet", "threshold")), totalCov, covThreshold)
return errors.New("coverage below threshold")
}
if testErr != nil {
return testErr
}
fmt.Printf("\n%s\n", successStyle.Render(i18n.T("cli.ok")))
fmt.Printf("\n%s\n", successStyle.Render(i18n.T("i18n.done.pass")))
return nil
},
}
covCmd.Flags().StringVar(&covPkg, "pkg", "", i18n.T("common.flag.pkg"))
covCmd.Flags().BoolVar(&covHTML, "html", false, i18n.T("cmd.go.cov.flag.html"))
covCmd.Flags().BoolVar(&covOpen, "open", false, i18n.T("cmd.go.cov.flag.open"))
covCmd.Flags().Float64Var(&covThreshold, "threshold", 0, i18n.T("cmd.go.cov.flag.threshold"))
covCmd.Flags().StringVar(&covPkg, "pkg", "", "Package to test")
covCmd.Flags().BoolVar(&covHTML, "html", false, "Generate HTML report")
covCmd.Flags().BoolVar(&covOpen, "open", false, "Open HTML report in browser")
covCmd.Flags().Float64Var(&covThreshold, "threshold", 0, "Minimum coverage percentage")
parent.AddCommand(covCmd)
}

View file

@ -17,12 +17,12 @@ var qaFix bool
func addGoQACommand(parent *cobra.Command) {
qaCmd := &cobra.Command{
Use: "qa",
Short: i18n.T("cmd.go.qa.short"),
Long: i18n.T("cmd.go.qa.long"),
Short: "Run QA checks",
Long: "Run code quality checks: formatting, vetting, linting, and testing",
RunE: runGoQADefault,
}
qaCmd.PersistentFlags().BoolVar(&qaFix, "fix", false, i18n.T("cmd.go.qa.flag.fix"))
qaCmd.PersistentFlags().BoolVar(&qaFix, "fix", false, i18n.T("common.flag.fix"))
// Subcommands for individual checks
qaCmd.AddCommand(&cobra.Command{
@ -97,16 +97,15 @@ type QACheck struct {
func runQAChecks(checkNames []string) error {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("failed to get working directory: %w", err)
return fmt.Errorf("%s: %w", i18n.T("i18n.fail.get", "working directory"), err)
}
// Detect if this is a Go project
if _, err := os.Stat("go.mod"); os.IsNotExist(err) {
return fmt.Errorf("not a Go project (no go.mod found)")
return fmt.Errorf("not a Go project (no %s found)", i18n.T("gram.word.go_mod"))
}
fmt.Println(cli.TitleStyle.Render("Go QA"))
fmt.Println()
fmt.Printf("%s %s\n\n", cli.DimStyle.Render(i18n.Label("qa")), i18n.ProgressSubject("run", "Go QA"))
checks := buildChecksForNames(checkNames)
@ -116,13 +115,13 @@ func runQAChecks(checkNames []string) error {
failed := 0
for _, check := range checks {
fmt.Printf("%s %s\n", cli.DimStyle.Render("→"), check.Name)
fmt.Printf("%s %s\n", cli.DimStyle.Render("→"), i18n.Progress(check.Name))
if err := runCheck(ctx, cwd, check); err != nil {
fmt.Printf(" %s %s\n", cli.ErrorStyle.Render(cli.SymbolCross), err.Error())
failed++
} else {
fmt.Printf(" %s\n", cli.SuccessStyle.Render(cli.SymbolCheck))
fmt.Printf(" %s %s\n", cli.SuccessStyle.Render(cli.SymbolCheck), i18n.T("i18n.done.pass"))
passed++
}
}
@ -132,15 +131,18 @@ func runQAChecks(checkNames []string) error {
duration := time.Since(startTime).Round(time.Millisecond)
if failed > 0 {
fmt.Printf("%s %d passed, %d failed (%s)\n",
fmt.Printf("%s %s, %s (%s)\n",
cli.ErrorStyle.Render(cli.SymbolCross),
passed, failed, duration)
i18n.T("i18n.count.check", passed)+" "+i18n.T("i18n.done.pass"),
i18n.T("i18n.count.check", failed)+" "+i18n.T("i18n.done.fail"),
duration)
os.Exit(1)
}
fmt.Printf("%s %d checks passed (%s)\n",
fmt.Printf("%s %s (%s)\n",
cli.SuccessStyle.Render(cli.SymbolCheck),
passed, duration)
i18n.T("i18n.count.check", passed)+" "+i18n.T("i18n.done.pass"),
duration)
return nil
}
@ -148,7 +150,7 @@ func runQAChecks(checkNames []string) error {
func buildChecksForNames(names []string) []QACheck {
allChecks := map[string]QACheck{
"fmt": {
Name: "fmt",
Name: "format",
Command: "gofmt",
Args: fmtArgs(qaFix),
},
@ -168,17 +170,17 @@ func buildChecksForNames(names []string) []QACheck {
Args: []string{"test", "./..."},
},
"race": {
Name: "race",
Name: "test",
Command: "go",
Args: []string{"test", "-race", "./..."},
},
"vuln": {
Name: "vuln",
Name: "scan",
Command: "govulncheck",
Args: []string{"./..."},
},
"sec": {
Name: "sec",
Name: "scan",
Command: "gosec",
Args: []string{"-quiet", "./..."},
},
@ -212,14 +214,14 @@ func lintArgs(fix bool) []string {
func runCheck(ctx context.Context, dir string, check QACheck) error {
// Check if command exists
if _, err := exec.LookPath(check.Command); err != nil {
return fmt.Errorf("%s not installed", check.Command)
return fmt.Errorf("%s: %s", check.Command, i18n.T("i18n.done.miss"))
}
cmd := exec.CommandContext(ctx, check.Command, check.Args...)
cmd.Dir = dir
// For gofmt -l, capture output to check if files need formatting
if check.Name == "fmt" && len(check.Args) > 0 && check.Args[0] == "-l" {
if check.Name == "format" && len(check.Args) > 0 && check.Args[0] == "-l" {
output, err := cmd.Output()
if err != nil {
return err
@ -227,7 +229,7 @@ func runCheck(ctx context.Context, dir string, check QACheck) error {
if len(output) > 0 {
// Show files that need formatting
fmt.Print(string(output))
return fmt.Errorf("files need formatting (use --fix)")
return fmt.Errorf("%s (use --fix)", i18n.T("i18n.fail.format", i18n.T("i18n.count.file", len(output))))
}
return nil
}

View file

@ -19,8 +19,8 @@ var (
func addGoInstallCommand(parent *cobra.Command) {
installCmd := &cobra.Command{
Use: "install [path]",
Short: i18n.T("cmd.go.install.short"),
Long: i18n.T("cmd.go.install.long"),
Short: "Install Go binary",
Long: "Install Go binary to $GOPATH/bin",
RunE: func(cmd *cobra.Command, args []string) error {
// Get install path from args or default to current dir
installPath := "./..."
@ -39,10 +39,10 @@ func addGoInstallCommand(parent *cobra.Command) {
}
}
fmt.Printf("%s %s\n", dimStyle.Render(i18n.T("common.label.install")), i18n.T("common.status.installing"))
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.T("common.label.path")), installPath)
fmt.Printf("%s %s\n", dimStyle.Render(i18n.Label("install")), i18n.Progress("install"))
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.Label("path")), installPath)
if installNoCgo {
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.T("cmd.go.install.cgo_label")), i18n.T("cmd.go.install.cgo_disabled"))
fmt.Printf(" %s %s\n", dimStyle.Render(i18n.Label("cgo")), "disabled")
}
cmdArgs := []string{"install"}
@ -59,7 +59,7 @@ func addGoInstallCommand(parent *cobra.Command) {
execCmd.Stderr = os.Stderr
if err := execCmd.Run(); err != nil {
fmt.Printf("\n%s\n", errorStyle.Render(i18n.T("cmd.go.install.failed")))
fmt.Printf("\n%s\n", errorStyle.Render(i18n.T("i18n.fail.install", "binary")))
return err
}
@ -71,13 +71,13 @@ func addGoInstallCommand(parent *cobra.Command) {
}
binDir := filepath.Join(gopath, "bin")
fmt.Printf("\n%s %s\n", successStyle.Render(i18n.T("cmd.go.install.success")), i18n.T("cmd.go.install.installed_to", map[string]interface{}{"Path": binDir}))
fmt.Printf("\n%s %s\n", successStyle.Render(i18n.T("i18n.done.install")), binDir)
return nil
},
}
installCmd.Flags().BoolVarP(&installVerbose, "verbose", "v", false, i18n.T("common.flag.verbose"))
installCmd.Flags().BoolVar(&installNoCgo, "no-cgo", false, i18n.T("cmd.go.install.flag.no_cgo"))
installCmd.Flags().BoolVarP(&installVerbose, "verbose", "v", false, "Verbose output")
installCmd.Flags().BoolVar(&installNoCgo, "no-cgo", false, "Disable CGO")
parent.AddCommand(installCmd)
}
@ -85,14 +85,14 @@ func addGoInstallCommand(parent *cobra.Command) {
func addGoModCommand(parent *cobra.Command) {
modCmd := &cobra.Command{
Use: "mod",
Short: i18n.T("cmd.go.mod.short"),
Long: i18n.T("cmd.go.mod.long"),
Short: "Module management",
Long: "Go module management commands",
}
// tidy
tidyCmd := &cobra.Command{
Use: "tidy",
Short: i18n.T("cmd.go.mod.tidy.short"),
Short: "Run go mod tidy",
RunE: func(cmd *cobra.Command, args []string) error {
execCmd := exec.Command("go", "mod", "tidy")
execCmd.Stdout = os.Stdout
@ -104,7 +104,7 @@ func addGoModCommand(parent *cobra.Command) {
// download
downloadCmd := &cobra.Command{
Use: "download",
Short: i18n.T("cmd.go.mod.download.short"),
Short: "Download module dependencies",
RunE: func(cmd *cobra.Command, args []string) error {
execCmd := exec.Command("go", "mod", "download")
execCmd.Stdout = os.Stdout
@ -116,7 +116,7 @@ func addGoModCommand(parent *cobra.Command) {
// verify
verifyCmd := &cobra.Command{
Use: "verify",
Short: i18n.T("cmd.go.mod.verify.short"),
Short: "Verify module checksums",
RunE: func(cmd *cobra.Command, args []string) error {
execCmd := exec.Command("go", "mod", "verify")
execCmd.Stdout = os.Stdout
@ -128,7 +128,7 @@ func addGoModCommand(parent *cobra.Command) {
// graph
graphCmd := &cobra.Command{
Use: "graph",
Short: i18n.T("cmd.go.mod.graph.short"),
Short: "Print module dependency graph",
RunE: func(cmd *cobra.Command, args []string) error {
execCmd := exec.Command("go", "mod", "graph")
execCmd.Stdout = os.Stdout
@ -147,14 +147,14 @@ func addGoModCommand(parent *cobra.Command) {
func addGoWorkCommand(parent *cobra.Command) {
workCmd := &cobra.Command{
Use: "work",
Short: i18n.T("cmd.go.work.short"),
Long: i18n.T("cmd.go.work.long"),
Short: "Workspace management",
Long: "Go workspace management commands",
}
// sync
syncCmd := &cobra.Command{
Use: "sync",
Short: i18n.T("cmd.go.work.sync.short"),
Short: "Sync workspace modules",
RunE: func(cmd *cobra.Command, args []string) error {
execCmd := exec.Command("go", "work", "sync")
execCmd.Stdout = os.Stdout
@ -166,7 +166,7 @@ func addGoWorkCommand(parent *cobra.Command) {
// init
initCmd := &cobra.Command{
Use: "init",
Short: i18n.T("cmd.go.work.init.short"),
Short: "Initialise a new workspace",
RunE: func(cmd *cobra.Command, args []string) error {
execCmd := exec.Command("go", "work", "init")
execCmd.Stdout = os.Stdout
@ -188,13 +188,13 @@ func addGoWorkCommand(parent *cobra.Command) {
// use
useCmd := &cobra.Command{
Use: "use [modules...]",
Short: i18n.T("cmd.go.work.use.short"),
Short: "Add modules to workspace",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
// Auto-detect modules
modules := findGoModules(".")
if len(modules) == 0 {
return errors.New(i18n.T("cmd.go.work.error.no_modules"))
return errors.New("no Go modules found")
}
for _, mod := range modules {
execCmd := exec.Command("go", "work", "use", mod)
@ -203,7 +203,7 @@ func addGoWorkCommand(parent *cobra.Command) {
if err := execCmd.Run(); err != nil {
return err
}
fmt.Println(i18n.T("cmd.go.work.added", map[string]interface{}{"Module": mod}))
fmt.Printf("%s %s\n", successStyle.Render(i18n.T("i18n.done.add")), mod)
}
return nil
}