feat(i18n): translate the usage template as well

This should keep backwards compat'.
This commit is contained in:
Goutte 2023-04-04 09:04:29 +02:00
parent d6ed0816a9
commit 0abea784c4
5 changed files with 219 additions and 13 deletions

View file

@ -68,7 +68,7 @@ func minimumNArgsWithLessArgs(err error, t *testing.T) {
t.Fatal("Expected an error")
}
got := err.Error()
expected := "requires at least 2 arg(s), only received 1"
expected := "requires at least 2 args, only received 1"
if got != expected {
t.Fatalf("Expected %q, got %q", expected, got)
}
@ -79,7 +79,7 @@ func maximumNArgsWithMoreArgs(err error, t *testing.T) {
t.Fatal("Expected an error")
}
got := err.Error()
expected := "accepts at most 2 arg(s), received 3"
expected := "accepts at most 2 args, received 3"
if got != expected {
t.Fatalf("Expected %q, got %q", expected, got)
}
@ -90,7 +90,7 @@ func exactArgsWithInvalidCount(err error, t *testing.T) {
t.Fatal("Expected an error")
}
got := err.Error()
expected := "accepts 2 arg(s), received 3"
expected := "accepts 2 args, received 3"
if got != expected {
t.Fatalf("Expected %q, got %q", expected, got)
}
@ -101,7 +101,7 @@ func rangeArgsWithInvalidCount(err error, t *testing.T) {
t.Fatal("Expected an error")
}
got := err.Error()
expected := "accepts between 2 and 4 arg(s), received 1"
expected := "accepts between 2 and 4 args, received 1"
if got != expected {
t.Fatalf("Expected %q, got %q", expected, got)
}

View file

