Add templating for proper localization (#4677)
* Add templating for proper localization * Fixing tests for new translation style * checking errors is important * fixing more console tests * good function names make for happy developers * add test for OutTemplateStyle * short function names make for happy developers * better formatting * more better variable namespull/4732/head
parent
57f6d877ed
commit
c92e65ec28
|
@ -181,7 +181,7 @@ assumes you have already installed one of the VM drivers: virtualbox/parallels/v
|
|||
|
||||
// runStart handles the executes the flow of "minikube start"
|
||||
func runStart(cmd *cobra.Command, args []string) {
|
||||
console.OutStyle(console.Happy, "minikube %s on %s (%s)", version.GetVersion(), runtime.GOOS, runtime.GOARCH)
|
||||
console.OutT(console.Happy, "minikube {{.version}} on {{.os}} ({{.arch}})", console.Arg{"version": version.GetVersion(), "os": runtime.GOOS, "arch": runtime.GOARCH})
|
||||
validateConfig()
|
||||
|
||||
validateUser()
|
||||
|
@ -239,7 +239,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
// Bypass proxy for minikube's vm ip
|
||||
err = proxy.ExcludeIP(ip)
|
||||
if err != nil {
|
||||
console.ErrStyle(console.FailureType, "Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,%s`.", ip)
|
||||
console.ErrT(console.FailureType, "Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.", console.Arg{"ip": ip})
|
||||
}
|
||||
|
||||
// Save IP to configuration file for subsequent use
|
||||
|
@ -297,7 +297,7 @@ func skipCache(config cfg.Config) {
|
|||
|
||||
func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
|
||||
version, _ := cr.Version()
|
||||
console.OutStyle(cr.Style(), "Configuring environment for Kubernetes %s on %s %s", k8sVersion, cr.Name(), version)
|
||||
console.OutT(cr.Style(), "Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}", console.Arg{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
|
||||
for _, v := range dockerOpt {
|
||||
console.OutStyle(console.Option, "opt %s", v)
|
||||
}
|
||||
|
@ -308,9 +308,9 @@ func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
|
|||
|
||||
func showKubectlConnectInfo(kubeconfig *pkgutil.KubeConfigSetup) {
|
||||
if kubeconfig.KeepContext {
|
||||
console.OutStyle(console.Kubectl, "To connect to this cluster, use: kubectl --context=%s", kubeconfig.ClusterName)
|
||||
console.OutT(console.Kubectl, "To connect to this cluster, use: kubectl --context={{.name}}", console.Arg{"name": kubeconfig.ClusterName})
|
||||
} else {
|
||||
console.OutStyle(console.Ready, "Done! kubectl is now configured to use %q", cfg.GetMachineName())
|
||||
console.OutT(console.Ready, "Done! kubectl is now configured to use {{.name}}", console.Arg{"name": cfg.GetMachineName()})
|
||||
}
|
||||
_, err := exec.LookPath("kubectl")
|
||||
if err != nil {
|
||||
|
@ -380,7 +380,7 @@ func validateUser() {
|
|||
exit.Usage("Please run with sudo. the vm-driver %q requires sudo.", constants.DriverNone)
|
||||
|
||||
} else if u.Name == "root" && !(d == constants.DriverHyperv || d == constants.DriverNone) {
|
||||
console.OutStyle(console.WarningType, "Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with %s driver.", d)
|
||||
console.OutT(console.WarningType, "Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with {{.driver}} driver.", console.Arg{"driver": d})
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -406,7 +406,7 @@ func validateConfig() {
|
|||
exit.Usage("Requested memory allocation (%dMB) is less than the minimum allowed of %dMB", memorySizeMB, pkgutil.CalculateSizeInMB(constants.MinimumMemorySize))
|
||||
}
|
||||
if memorySizeMB < pkgutil.CalculateSizeInMB(constants.DefaultMemorySize) {
|
||||
console.OutStyle(console.Notice, "Requested memory allocation (%dMB) is less than the default memory allocation of (%dMB). Beware that Minikube might not work correctly or crash unexpectedly.", memorySizeMB, pkgutil.CalculateSizeInMB(constants.DefaultMemorySize))
|
||||
console.OutT(console.Notice, "Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default}}MB. Beware that minikube might not work correctly or crash unexpectedly.", console.Arg{"memory": memorySizeMB, "default": pkgutil.CalculateSizeInMB(constants.DefaultMemorySize)})
|
||||
}
|
||||
|
||||
// check that kubeadm extra args contain only whitelisted parameters
|
||||
|
@ -515,7 +515,7 @@ func generateConfig(cmd *cobra.Command, k8sVersion string) (cfg.Config, error) {
|
|||
}
|
||||
|
||||
if repository != "" {
|
||||
console.OutStyle(console.SuccessType, "using image repository %s", repository)
|
||||
console.OutT(console.SuccessType, "Using image repository {{.name}}", console.Arg{"name": repository})
|
||||
}
|
||||
|
||||
cfg := cfg.Config{
|
||||
|
@ -686,11 +686,11 @@ func validateKubernetesVersions(old *cfg.Config) (string, bool) {
|
|||
|
||||
if nvs.LT(ovs) {
|
||||
nv = version.VersionPrefix + ovs.String()
|
||||
console.ErrStyle(console.Conflict, "Kubernetes downgrade is not supported, will continue to use %v", nv)
|
||||
console.ErrT(console.Conflict, "Kubernetes downgrade is not supported, will continue to use {{.version}}", console.Arg{"version": nv})
|
||||
return nv, isUpgrade
|
||||
}
|
||||
if nvs.GT(ovs) {
|
||||
console.OutStyle(console.ThumbsUp, "minikube will upgrade the local cluster from Kubernetes %s to %s", ovs, nvs)
|
||||
console.OutT(console.ThumbsUp, "minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}", console.Arg{"old": ovs, "new": nvs})
|
||||
isUpgrade = true
|
||||
}
|
||||
return nv, isUpgrade
|
||||
|
@ -767,12 +767,12 @@ func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner c
|
|||
if isUpgrade || !preexisting {
|
||||
console.OutStyle(console.Pulling, "Pulling images ...")
|
||||
if err := bs.PullImages(kc); err != nil {
|
||||
console.OutStyle(console.FailureType, "Unable to pull images, which may be OK: %v", err)
|
||||
console.OutT(console.FailureType, "Unable to pull images, which may be OK: {{.error}}", console.Arg{"error": err})
|
||||
}
|
||||
}
|
||||
|
||||
if preexisting {
|
||||
console.OutStyle(console.Restarting, "Relaunching Kubernetes %s using %s ... ", kc.KubernetesVersion, bsName)
|
||||
console.OutT(console.Restarting, "Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ", console.Arg{"version": kc.KubernetesVersion, "bootstrapper": bsName})
|
||||
if err := bs.RestartCluster(kc); err != nil {
|
||||
exit.WithLogEntries("Error restarting cluster", err, logs.FindProblems(r, bs, runner))
|
||||
}
|
||||
|
@ -791,7 +791,7 @@ func configureMounts() {
|
|||
return
|
||||
}
|
||||
|
||||
console.OutStyle(console.Mounting, "Creating mount %s ...", viper.GetString(mountString))
|
||||
console.OutT(console.Mounting, "Creating mount {{.name}} ...", console.Arg{"name": viper.GetString(mountString)})
|
||||
path := os.Args[0]
|
||||
mountDebugVal := 0
|
||||
if glog.V(8) {
|
||||
|
|
|
@ -26,8 +26,6 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
isatty "github.com/mattn/go-isatty"
|
||||
"golang.org/x/text/message"
|
||||
"k8s.io/minikube/pkg/minikube/translate"
|
||||
)
|
||||
|
||||
// By design, this package uses global references to language and output objects, in preference
|
||||
|
@ -59,24 +57,27 @@ type fdWriter interface {
|
|||
Fd() uintptr
|
||||
}
|
||||
|
||||
// Arg is a convenience wrapper for templating
|
||||
type Arg map[string]interface{}
|
||||
|
||||
// OutStyle writes a stylized and formatted message to stdout
|
||||
func OutStyle(style StyleEnum, format string, a ...interface{}) {
|
||||
outStyled := applyStyle(style, useColor, format, a...)
|
||||
outStyled := applyStyle(style, useColor, format)
|
||||
Out(outStyled, a...)
|
||||
}
|
||||
|
||||
// escape any outstanding '%' signs so that they don't get interpreted
|
||||
// as a formatting directive down the line
|
||||
outStyled = strings.Replace(outStyled, "%", "%%", -1)
|
||||
func OutT(style StyleEnum, format string, a map[string]interface{}) {
|
||||
outStyled := applyTemplateFormatting(style, useColor, format, a)
|
||||
Out(outStyled)
|
||||
}
|
||||
|
||||
// Out writes a basic formatted string to stdout
|
||||
func Out(format string, a ...interface{}) {
|
||||
p := message.NewPrinter(translate.GetPreferredLanguage())
|
||||
if outFile == nil {
|
||||
glog.Warningf("[unset outFile]: %s", fmt.Sprintf(format, a...))
|
||||
return
|
||||
}
|
||||
_, err := p.Fprintf(outFile, format, a...)
|
||||
_, err := fmt.Fprintf(outFile, format, a...)
|
||||
if err != nil {
|
||||
glog.Errorf("Fprintf failed: %v", err)
|
||||
}
|
||||
|
@ -89,22 +90,22 @@ func OutLn(format string, a ...interface{}) {
|
|||
|
||||
// ErrStyle writes a stylized and formatted error message to stderr
|
||||
func ErrStyle(style StyleEnum, format string, a ...interface{}) {
|
||||
format = applyStyle(style, useColor, format, a...)
|
||||
errStyled := applyStyle(style, useColor, format)
|
||||
Err(errStyled, a...)
|
||||
}
|
||||
|
||||
// escape any outstanding '%' signs so that they don't get interpreted
|
||||
// as a formatting directive down the line
|
||||
format = strings.Replace(format, "%", "%%", -1)
|
||||
Err(format)
|
||||
func ErrT(style StyleEnum, format string, a map[string]interface{}) {
|
||||
errStyled := applyTemplateFormatting(style, useColor, format, a)
|
||||
Err(errStyled)
|
||||
}
|
||||
|
||||
// Err writes a basic formatted string to stderr
|
||||
func Err(format string, a ...interface{}) {
|
||||
p := message.NewPrinter(translate.GetPreferredLanguage())
|
||||
if errFile == nil {
|
||||
glog.Errorf("[unset errFile]: %s", fmt.Sprintf(format, a...))
|
||||
return
|
||||
}
|
||||
_, err := p.Fprintf(errFile, format, a...)
|
||||
_, err := fmt.Fprintf(errFile, format, a...)
|
||||
if err != nil {
|
||||
glog.Errorf("Fprint failed: %v", err)
|
||||
}
|
||||
|
|
|
@ -22,13 +22,18 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
"k8s.io/minikube/pkg/minikube/tests"
|
||||
"k8s.io/minikube/pkg/minikube/translate"
|
||||
)
|
||||
|
||||
func TestOutStyle(t *testing.T) {
|
||||
// Set the system locale to Arabic and define a dummy translation file.
|
||||
if err := translate.SetPreferredLanguage("ar"); err != nil {
|
||||
t.Fatalf("SetPreferredLanguage: %v", err)
|
||||
}
|
||||
translate.Translations = map[string]interface{}{
|
||||
"Installing Kubernetes version %s ...": "... %s تثبيت Kubernetes الإصدار",
|
||||
}
|
||||
|
||||
var testCases = []struct {
|
||||
style StyleEnum
|
||||
|
@ -44,6 +49,7 @@ func TestOutStyle(t *testing.T) {
|
|||
{WaitingPods, "wait", nil, "⌛ wait", "* wait"},
|
||||
{Issue, "http://i/%d", []interface{}{10000}, " ▪ http://i/10000\n", " - http://i/10000\n"},
|
||||
{Usage, "raw: %s %s", []interface{}{"'%'", "%d"}, "💡 raw: '%' %d\n", "* raw: '%' %d\n"},
|
||||
{Running, "Installing Kubernetes version %s ...", []interface{}{"v1.13"}, "🏃 ... v1.13 تثبيت Kubernetes الإصدار\n", "* ... v1.13 تثبيت Kubernetes الإصدار\n"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
for _, override := range []bool{true, false} {
|
||||
|
@ -66,34 +72,74 @@ func TestOutStyle(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOut(t *testing.T) {
|
||||
os.Setenv(OverrideEnv, "")
|
||||
// An example translation just to assert that this code path is executed.
|
||||
err := message.SetString(language.Arabic, "Installing Kubernetes version %s ...", "... %s تثبيت Kubernetes الإصدار")
|
||||
if err != nil {
|
||||
t.Fatalf("setstring: %v", err)
|
||||
func TestOutT(t *testing.T) {
|
||||
// Set the system locale to Arabic and define a dummy translation file.
|
||||
if err := translate.SetPreferredLanguage("ar"); err != nil {
|
||||
t.Fatalf("SetPreferredLanguage: %v", err)
|
||||
}
|
||||
translate.Translations = map[string]interface{}{
|
||||
"Installing Kubernetes version {{.version}} ...": "... {{.version}} تثبيت Kubernetes الإصدار",
|
||||
}
|
||||
|
||||
var testCases = []struct {
|
||||
style StyleEnum
|
||||
message string
|
||||
params Arg
|
||||
want string
|
||||
wantASCII string
|
||||
}{
|
||||
{Happy, "Happy", nil, "😄 Happy\n", "* Happy\n"},
|
||||
{Option, "Option", nil, " ▪ Option\n", " - Option\n"},
|
||||
{WarningType, "Warning", nil, "⚠️ Warning\n", "! Warning\n"},
|
||||
{FatalType, "Fatal: {{.error}}", Arg{"error": "ugh"}, "💣 Fatal: ugh\n", "X Fatal: ugh\n"},
|
||||
{WaitingPods, "wait", nil, "⌛ wait", "* wait"},
|
||||
{Issue, "http://i/{{.number}}", Arg{"number": 10000}, " ▪ http://i/10000\n", " - http://i/10000\n"},
|
||||
{Usage, "raw: {{.one}} {{.two}}", Arg{"one": "'%'", "two": "%d"}, "💡 raw: '%' %d\n", "* raw: '%' %d\n"},
|
||||
{Running, "Installing Kubernetes version {{.version}} ...", Arg{"version": "v1.13"}, "🏃 ... v1.13 تثبيت Kubernetes الإصدار\n", "* ... v1.13 تثبيت Kubernetes الإصدار\n"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
for _, override := range []bool{true, false} {
|
||||
t.Run(fmt.Sprintf("%s-override-%v", tc.message, override), func(t *testing.T) {
|
||||
// Set MINIKUBE_IN_STYLE=<override>
|
||||
os.Setenv(OverrideEnv, strconv.FormatBool(override))
|
||||
f := tests.NewFakeFile()
|
||||
SetOutFile(f)
|
||||
OutT(tc.style, tc.message, tc.params)
|
||||
got := f.String()
|
||||
want := tc.wantASCII
|
||||
if override {
|
||||
want = tc.want
|
||||
}
|
||||
if got != want {
|
||||
t.Errorf("OutStyle() = %q (%d runes), want %q (%d runes)", got, len(got), want, len(want))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOut(t *testing.T) {
|
||||
os.Setenv(OverrideEnv, "")
|
||||
|
||||
var testCases = []struct {
|
||||
format string
|
||||
lang string
|
||||
arg interface{}
|
||||
want string
|
||||
}{
|
||||
{format: "xyz123", want: "xyz123"},
|
||||
{format: "Installing Kubernetes version %s ...", lang: "ar", arg: "v1.13", want: "... v1.13 تثبيت Kubernetes الإصدار"},
|
||||
{format: "Installing Kubernetes version %s ...", lang: "en-us", arg: "v1.13", want: "Installing Kubernetes version v1.13 ..."},
|
||||
{format: "Installing Kubernetes version %s ...", arg: "v1.13", want: "Installing Kubernetes version v1.13 ..."},
|
||||
{format: "Parameter encoding: %s", arg: "%s%%%d", want: "Parameter encoding: %s%%%d"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.format, func(t *testing.T) {
|
||||
if err := translate.SetPreferredLanguage(tc.lang); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
f := tests.NewFakeFile()
|
||||
SetOutFile(f)
|
||||
ErrLn("unrelated message")
|
||||
if tc.arg == nil {
|
||||
Out(tc.format)
|
||||
} else {
|
||||
Out(tc.format, tc.arg)
|
||||
}
|
||||
got := f.String()
|
||||
if got != tc.want {
|
||||
t.Errorf("Out(%s, %s) = %q, want %q", tc.format, tc.arg, got, tc.want)
|
||||
|
@ -127,34 +173,3 @@ func TestErrStyle(t *testing.T) {
|
|||
t.Errorf("ErrStyle() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetPreferredLanguage(t *testing.T) {
|
||||
os.Setenv(OverrideEnv, "0")
|
||||
var tests = []struct {
|
||||
input string
|
||||
want language.Tag
|
||||
}{
|
||||
{"", language.AmericanEnglish},
|
||||
{"C", language.AmericanEnglish},
|
||||
{"zh", language.Chinese},
|
||||
{"fr_FR.utf8", language.French},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
// Set something so that we can assert change.
|
||||
if err := translate.SetPreferredLanguage("is"); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
if err := translate.SetPreferredLanguage(tc.input); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
|
||||
want, _ := tc.want.Base()
|
||||
got, _ := translate.GetPreferredLanguage().Base()
|
||||
if got != want {
|
||||
t.Errorf("SetPreferredLanguage(%s) = %q, want %q", tc.input, got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,10 +17,11 @@ limitations under the License.
|
|||
package console
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"golang.org/x/text/message"
|
||||
"golang.org/x/text/number"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/minikube/pkg/minikube/translate"
|
||||
)
|
||||
|
||||
|
@ -130,29 +131,46 @@ func lowPrefix(s style) string {
|
|||
return lowBullet
|
||||
}
|
||||
|
||||
// Apply styling to a format string
|
||||
func applyStyle(style StyleEnum, useColor bool, format string, a ...interface{}) string {
|
||||
p := message.NewPrinter(translate.GetPreferredLanguage())
|
||||
for i, x := range a {
|
||||
if _, ok := x.(int); ok {
|
||||
a[i] = number.Decimal(x, number.NoSeparator())
|
||||
}
|
||||
}
|
||||
// applyStyle translates the given string if necessary then adds any appropriate style prefix.
|
||||
func applyStyle(style StyleEnum, useColor bool, format string) string {
|
||||
format = translate.T(format)
|
||||
out := p.Sprintf(format, a...)
|
||||
|
||||
s, ok := styles[style]
|
||||
if !s.OmitNewline {
|
||||
out += "\n"
|
||||
format += "\n"
|
||||
}
|
||||
|
||||
// Similar to CSS styles, if no style matches, output an unformatted string.
|
||||
if !ok {
|
||||
return p.Sprintf(format, a...)
|
||||
return format
|
||||
}
|
||||
|
||||
if !useColor {
|
||||
return applyPrefix(lowPrefix(s), out)
|
||||
return applyPrefix(lowPrefix(s), format)
|
||||
}
|
||||
return applyPrefix(s.Prefix, out)
|
||||
return applyPrefix(s.Prefix, format)
|
||||
}
|
||||
|
||||
func applyTemplateFormatting(style StyleEnum, useColor bool, format string, a map[string]interface{}) string {
|
||||
format = applyStyle(style, useColor, format)
|
||||
|
||||
var buf bytes.Buffer
|
||||
t, err := template.New(format).Parse(format)
|
||||
if err != nil {
|
||||
glog.Infof("Initializing template failed. Returning raw string.")
|
||||
return format
|
||||
}
|
||||
|
||||
err = t.Execute(&buf, a)
|
||||
if err != nil {
|
||||
glog.Infof("Executing template failed. Returning raw string.")
|
||||
return format
|
||||
}
|
||||
outStyled := buf.String()
|
||||
|
||||
// escape any outstanding '%' signs so that they don't get interpreted
|
||||
// as a formatting directive down the line
|
||||
outStyled = strings.Replace(outStyled, "%", "%%", -1)
|
||||
|
||||
return outStyled
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@ var blacklist = []string{
|
|||
"%s/%d",
|
||||
"%s=%s",
|
||||
"%v",
|
||||
"GID: %s",
|
||||
"MSize: %d",
|
||||
"UID: %s",
|
||||
"env %s",
|
||||
"opt %s",
|
||||
}
|
||||
|
||||
// state is a struct that represent the current state of the extraction process
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package translate
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func TestSetPreferredLanguage(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input string
|
||||
want language.Tag
|
||||
}{
|
||||
{"", language.AmericanEnglish},
|
||||
{"C", language.AmericanEnglish},
|
||||
{"zh", language.Chinese},
|
||||
{"fr_FR.utf8", language.French},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
// Set something so that we can assert change.
|
||||
if err := SetPreferredLanguage("is"); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
if err := SetPreferredLanguage(tc.input); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
|
||||
want, _ := tc.want.Base()
|
||||
got, _ := GetPreferredLanguage().Base()
|
||||
if got != want {
|
||||
t.Errorf("SetPreferredLanguage(%s) = %q, want %q", tc.input, got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -20,13 +20,13 @@
|
|||
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
|
||||
"Cannot find directory %s for mount": "",
|
||||
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "",
|
||||
"Configuring environment for Kubernetes %s on %s %s": "Configurant l'environment pour Kubernetes %s sur %s %s",
|
||||
"Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}": "Configurant l'environment pour Kubernetes {{.k8sVersion}} sur {{.runtime}} {{.runtimeVersion}}",
|
||||
"Configuring local host environment ...": "",
|
||||
"Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "Créant un VM %s (CPUs=%d, Mémoire=%dMB, Disque=%dMB)",
|
||||
"Creating mount %s ...": "",
|
||||
"Creating mount {{.name}} ...": "",
|
||||
"Deleting %q from %s ...": "",
|
||||
"Documentation: %s": "",
|
||||
"Done! kubectl is now configured to use %q": "Fini! kubectl est maintenant configuré pour utiliser %s.",
|
||||
"Done! kubectl is now configured to use {{.name}}": "Fini! kubectl est maintenant configuré pour utiliser {{.name}}.",
|
||||
"Download complete!": "",
|
||||
"Downloading %s %s": "",
|
||||
"Downloading Minikube ISO ...": "",
|
||||
|
@ -93,7 +93,7 @@
|
|||
"Failed to list cached images": "",
|
||||
"Failed to remove profile": "",
|
||||
"Failed to save config": "",
|
||||
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,%s`.": "",
|
||||
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.": "",
|
||||
"Failed to setup certs": "",
|
||||
"Failed to setup kubeconfig": "",
|
||||
"Failed to update cluster": "",
|
||||
|
@ -103,14 +103,13 @@
|
|||
"For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
|
||||
"For more information, see:": "",
|
||||
"Found network options:": "",
|
||||
"GID: %s": "",
|
||||
"If the above advice does not help, please let us know: ": "",
|
||||
"Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
|
||||
"Invalid size passed in argument: %v": "",
|
||||
"IsEnabled failed": "",
|
||||
"Kubernetes downgrade is not supported, will continue to use %v": "",
|
||||
"Kubernetes downgrade is not supported, will continue to use {{.version}}": "",
|
||||
"Launching Kubernetes ... ": "Lançant Kubernetes ...",
|
||||
"Launching proxy ...": "",
|
||||
"MSize: %d": "",
|
||||
"Mode: %o (%s)": "",
|
||||
"Mount options:": "",
|
||||
"Mounting host path %s into VM as %s ...": "",
|
||||
|
@ -120,25 +119,27 @@
|
|||
"Opening %s in your default browser...": "",
|
||||
"Opening kubernetes service %s/%s in default browser...": "",
|
||||
"Options: %s": "",
|
||||
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary.": "",
|
||||
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with {{.driver}} driver.": "",
|
||||
"Please enter a value:": "",
|
||||
"Please run with sudo. the vm-driver %q requires sudo.": "",
|
||||
"Please specify the directory to be mounted: \n\tminikube mount \u003csource directory\u003e:\u003ctarget directory\u003e (example: \"/host-home:/vm-home\")": "",
|
||||
"Powering off %q via SSH ...": "",
|
||||
"Problems detected in %q:": "",
|
||||
"Pulling images ...": "Extrayant les images ... ",
|
||||
"Re-using the currently running %s VM for %q ...": "",
|
||||
"Related issues:": "",
|
||||
"Relaunching Kubernetes %s using %s ... ": "",
|
||||
"Requested disk size (%dMB) is less than minimum of %dMB": "",
|
||||
"Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ": "",
|
||||
"Requested disk size (%dMB) is less than minimum of (%dMB)": "",
|
||||
"Requested memory allocation (%dMB) is less than the minimum allowed of %dMB": "",
|
||||
"Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default}}MB. Beware that minikube might not work correctly or crash unexpectedly.": "",
|
||||
"Restarting existing %s VM for %q ...": "",
|
||||
"Set failed": "",
|
||||
"Setting profile failed": "",
|
||||
"Skipped switching kubectl context for %s , because --keep-context": "",
|
||||
"Sorry that minikube crashed. If this was unexpected, we would love to hear from you:": "",
|
||||
"Sorry, completion support is not yet implemented for %q": "",
|
||||
"Sorry, the --gpu feature is currently only supported with --vm-driver=kvm2": "",
|
||||
"Sorry, the --hidden feature is currently only supported with --vm-driver=kvm2": "",
|
||||
"Sorry, the kubeadm.%s parameter is currently not supported by --extra-config": "",
|
||||
"Sorry, url provided with --registry-mirror flag is invalid %q": "",
|
||||
"Stopping %q in %s ...": "",
|
||||
"Successfully mounted %s to %s": "",
|
||||
"Target directory %q must be an absolute path": "",
|
||||
|
@ -157,10 +158,10 @@
|
|||
"This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true": "",
|
||||
"Tip: Use 'minikube start -p \u003cname\u003e' to create a new cluster, or 'minikube delete' to delete this one.": "",
|
||||
"To connect to this cluster, use: kubectl --context=%s": "",
|
||||
"To connect to this cluster, use: kubectl --context={{.name}}": "",
|
||||
"To switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver=%s`": "",
|
||||
"To use kubectl or minikube commands as your own user, you may": "",
|
||||
"Type: %s": "",
|
||||
"UID: %s": "",
|
||||
"Unable to bind flags": "",
|
||||
"Unable to enable dashboard": "",
|
||||
"Unable to fetch latest version info": "",
|
||||
|
@ -171,7 +172,7 @@
|
|||
"Unable to load cached images: %v": "",
|
||||
"Unable to load config: %v": "",
|
||||
"Unable to parse %q: %v": "",
|
||||
"Unable to pull images, which may be OK: %v": "",
|
||||
"Unable to pull images, which may be OK: {{.error}}": "",
|
||||
"Unable to start VM": "",
|
||||
"Unable to stop VM": "",
|
||||
"Uninstalling Kubernetes %s using %s ...": "",
|
||||
|
@ -180,6 +181,7 @@
|
|||
"Usage: minikube completion SHELL": "",
|
||||
"Userspace file server is shutdown": "",
|
||||
"Userspace file server: ": "",
|
||||
"Using image repository {{.name}}": "",
|
||||
"Verifying dashboard health ...": "",
|
||||
"Verifying proxy health ...": "",
|
||||
"Verifying:": "Vérifiant:",
|
||||
|
@ -198,7 +200,6 @@
|
|||
"config view failed": "",
|
||||
"disable failed": "",
|
||||
"enable failed: %v": "",
|
||||
"env %s": "",
|
||||
"error creating clientset": "",
|
||||
"error creating machine client": "",
|
||||
"error getting driver": "",
|
||||
|
@ -209,14 +210,13 @@
|
|||
"kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
|
||||
"kubectl proxy": "",
|
||||
"logdir set failed": "",
|
||||
"minikube %s on %s (%s)": "minikube %s sur %s (%s)",
|
||||
"minikube is not running, so the service cannot be accessed": "",
|
||||
"minikube profile was successfully set to %s": "",
|
||||
"minikube will upgrade the local cluster from Kubernetes %s to %s": "",
|
||||
"minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}": "",
|
||||
"minikube {{.version}} on {{.os}} ({{.arch}})": "minikube {{.version}} sur {{.os}} ({{.arch}})",
|
||||
"mount argument %q must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
|
||||
"mount failed": "",
|
||||
"need to relocate them. For example, to overwrite your own settings:": "",
|
||||
"opt %s": "",
|
||||
"stat failed": "",
|
||||
"unable to bind flags": "",
|
||||
"unable to set logtostderr": "",
|
||||
|
@ -232,6 +232,5 @@
|
|||
"usage: minikube config unset PROPERTY_NAME": "",
|
||||
"usage: minikube delete": "",
|
||||
"usage: minikube profile [MINIKUBE_PROFILE_NAME]": "",
|
||||
"using image repository %s": "",
|
||||
"zsh completion failed": ""
|
||||
}
|
|
@ -20,13 +20,13 @@
|
|||
"Alternatively, you may delete the existing VM using `minikube delete -p %s`": "",
|
||||
"Cannot find directory %s for mount": "",
|
||||
"Check that minikube is running and that you have specified the correct namespace (-n flag) if required.": "",
|
||||
"Configuring environment for Kubernetes %s on %s %s": "开始为Kubernetes %s,%s %s 配置环境变量",
|
||||
"Configuring environment for Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}}": "开始为Kubernetes {{.k8sVersion}},{{.runtime}} {{.runtimeVersion}} 配置环境变量",
|
||||
"Configuring local host environment ...": "",
|
||||
"Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...": "正在创建%s虚拟机(CPU=%d,内存=%dMB,磁盘=%dMB)...",
|
||||
"Creating mount %s ...": "",
|
||||
"Creating mount {{.name}} ...": "",
|
||||
"Deleting %q from %s ...": "",
|
||||
"Documentation: %s": "",
|
||||
"Done! kubectl is now configured to use %q": "完成!kubectl已经配置至%q",
|
||||
"Done! kubectl is now configured to use {{.name}}": "完成!kubectl已经配置至{{.name}}",
|
||||
"Download complete!": "",
|
||||
"Downloading %s %s": "",
|
||||
"Downloading Minikube ISO ...": "",
|
||||
|
@ -93,7 +93,7 @@
|
|||
"Failed to list cached images": "",
|
||||
"Failed to remove profile": "",
|
||||
"Failed to save config": "",
|
||||
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,%s`.": "",
|
||||
"Failed to set NO_PROXY Env. Please use `export NO_PROXY=$NO_PROXY,{{.ip}}`.": "",
|
||||
"Failed to setup certs": "",
|
||||
"Failed to setup kubeconfig": "",
|
||||
"Failed to update cluster": "",
|
||||
|
@ -103,14 +103,13 @@
|
|||
"For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
|
||||
"For more information, see:": "",
|
||||
"Found network options:": "",
|
||||
"GID: %s": "",
|
||||
"If the above advice does not help, please let us know: ": "",
|
||||
"Ignoring --vm-driver=%s, as the existing %q VM was created using the %s driver.": "",
|
||||
"Invalid size passed in argument: %v": "",
|
||||
"IsEnabled failed": "",
|
||||
"Kubernetes downgrade is not supported, will continue to use %v": "",
|
||||
"Kubernetes downgrade is not supported, will continue to use {{.version}}": "",
|
||||
"Launching Kubernetes ... ": "正在启动 Kubernetes ... ",
|
||||
"Launching proxy ...": "",
|
||||
"MSize: %d": "",
|
||||
"Mode: %o (%s)": "",
|
||||
"Mount options:": "",
|
||||
"Mounting host path %s into VM as %s ...": "",
|
||||
|
@ -120,25 +119,27 @@
|
|||
"Opening %s in your default browser...": "",
|
||||
"Opening kubernetes service %s/%s in default browser...": "",
|
||||
"Options: %s": "",
|
||||
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary.": "",
|
||||
"Please don't run minikube as root or with 'sudo' privileges. It isn't necessary with {{.driver}} driver.": "",
|
||||
"Please enter a value:": "",
|
||||
"Please run with sudo. the vm-driver %q requires sudo.": "",
|
||||
"Please specify the directory to be mounted: \n\tminikube mount \u003csource directory\u003e:\u003ctarget directory\u003e (example: \"/host-home:/vm-home\")": "",
|
||||
"Powering off %q via SSH ...": "",
|
||||
"Problems detected in %q:": "",
|
||||
"Pulling images ...": "拉取镜像 ...",
|
||||
"Re-using the currently running %s VM for %q ...": "",
|
||||
"Related issues:": "",
|
||||
"Relaunching Kubernetes %s using %s ... ": "",
|
||||
"Requested disk size (%dMB) is less than minimum of %dMB": "",
|
||||
"Relaunching Kubernetes {{.version}} using {{.bootstrapper}} ... ": "",
|
||||
"Requested disk size (%dMB) is less than minimum of (%dMB)": "",
|
||||
"Requested memory allocation (%dMB) is less than the minimum allowed of %dMB": "",
|
||||
"Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default}}MB. Beware that minikube might not work correctly or crash unexpectedly.": "",
|
||||
"Restarting existing %s VM for %q ...": "",
|
||||
"Set failed": "",
|
||||
"Setting profile failed": "",
|
||||
"Skipped switching kubectl context for %s , because --keep-context": "",
|
||||
"Sorry that minikube crashed. If this was unexpected, we would love to hear from you:": "",
|
||||
"Sorry, completion support is not yet implemented for %q": "",
|
||||
"Sorry, the --gpu feature is currently only supported with --vm-driver=kvm2": "",
|
||||
"Sorry, the --hidden feature is currently only supported with --vm-driver=kvm2": "",
|
||||
"Sorry, the kubeadm.%s parameter is currently not supported by --extra-config": "",
|
||||
"Sorry, url provided with --registry-mirror flag is invalid %q": "",
|
||||
"Stopping %q in %s ...": "",
|
||||
"Successfully mounted %s to %s": "",
|
||||
"Target directory %q must be an absolute path": "",
|
||||
|
@ -157,10 +158,10 @@
|
|||
"This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true": "",
|
||||
"Tip: Use 'minikube start -p \u003cname\u003e' to create a new cluster, or 'minikube delete' to delete this one.": "",
|
||||
"To connect to this cluster, use: kubectl --context=%s": "",
|
||||
"To connect to this cluster, use: kubectl --context={{.name}}": "",
|
||||
"To switch drivers, you may create a new VM using `minikube start -p \u003cname\u003e --vm-driver=%s`": "",
|
||||
"To use kubectl or minikube commands as your own user, you may": "",
|
||||
"Type: %s": "",
|
||||
"UID: %s": "",
|
||||
"Unable to bind flags": "",
|
||||
"Unable to enable dashboard": "",
|
||||
"Unable to fetch latest version info": "",
|
||||
|
@ -171,7 +172,7 @@
|
|||
"Unable to load cached images: %v": "",
|
||||
"Unable to load config: %v": "",
|
||||
"Unable to parse %q: %v": "",
|
||||
"Unable to pull images, which may be OK: %v": "",
|
||||
"Unable to pull images, which may be OK: {{.error}}": "",
|
||||
"Unable to start VM": "",
|
||||
"Unable to stop VM": "",
|
||||
"Uninstalling Kubernetes %s using %s ...": "",
|
||||
|
@ -180,6 +181,7 @@
|
|||
"Usage: minikube completion SHELL": "",
|
||||
"Userspace file server is shutdown": "",
|
||||
"Userspace file server: ": "",
|
||||
"Using image repository {{.name}}": "",
|
||||
"Verifying dashboard health ...": "",
|
||||
"Verifying proxy health ...": "",
|
||||
"Verifying:": "正在验证:",
|
||||
|
@ -198,7 +200,6 @@
|
|||
"config view failed": "",
|
||||
"disable failed": "",
|
||||
"enable failed: %v": "",
|
||||
"env %s": "",
|
||||
"error creating clientset": "",
|
||||
"error creating machine client": "",
|
||||
"error getting driver": "",
|
||||
|
@ -209,14 +210,13 @@
|
|||
"kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/": "",
|
||||
"kubectl proxy": "",
|
||||
"logdir set failed": "",
|
||||
"minikube %s on %s (%s)": "您正在使用minikube %s, 运行平台:%s (%s)",
|
||||
"minikube is not running, so the service cannot be accessed": "",
|
||||
"minikube profile was successfully set to %s": "",
|
||||
"minikube will upgrade the local cluster from Kubernetes %s to %s": "",
|
||||
"minikube will upgrade the local cluster from Kubernetes {{.old}} to {{.new}}": "",
|
||||
"minikube {{.version}} on {{.os}} ({{.arch}})": "您正在使用minikube {{.version}}, 运行平台:{{.os}} ({{.arch}})",
|
||||
"mount argument %q must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
|
||||
"mount failed": "",
|
||||
"need to relocate them. For example, to overwrite your own settings:": "",
|
||||
"opt %s": "",
|
||||
"stat failed": "",
|
||||
"unable to bind flags": "",
|
||||
"unable to set logtostderr": "",
|
||||
|
@ -232,6 +232,5 @@
|
|||
"usage: minikube config unset PROPERTY_NAME": "",
|
||||
"usage: minikube delete": "",
|
||||
"usage: minikube profile [MINIKUBE_PROFILE_NAME]": "",
|
||||
"using image repository %s": "",
|
||||
"zsh completion failed": ""
|
||||
}
|
Loading…
Reference in New Issue