@ -252,6 +252,8 @@ type Command struct {
// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
// Must be > 0.
SuggestionsMinimumDistance int
I18n *i18nCommandGlossary
}
// Context returns underlying command context. If command was executed
@ -542,6 +544,7 @@ func (c *Command) NamePadding() int {
// UsageTemplate returns usage template for the command.
func (c *Command) UsageTemplate() string {
c.I18n = getCommandGlossary()
if c.usageTemplate != "" {
return c.usageTemplate
}
@ -549,35 +552,35 @@ func (c *Command) UsageTemplate() string {
if c.HasParent() {
return c.parent.UsageTemplate()
}
return `Usage:{{if .Runnable}}
return `{{.I18n.SectionUsage}}:{{if .Runnable}}
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
Aliases:
{{.I18n.SectionAliases}}:
{{.NameAndAliases}}{{end}}{{if .HasExample}}
Examples:
{{.I18n.SectionExamples}}:
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}}
Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{.I18n.SectionAvailableCommands}}:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}}
{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}}
Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
{{.I18n.SectionAdditionalCommands}}:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
Flags:
{{.I18n.SectionFlags}}:
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
Global Flags:
{{.I18n.SectionGlobalFlags}}:
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{.I18n.SectionAdditionalHelpTopics}}:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
{{.I18n.Use}} "{{.CommandPath}} [command] --help" {{.I18n.ForInfoAboutCommand}}.{{end}}
`
}

View file

@ -27,6 +27,119 @@ var localeFS embed.FS
// Localizer can be used to fetch localized messages
var localizer *i18n.Localizer
type i18nCommandGlossary struct {
SectionUsage string
SectionAliases string
SectionExamples string
SectionAvailableCommands string
SectionAdditionalCommands string
SectionFlags string
SectionGlobalFlags string
SectionAdditionalHelpTopics string
Use string
ForInfoAboutCommand string
}
var commonCommandGlossary *i18nCommandGlossary
func getCommandGlossary() *i18nCommandGlossary {
if commonCommandGlossary == nil {
commonCommandGlossary = &i18nCommandGlossary{
SectionUsage: i18nSectionUsage(),
SectionAliases: i18nSectionAliases(),
SectionExamples: i18nSectionExamples(),
SectionAvailableCommands: i18nSectionAvailableCommands(),
SectionAdditionalCommands: i18nSectionAdditionalCommands(),
SectionFlags: i18nSectionFlags(),
SectionGlobalFlags: i18nSectionGlobalFlags(),
SectionAdditionalHelpTopics: i18nSectionAdditionalHelpTopics(),
Use: i18nUse(),
ForInfoAboutCommand: i18nForInfoAboutCommand(),
}
}
return commonCommandGlossary
}
func i18nSectionUsage() string {
return localizeMessage(&i18n.Message{
ID: "SectionUsage",
Description: "title of the section in the usage template",
Other: "Usage",
})
}
func i18nSectionAliases() string {
return localizeMessage(&i18n.Message{
ID: "SectionAliases",
Description: "title of the section in the usage template",
Other: "Aliases",
})
}
func i18nSectionExamples() string {
return localizeMessage(&i18n.Message{
ID: "SectionExamples",
Description: "title of the section in the usage template",
Other: "Examples",
})
}
func i18nSectionAvailableCommands() string {
return localizeMessage(&i18n.Message{
ID: "SectionAvailableCommands",
Description: "title of the section in the usage template",
Other: "Available Commands",
})
}
func i18nSectionAdditionalCommands() string {
return localizeMessage(&i18n.Message{
ID: "SectionAdditionalCommands",
Description: "title of the section in the usage template",
Other: "Additional Commands",
})
}
func i18nSectionFlags() string {
return localizeMessage(&i18n.Message{
ID: "SectionFlags",
Description: "title of the section in the usage template",
Other: "Flags",
})
}
func i18nSectionGlobalFlags() string {
return localizeMessage(&i18n.Message{
ID: "SectionGlobalFlags",
Description: "title of the section in the usage template",
Other: "Global Flags",
})
}
func i18nSectionAdditionalHelpTopics() string {
return localizeMessage(&i18n.Message{
ID: "SectionAdditionalHelpTopics",
Description: "title of the section in the usage template",
Other: "Additional Help Topics",
})
}
func i18nUse() string {
return localizeMessage(&i18n.Message{
ID: "Use",
Description: "beginning of a sentence like 'Use <this> to do <that>'",
Other: "Use",
})
}
func i18nForInfoAboutCommand() string {
return localizeMessage(&i18n.Message{
ID: "ForInfoAboutCommand",
Description: "end of a sentence",
Other: "for more information about a command",
})
}
func i18nError() string {
return localizeMessage(&i18n.Message{
ID: "Error",

View file

@ -11,6 +11,10 @@ other = "accepts %d args, received %d"
description = "error shown when multiple exclusive flags are provided (group flags, offending flags)"
other = "if any flags in the group [%v] are set none of the others can be; %v were all set"
[ForInfoAboutCommand]
description = "end of a sentence"
other = "for more information about a command"
[LegacyArgsValidationError]
description = "error shown when args are not understood (subcmd, cmd, suggestion)"
other = "unknown command %q for %q%s"
@ -41,3 +45,39 @@ other = "accepts between %d and %d args, received %d"
[RunHelpTip]
description = "tip shown when a command fails (command path)"
other = "Run '%v --help' for usage."
[SectionAdditionalCommands]
description = "title of the section in the usage template"
other = "Additional Commands"
[SectionAdditionalHelpTopics]
description = "title of the section in the usage template"
other = "Additional Help Topics"
[SectionAliases]
description = "title of the section in the usage template"
other = "Aliases"
[SectionAvailableCommands]
description = "title of the section in the usage template"
other = "Available Commands"
[SectionExamples]
description = "title of the section in the usage template"
other = "Examples"
[SectionFlags]
description = "title of the section in the usage template"
other = "Flags"
[SectionGlobalFlags]
description = "title of the section in the usage template"
other = "Global Flags"
[SectionUsage]
description = "title of the section in the usage template"
other = "Usage"
[Use]
description = "beginning of a sentence like 'Use <this> to do <that>'"
other = "Use"

View file

@ -14,6 +14,11 @@ description = "error shown when multiple exclusive flags are provided (group fla
hash = "sha1-221b98bada52cfc2932f9aa5142b653b46baded6"
other = "les options [%v] sont exclusives, mais les options %v ont été fournies"
[ForInfoAboutCommand]
description = "end of a sentence"
hash = "sha1-923f6d48908b3a6981fb5504b0e5078700a312c0"
other = "pour plus d'information au sujet d'une commande"
[LegacyArgsValidationError]
description = "error shown when args are not understood (subcmd, cmd, suggestion)"
hash = "sha1-c601c68bdcb9687109e793112b789b1858953b15"
@ -51,3 +56,48 @@ other = "accepte entre %d et %d args, mais en a reçu %d"
description = "tip shown when a command fails (command path)"
hash = "sha1-e1d2c4cccd484df365c3249347d5172981929b88"
other = "Essayez '%v --help' pour obtenir de l'aide."
[SectionAdditionalCommands]
description = "title of the section in the usage template"
hash = "sha1-730484f22c7ce0885ca13a3b8222b231dc29a4a9"
other = "Commandes Connexes"
[SectionAdditionalHelpTopics]
description = "title of the section in the usage template"
hash = "sha1-615c9551f4dcd30836fbe04506e0b807c59dd901"
other = "Autres Sujets"
[SectionAliases]
description = "title of the section in the usage template"
hash = "sha1-3c66c036f454cb3d23f757c430a5c05b148dc01f"
other = "Alias"
[SectionAvailableCommands]
description = "title of the section in the usage template"
hash = "sha1-fc33c38777373e51c9c84c8594efb5de4df0f23e"
other = "Commandes Disponibles"
[SectionExamples]
description = "title of the section in the usage template"
hash = "sha1-6e2f0c7dddc3ce6aacb1184b3b21694492d6595a"
other = "Exemples"
[SectionFlags]
description = "title of the section in the usage template"
hash = "sha1-5513ed25ed4e1ad2e569ff4c963bba347320e9f7"
other = "Options"
[SectionGlobalFlags]
description = "title of the section in the usage template"
hash = "sha1-705f1ebcdce1374e23f41bc8e0e14e5197ac1742"
other = "Options Globales"
[SectionUsage]
description = "title of the section in the usage template"
hash = "sha1-5fdae7bd171315a453063384887ee4300363cf20"
other = "Usage"
[Use]
description = "beginning of a sentence like 'Use <this> to do <that>'"
hash = "sha1-f42c92acc9934eec952161dfa338a95ec0f02b75"
other = "Utilisez"