More console work
parent
cf938ee5d6
commit
f2d6f45538
|
@ -655,12 +655,20 @@
|
|||
revision = "95c6576299259db960f6c5b9b69ea52422860fce"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5b12278b98e82aecd7d0b84e0b5fba67f37aba8fde89fa86d51e30556d381a4c"
|
||||
branch = "master"
|
||||
digest = "1:11d290de3457882172ce8d9ffe930999cfb62929b58e486e1ff1b6adcf3c52bc"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"feature/plural",
|
||||
"internal",
|
||||
"internal/catmsg",
|
||||
"internal/colltab",
|
||||
"internal/format",
|
||||
"internal/gen",
|
||||
"internal/language",
|
||||
"internal/language/compact",
|
||||
"internal/number",
|
||||
"internal/stringset",
|
||||
"internal/tag",
|
||||
|
@ -677,7 +685,7 @@
|
|||
"unicode/rangetable",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||
revision = "e6919f6577db79269a6443b9dc46d18f2238fb5d"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d37b0ef2944431fe9e8ef35c6fffc8990d9e2ca300588df94a6890f3649ae365"
|
||||
|
|
|
@ -113,3 +113,4 @@
|
|||
|
||||
[[constraint]]
|
||||
name = "golang.org/x/text"
|
||||
branch = "master"
|
||||
|
|
|
@ -19,6 +19,8 @@ package cmd
|
|||
import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/machine/libmachine/mcnerror"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
cmdUtil "k8s.io/minikube/cmd/util"
|
||||
|
@ -40,8 +42,8 @@ associated files.`,
|
|||
console.ErrStyle("usage", "usage: minikube delete")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
console.OutStyle("stopping", "Deleting local Kubernetes cluster ...")
|
||||
profile := viper.GetString(pkg_config.MachineProfile)
|
||||
console.OutStyle("deleting-vm", "Deleting %q Kubernetes cluster ...", profile)
|
||||
api, err := machine.NewAPIClient()
|
||||
if err != nil {
|
||||
console.Fatal("Error getting client: %v", err)
|
||||
|
@ -50,19 +52,30 @@ associated files.`,
|
|||
defer api.Close()
|
||||
|
||||
if err = cluster.DeleteHost(api); err != nil {
|
||||
console.Fatal("Errors occurred deleting machine: %v", err)
|
||||
os.Exit(1)
|
||||
switch err := errors.Cause(err).(type) {
|
||||
case mcnerror.ErrHostDoesNotExist:
|
||||
console.OutStyle("meh", "%q VM does not exist", profile)
|
||||
default:
|
||||
console.Fatal("Failed to delete VM: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
console.Success("VM deleted.")
|
||||
}
|
||||
console.Success("Machine deleted.")
|
||||
|
||||
if err := cmdUtil.KillMountProcess(); err != nil {
|
||||
console.Fatal("Errors occurred deleting mount process: %v", err)
|
||||
console.Fatal("Failed to kill mount process: %v", err)
|
||||
}
|
||||
|
||||
if err := os.Remove(constants.GetProfileFile(viper.GetString(pkg_config.MachineProfile))); err != nil {
|
||||
console.Fatal("Error deleting machine profile config: %v", err)
|
||||
if os.IsNotExist(err) {
|
||||
console.OutStyle("meh", "%q profile does not exist", profile)
|
||||
os.Exit(0)
|
||||
}
|
||||
console.Fatal("Failed to remove profile: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
console.Success("Removed %q profile!", profile)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -199,25 +199,35 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
fatalExit("Error saving profile cluster configuration: %v", err)
|
||||
}
|
||||
|
||||
console.OutStyle("starting-vm", "Starting local Kubernetes %s cluster ...", viper.GetString(kubernetesVersion))
|
||||
|
||||
// TODO(tstromberg): Include version of VM software in output
|
||||
if config.VMDriver == constants.DriverNone {
|
||||
console.OutStyle("starting-none", "Configuring local host environment ...")
|
||||
} else {
|
||||
console.OutStyle("starting-vm", "Starting %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...", viper.GetString(vmDriver), config.CPUs, config.Memory, config.DiskSize)
|
||||
}
|
||||
var host *host.Host
|
||||
start := func() (err error) {
|
||||
host, err = cluster.StartHost(api, config)
|
||||
if err != nil {
|
||||
glog.Errorf("StartHost: %v", err)
|
||||
glog.Infof("StartHost: %v", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = pkgutil.RetryAfter(5, start, 2*time.Second)
|
||||
if err != nil {
|
||||
reportAndExit("Error starting host: ", err)
|
||||
reportErrAndExit("Unable to start VM", err)
|
||||
}
|
||||
|
||||
console.OutStyle("connectivity", "Verifying connectivity ...")
|
||||
for _, k := range []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY"} {
|
||||
if v := os.Getenv(k); v != "" {
|
||||
console.OutStyle("options", "%s=%s", k, v)
|
||||
}
|
||||
}
|
||||
|
||||
ip, err := host.Driver.GetIP()
|
||||
if err != nil {
|
||||
reportAndExit("Unable to get VM IP address", err)
|
||||
reportErrAndExit("Unable to get VM IP address", err)
|
||||
}
|
||||
|
||||
// common config (currently none)
|
||||
|
@ -229,7 +239,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
_, err = host.RunSSHCommand(command)
|
||||
}
|
||||
if err != nil {
|
||||
reportAndExit("Error writing crictl config", err)
|
||||
reportErrAndExit("Error writing crictl config", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,6 +266,9 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
selectedKubernetesVersion = version.VersionPrefix + oldKubernetesVersion.String()
|
||||
console.ErrStyle("conflict", "Kubernetes downgrade is not supported, will continue to use %v", selectedKubernetesVersion)
|
||||
}
|
||||
if newKubernetesVersion.GT(oldKubernetesVersion) {
|
||||
console.OutStyle("thumbs-up", "Will upgrade local cluster from Kubernetes %s to %s", oldKubernetesVersion, newKubernetesVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,10 +290,9 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
ShouldLoadCachedImages: shouldCacheImages,
|
||||
EnableDefaultCNI: viper.GetBool(enableDefaultCNI),
|
||||
}
|
||||
|
||||
k8sBootstrapper, err := GetClusterBootstrapper(api, clusterBootstrapper)
|
||||
if err != nil {
|
||||
reportAndExit("Error getting cluster bootstrapper", err)
|
||||
reportErrAndExit("Error getting cluster bootstrapper", err)
|
||||
}
|
||||
|
||||
// Write profile cluster configuration to file
|
||||
|
@ -290,7 +302,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
|
||||
if err := saveConfig(clusterConfig); err != nil {
|
||||
reportAndExit("Error saving profile cluster configuration", err)
|
||||
reportErrAndExit("Error saving profile cluster configuration", err)
|
||||
}
|
||||
|
||||
if shouldCacheImages {
|
||||
|
@ -300,19 +312,23 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
}
|
||||
|
||||
console.OutStyle("copying", "Copying files into VM ...")
|
||||
console.OutStyle("copying", "Configuring minikube VM environment ...")
|
||||
for _, eo := range extraOptions {
|
||||
console.OutStyle("options", "%s.%s=%s", eo.Component, eo.Key, eo.Value)
|
||||
|
||||
}
|
||||
|
||||
if err := k8sBootstrapper.UpdateCluster(kubernetesConfig); err != nil {
|
||||
reportAndExit("Failed to update cluster", err)
|
||||
reportErrAndExit("Failed to update cluster", err)
|
||||
}
|
||||
|
||||
if err := k8sBootstrapper.SetupCerts(kubernetesConfig); err != nil {
|
||||
reportAndExit("Failed to setup certs", err)
|
||||
reportErrAndExit("Failed to setup certs", err)
|
||||
}
|
||||
|
||||
kubeHost, err := host.Driver.GetURL()
|
||||
if err != nil {
|
||||
reportAndExit("Failed to get driver URL", err)
|
||||
reportErrAndExit("Failed to get driver URL", err)
|
||||
}
|
||||
kubeHost = strings.Replace(kubeHost, "tcp://", "https://", -1)
|
||||
kubeHost = strings.Replace(kubeHost, ":2376", ":"+strconv.Itoa(kubernetesConfig.NodePort), -1)
|
||||
|
@ -329,24 +345,33 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
kubeCfgSetup.SetKubeConfigFile(kubeConfigFile)
|
||||
|
||||
if err := kubeconfig.SetupKubeConfig(kubeCfgSetup); err != nil {
|
||||
reportAndExit("Failed to setup kubeconfig", err)
|
||||
reportErrAndExit("Failed to setup kubeconfig", err)
|
||||
}
|
||||
|
||||
// TODO(tstromberg): use cruntime.Manager.Name() once PR is merged
|
||||
rname := viper.GetString(containerRuntime)
|
||||
if rname == "" {
|
||||
rname = "Docker"
|
||||
}
|
||||
console.OutStyle("container-runtime", "Configuring %s within VM ...", rname)
|
||||
for _, v := range dockerOpt {
|
||||
console.OutStyle("options", "opt %s", v)
|
||||
}
|
||||
for _, v := range dockerEnv {
|
||||
console.OutStyle("options", "env %s", v)
|
||||
}
|
||||
|
||||
if config.VMDriver != constants.DriverNone && selectedContainerRuntime != "" {
|
||||
if _, err := host.RunSSHCommand("sudo systemctl stop docker"); err == nil {
|
||||
_, err = host.RunSSHCommand("sudo systemctl stop docker.socket")
|
||||
}
|
||||
if err != nil {
|
||||
reportAndExit("Failed to stop docker", err)
|
||||
reportErrAndExit("Failed to stop docker", err)
|
||||
}
|
||||
}
|
||||
if config.VMDriver != constants.DriverNone && (selectedContainerRuntime != constants.CrioRuntime && selectedContainerRuntime != constants.Cri_oRuntime) {
|
||||
if _, err := host.RunSSHCommand("sudo systemctl stop crio"); err != nil {
|
||||
reportAndExit("Failed to stop CRIO", err)
|
||||
reportErrAndExit("Failed to stop CRIO", err)
|
||||
}
|
||||
}
|
||||
if config.VMDriver != constants.DriverNone && selectedContainerRuntime != constants.RktRuntime {
|
||||
|
@ -354,19 +379,19 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
_, err = host.RunSSHCommand("sudo systemctl stop rkt-metadata")
|
||||
}
|
||||
if err != nil {
|
||||
reportAndExit("Failed to stop rkt", err)
|
||||
reportErrAndExit("Failed to stop rkt", err)
|
||||
}
|
||||
}
|
||||
if config.VMDriver != constants.DriverNone && selectedContainerRuntime != constants.ContainerdRuntime {
|
||||
if _, err = host.RunSSHCommand("sudo systemctl stop containerd"); err != nil {
|
||||
reportAndExit("Failed to stop containerd", err)
|
||||
reportErrAndExit("Failed to stop containerd", err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.VMDriver != constants.DriverNone && (selectedContainerRuntime == constants.CrioRuntime || selectedContainerRuntime == constants.Cri_oRuntime) {
|
||||
// restart crio so that it can monitor all hook dirs
|
||||
if _, err := host.RunSSHCommand("sudo systemctl restart crio"); err != nil {
|
||||
reportAndExit("Failed to restart crio", err)
|
||||
reportErrAndExit("Failed to restart crio", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,7 +399,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
console.Fatal("Restarting containerd runtime...")
|
||||
// restart containerd so that it can install all plugins
|
||||
if _, err := host.RunSSHCommand("sudo systemctl restart containerd"); err != nil {
|
||||
reportAndExit("Failed to restart containerd", err)
|
||||
reportErrAndExit("Failed to restart containerd", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,51 +429,53 @@ This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(tstromberg): Add call to bootstrapper.PullImages once PR is merged.
|
||||
|
||||
if !exists || config.VMDriver == constants.DriverNone {
|
||||
console.OutStyle("launch", "Launching Kubernetes %s with %s ... ", kubernetesConfig.KubernetesVersion, clusterBootstrapper)
|
||||
console.OutStyle("launch", "Launching Kubernetes %s using %s ... ", kubernetesConfig.KubernetesVersion, clusterBootstrapper)
|
||||
if err := k8sBootstrapper.StartCluster(kubernetesConfig); err != nil {
|
||||
reportAndExit("Error starting cluster", err)
|
||||
reportErrAndExit("Error starting cluster", err)
|
||||
}
|
||||
} else {
|
||||
console.OutStyle("restarting", "Relaunching Kubernetes %s with %s ... ", kubernetesConfig.KubernetesVersion, clusterBootstrapper)
|
||||
console.OutStyle("restarting", "Reconfiguring Kubernetes %s with %s ... ", kubernetesConfig.KubernetesVersion, clusterBootstrapper)
|
||||
if err := k8sBootstrapper.RestartCluster(kubernetesConfig); err != nil {
|
||||
reportAndExit("Error restarting cluster", err)
|
||||
reportErrAndExit("Error restarting cluster", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Block until the cluster is healthy.
|
||||
console.OutStyle("verifying", "Verifying component health ...")
|
||||
console.OutStyle("verifying-noline", "Verifying component health ...")
|
||||
// TODO(tstromberg): Display pod health.
|
||||
kStat := func() (err error) {
|
||||
st, err := k8sBootstrapper.GetKubeletStatus()
|
||||
console.Out(".")
|
||||
if err != nil || st != state.Running.String() {
|
||||
console.Out(".")
|
||||
return &pkgutil.RetriableError{Err: fmt.Errorf("kubelet unhealthy: %v: %s", err, st)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err = pkgutil.RetryAfter(20, kStat, 3*time.Second)
|
||||
if err != nil {
|
||||
reportAndExit("kubelet checks failed", err)
|
||||
reportErrAndExit("kubelet checks failed", err)
|
||||
}
|
||||
aStat := func() (err error) {
|
||||
st, err := k8sBootstrapper.GetApiServerStatus(net.ParseIP(ip))
|
||||
console.Out(".")
|
||||
if err != nil || st != state.Running.String() {
|
||||
console.Out(".")
|
||||
return &pkgutil.RetriableError{Err: fmt.Errorf("apiserver status=%s err=%v", st, err)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err = pkgutil.RetryAfter(30, aStat, 10*time.Second)
|
||||
// End the dots.
|
||||
console.OutLn("")
|
||||
if err != nil {
|
||||
reportAndExit("apiserver checks failed", err)
|
||||
reportErrAndExit("apiserver checks failed", err)
|
||||
}
|
||||
console.OutLn("")
|
||||
|
||||
// start 9p server mount
|
||||
if viper.GetBool(createMount) {
|
||||
console.OutStyle("mount", "Setting up mount on %s ...", viper.GetString(mountString))
|
||||
console.OutStyle("mount", "Creating mount %s ...", viper.GetString(mountString))
|
||||
|
||||
path := os.Args[0]
|
||||
mountDebugVal := 0
|
||||
|
@ -484,8 +511,7 @@ This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_
|
|||
if err != nil {
|
||||
console.Failure("Unable to load cached images from config file.")
|
||||
}
|
||||
console.OutStyle("ready", "Your local Kubernetes cluster is ready! Thank you for using minikube!")
|
||||
return
|
||||
console.OutStyle("ready", "Done! Thank you for using minikube!")
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -585,15 +611,15 @@ func saveConfigToFile(data []byte, file string) error {
|
|||
|
||||
// fatalExit is a shortcut for outputting a failure message and exiting.
|
||||
func fatalExit(format string, a ...interface{}) {
|
||||
glog.Errorf(format, a...)
|
||||
// use Warning because Error will display a duplicate message
|
||||
glog.Warningf(format, a...)
|
||||
console.Fatal(format, a...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// reportFatalExit is a shortcut for outputting an error, reporting it, and exiting.
|
||||
func reportAndExit(msg string, err error) {
|
||||
func reportErrAndExit(msg string, err error) {
|
||||
console.Fatal(msg+": %v", err)
|
||||
glog.Errorf("%s: %v", msg, err)
|
||||
cmdutil.MaybeReportErrorAndExit(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
|
@ -20,9 +20,13 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine/mcnerror"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
cmdUtil "k8s.io/minikube/cmd/util"
|
||||
"k8s.io/minikube/pkg/minikube/cluster"
|
||||
pkg_config "k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/console"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
|
@ -35,7 +39,9 @@ var stopCmd = &cobra.Command{
|
|||
Long: `Stops a local kubernetes cluster running in Virtualbox. This command stops the VM
|
||||
itself, leaving all files intact. The cluster can be started again with the "start" command.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
console.OutStyle("stopping", "Stopping local Kubernetes cluster...")
|
||||
profile := viper.GetString(pkg_config.MachineProfile)
|
||||
console.OutStyle("stopping", "Stopping %q Kubernetes cluster...", profile)
|
||||
|
||||
api, err := machine.NewAPIClient()
|
||||
if err != nil {
|
||||
console.Fatal("Error getting client: %v", err)
|
||||
|
@ -43,17 +49,29 @@ itself, leaving all files intact. The cluster can be started again with the "sta
|
|||
}
|
||||
defer api.Close()
|
||||
|
||||
nonexistent := false
|
||||
|
||||
stop := func() (err error) {
|
||||
return cluster.StopHost(api)
|
||||
err = cluster.StopHost(api)
|
||||
switch err := errors.Cause(err).(type) {
|
||||
case mcnerror.ErrHostDoesNotExist:
|
||||
console.OutStyle("meh", "%q VM does not exist, nothing to stop", profile)
|
||||
nonexistent = true
|
||||
return nil
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := pkgutil.RetryAfter(5, stop, 1*time.Second); err != nil {
|
||||
console.Fatal("Error stopping machine: %v", err)
|
||||
console.Fatal("Unable to stop VM: %v", err)
|
||||
cmdUtil.MaybeReportErrorAndExit(err)
|
||||
}
|
||||
console.OutStyle("stopped", "Machine stopped.")
|
||||
if !nonexistent {
|
||||
console.OutStyle("stopped", "%q stopped.", profile)
|
||||
}
|
||||
|
||||
if err := cmdUtil.KillMountProcess(); err != nil {
|
||||
console.Fatal("Errors occurred deleting mount process: %v", err)
|
||||
console.Fatal("Unable to kill mount process: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func main() {
|
|||
}
|
||||
console.SetOutFile(os.Stdout)
|
||||
console.SetErrFile(os.Stderr)
|
||||
err := console.SetLanguage(os.Getenv("LANG"))
|
||||
err := console.SetPreferredLanguage(os.Getenv("LANG"))
|
||||
if err != nil {
|
||||
glog.Warningf("unable to detect language: %v", err)
|
||||
}
|
||||
|
|
|
@ -159,7 +159,6 @@ To disable this prompt, run: 'minikube config set WantReportErrorPrompt false'
|
|||
if err != nil {
|
||||
glog.Infof("report error failed: %v", err)
|
||||
}
|
||||
console.ErrStyle("embarassed", "minikube failed, exiting with error code %d", returnCode)
|
||||
os.Exit(returnCode)
|
||||
}
|
||||
|
||||
|
|
|
@ -383,10 +383,10 @@ func (k *KubeadmBootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
|
|||
}
|
||||
f, err := assets.NewFileAsset(path, "/usr/bin", bin, "0641")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "making new file asset")
|
||||
return errors.Wrap(err, "new file asset")
|
||||
}
|
||||
if err := k.c.Copy(f); err != nil {
|
||||
return errors.Wrapf(err, "transferring kubeadm file: %+v", f)
|
||||
return errors.Wrapf(err, "copy")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
@ -396,15 +396,16 @@ func (k *KubeadmBootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
|
|||
}
|
||||
|
||||
if err := addAddons(&files); err != nil {
|
||||
return errors.Wrap(err, "adding addons to copyable files")
|
||||
return errors.Wrap(err, "adding addons")
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if err := k.c.Copy(f); err != nil {
|
||||
return errors.Wrapf(err, "transferring kubeadm file: %+v", f)
|
||||
return errors.Wrapf(err, "copy")
|
||||
}
|
||||
}
|
||||
|
||||
console.OutStyle("celebrate", "Starting kubelet %s ...", cfg.KubernetesVersion)
|
||||
err = k.c.Run(`
|
||||
sudo systemctl daemon-reload &&
|
||||
sudo systemctl enable kubelet &&
|
||||
|
|
|
@ -64,7 +64,7 @@ func init() {
|
|||
func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error) {
|
||||
exists, err := api.Exists(cfg.GetMachineName())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error checking if host exists: %s", cfg.GetMachineName())
|
||||
return nil, errors.Wrapf(err, "machine name: %s", cfg.GetMachineName())
|
||||
}
|
||||
if !exists {
|
||||
glog.Infoln("Machine does not exist... provisioning new machine")
|
||||
|
@ -91,10 +91,10 @@ func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error)
|
|||
|
||||
if s != state.Running {
|
||||
if err := h.Driver.Start(); err != nil {
|
||||
return nil, errors.Wrap(err, "Error starting stopped host")
|
||||
return nil, errors.Wrap(err, "start")
|
||||
}
|
||||
if err := api.Save(h); err != nil {
|
||||
return nil, errors.Wrap(err, "Error saving started host")
|
||||
return nil, errors.Wrap(err, "save")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error)
|
|||
func StopHost(api libmachine.API) error {
|
||||
host, err := api.Load(cfg.GetMachineName())
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Load: %s", cfg.GetMachineName())
|
||||
return errors.Wrapf(err, "load")
|
||||
}
|
||||
if err := host.Stop(); err != nil {
|
||||
alreadyInStateError, ok := err.(mcnerror.ErrHostAlreadyInState)
|
||||
|
@ -138,19 +138,22 @@ func StopHost(api libmachine.API) error {
|
|||
func DeleteHost(api libmachine.API) error {
|
||||
host, err := api.Load(cfg.GetMachineName())
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Load: %s", cfg.GetMachineName())
|
||||
return errors.Wrap(err, "load")
|
||||
}
|
||||
m := util.MultiError{}
|
||||
m.Collect(host.Driver.Remove())
|
||||
m.Collect(api.Remove(cfg.GetMachineName()))
|
||||
return m.ToError()
|
||||
if err := host.Driver.Remove(); err != nil {
|
||||
return errors.Wrap(err, "host remove")
|
||||
}
|
||||
if err := api.Remove(cfg.GetMachineName()); err != nil {
|
||||
return errors.Wrap(err, "api remove")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetHostStatus gets the status of the host VM.
|
||||
func GetHostStatus(api libmachine.API) (string, error) {
|
||||
exists, err := api.Exists(cfg.GetMachineName())
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "Error checking that api exists for: %s", cfg.GetMachineName())
|
||||
return "", errors.Wrapf(err, "%s exists", cfg.GetMachineName())
|
||||
}
|
||||
if !exists {
|
||||
return state.None.String(), nil
|
||||
|
@ -158,12 +161,12 @@ func GetHostStatus(api libmachine.API) (string, error) {
|
|||
|
||||
host, err := api.Load(cfg.GetMachineName())
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "Error loading api for: %s", cfg.GetMachineName())
|
||||
return "", errors.Wrapf(err, "load")
|
||||
}
|
||||
|
||||
s, err := host.Driver.GetState()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Error getting host state")
|
||||
return "", errors.Wrap(err, "state")
|
||||
}
|
||||
return s.String(), nil
|
||||
}
|
||||
|
@ -177,11 +180,11 @@ func GetHostDriverIP(api libmachine.API, machineName string) (net.IP, error) {
|
|||
|
||||
ipStr, err := host.Driver.GetIP()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error getting IP")
|
||||
return nil, errors.Wrap(err, "getting IP")
|
||||
}
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("error parsing IP: %s", ipStr)
|
||||
return nil, fmt.Errorf("parsing IP: %s", ipStr)
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
|
@ -249,12 +252,12 @@ func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error
|
|||
|
||||
data, err := json.Marshal(driver)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error marshalling json")
|
||||
return nil, errors.Wrap(err, "marshal")
|
||||
}
|
||||
|
||||
h, err := api.NewHost(config.VMDriver, data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error creating new host")
|
||||
return nil, errors.Wrap(err, "new host")
|
||||
}
|
||||
|
||||
h.HostOptions.AuthOptions.CertDir = constants.GetMinipath()
|
||||
|
@ -264,11 +267,11 @@ func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error
|
|||
if err := api.Create(h); err != nil {
|
||||
// Wait for all the logs to reach the client
|
||||
time.Sleep(2 * time.Second)
|
||||
return nil, errors.Wrap(err, "Error creating host")
|
||||
return nil, errors.Wrap(err, "create")
|
||||
}
|
||||
|
||||
if err := api.Save(h); err != nil {
|
||||
return nil, errors.Wrap(err, "Error attempting to save")
|
||||
return nil, errors.Wrap(err, "save")
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
@ -310,11 +313,11 @@ func MountHost(api libmachine.API, ip net.IP, path, port, mountVersion string, u
|
|||
host.RunSSHCommand(GetMountCleanupCommand(path))
|
||||
mountCmd, err := GetMountCommand(ip, path, port, mountVersion, uid, gid, msize)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error getting mount command")
|
||||
return errors.Wrap(err, "mount command")
|
||||
}
|
||||
_, err = host.RunSSHCommand(mountCmd)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "running mount host command")
|
||||
return errors.Wrap(err, "running mount")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -332,13 +335,13 @@ func GetVMHostIP(host *host.Host) (net.IP, error) {
|
|||
hypervVirtualSwitch := re.FindStringSubmatch(string(host.RawDriver))[1]
|
||||
ip, err := getIPForInterface(fmt.Sprintf("vEthernet (%s)", hypervVirtualSwitch))
|
||||
if err != nil {
|
||||
return []byte{}, errors.Wrap(err, "Error getting VM/Host IP address")
|
||||
return []byte{}, errors.Wrap(err, fmt.Sprintf("ip for interface (%s)", hypervVirtualSwitch))
|
||||
}
|
||||
return ip, nil
|
||||
case "virtualbox":
|
||||
out, err := exec.Command(detectVBoxManageCmd(), "showvminfo", host.Name, "--machinereadable").Output()
|
||||
if err != nil {
|
||||
return []byte{}, errors.Wrap(err, "Error running vboxmanage command")
|
||||
return []byte{}, errors.Wrap(err, "vboxmanage")
|
||||
}
|
||||
re := regexp.MustCompile(`hostonlyadapter2="(.*?)"`)
|
||||
iface := re.FindStringSubmatch(string(out))[1]
|
||||
|
@ -388,21 +391,21 @@ func CreateSSHShell(api libmachine.API, args []string) error {
|
|||
machineName := cfg.GetMachineName()
|
||||
host, err := CheckIfHostExistsAndLoad(api, machineName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error checking if api exist and loading it")
|
||||
return errors.Wrap(err, "host exists and load")
|
||||
}
|
||||
|
||||
currentState, err := host.Driver.GetState()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error getting state of host")
|
||||
return errors.Wrap(err, "state")
|
||||
}
|
||||
|
||||
if currentState != state.Running {
|
||||
return errors.Errorf("Error: Cannot run ssh command: Host %q is not running", machineName)
|
||||
return errors.Errorf("%q is not running", machineName)
|
||||
}
|
||||
|
||||
client, err := host.CreateSSHClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error creating ssh client")
|
||||
return errors.Wrap(err, "Creating ssh client")
|
||||
}
|
||||
return client.Shell(args...)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2019 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 console provides a mechanism for sending localized, stylized output to the console.
|
||||
package console
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2019 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 console
|
||||
|
||||
import (
|
||||
|
@ -30,7 +46,7 @@ func (f *fakeFile) String() string {
|
|||
}
|
||||
|
||||
func TestOutStyle(t *testing.T) {
|
||||
os.Setenv(OverrideEnv, "")
|
||||
os.Setenv(OverrideEnv, "1")
|
||||
f := newFakeFile()
|
||||
SetOutFile(f)
|
||||
if err := OutStyle("happy", "This is a happy message."); err != nil {
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2019 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 console
|
||||
|
||||
import (
|
||||
|
@ -15,39 +31,45 @@ type style struct {
|
|||
}
|
||||
|
||||
// styles is a map of style name to style struct
|
||||
// For consistency, ensure that emojis added render with the same width across platforms.
|
||||
var styles = map[string]style{
|
||||
// General purpose
|
||||
"happy": style{Prefix: "😄"},
|
||||
"success": style{Prefix: "✅ "},
|
||||
"failure": style{Prefix: "❌"},
|
||||
"conflict": style{Prefix: "💥"},
|
||||
"fatal": style{Prefix: "💣"},
|
||||
"notice": style{Prefix: "📌"},
|
||||
"ready": style{Prefix: "🏄"},
|
||||
"restarting": style{Prefix: "🔁"},
|
||||
"stopping": style{Prefix: "🚦"},
|
||||
"stopped": style{Prefix: "🛑"},
|
||||
"warning": style{Prefix: "⚠️"},
|
||||
"waiting": style{Prefix: "⌛"},
|
||||
"usage": style{Prefix: "💡"},
|
||||
"launch": style{Prefix: "🚀"},
|
||||
"happy": {Prefix: "😄"},
|
||||
"success": {Prefix: "✅"},
|
||||
"failure": {Prefix: "❌"},
|
||||
"conflict": {Prefix: "💥"},
|
||||
"fatal": {Prefix: "💣"},
|
||||
"notice": {Prefix: "📌"},
|
||||
"ready": {Prefix: "🏄"},
|
||||
"restarting": {Prefix: "🔄"},
|
||||
"stopping": {Prefix: "✋"},
|
||||
"stopped": {Prefix: "🛑"},
|
||||
"warning": {Prefix: "⚠️"},
|
||||
"waiting": {Prefix: "⌛"},
|
||||
"usage": {Prefix: "💡"},
|
||||
"launch": {Prefix: "🚀"},
|
||||
"thumbs-up": {Prefix: "👍"},
|
||||
"options": {Prefix: " ⚫"},
|
||||
|
||||
// Specialized purpose
|
||||
"iso-download": style{Prefix: "💿"},
|
||||
"file-download": style{Prefix: "💾"},
|
||||
"caching": style{Prefix: "🤹"},
|
||||
"starting-vm": style{Prefix: "🔥"},
|
||||
"copying": style{Prefix: "✨"},
|
||||
"connectivity": style{Prefix: "📡"},
|
||||
"mounting": style{Prefix: "📁"},
|
||||
"celebrate": style{Prefix: "🎉"},
|
||||
"container-runtime": style{Prefix: "🎁"},
|
||||
"enabling": style{Prefix: "🔌"},
|
||||
"pulling": style{Prefix: "🚜"},
|
||||
"verifying": style{Prefix: "🤔"},
|
||||
"kubectl": style{Prefix: "❤️"},
|
||||
"meh": style{Prefix: "🙄"},
|
||||
"embarassed": style{Prefix: "🤦"},
|
||||
// Specialized purpose styles
|
||||
"iso-download": {Prefix: "💿"},
|
||||
"file-download": {Prefix: "💾"},
|
||||
"caching": {Prefix: "🤹"},
|
||||
"starting-vm": {Prefix: "🔥"},
|
||||
"starting-none": {Prefix: "🤹"},
|
||||
"deleting-vm": {Prefix: "🔥"},
|
||||
"copying": {Prefix: "✨"},
|
||||
"connectivity": {Prefix: "📡"},
|
||||
"mounting": {Prefix: "📁"},
|
||||
"celebrate": {Prefix: "🎉"},
|
||||
"container-runtime": {Prefix: "🎁"},
|
||||
"enabling": {Prefix: "🔌"},
|
||||
"pulling": {Prefix: "🚜"},
|
||||
"verifying": {Prefix: "🤔"},
|
||||
"verifying-noline": {Prefix: "🤔", OmitNewline: true},
|
||||
"kubectl": {Prefix: "💗"},
|
||||
"meh": {Prefix: "🙄"},
|
||||
"embarassed": {Prefix: "🤦"},
|
||||
"tip": {Prefix: "💡"},
|
||||
}
|
||||
|
||||
// Add a prefix to a string
|
||||
|
|
|
@ -19,7 +19,6 @@ package machine
|
|||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -121,7 +120,7 @@ func (api *LocalClient) NewHost(driverName string, rawDriver []byte) (*host.Host
|
|||
func (api *LocalClient) Load(name string) (*host.Host, error) {
|
||||
h, err := api.Filestore.Load(name)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error loading host from store")
|
||||
return nil, errors.Wrap(err, "filestore")
|
||||
}
|
||||
|
||||
var def registry.DriverDef
|
||||
|
@ -166,25 +165,25 @@ func (api *LocalClient) Create(h *host.Host) error {
|
|||
f func() error
|
||||
}{
|
||||
{
|
||||
"Bootstrapping certs.",
|
||||
"bootstrapping certificates",
|
||||
func() error { return cert.BootstrapCertificates(h.AuthOptions()) },
|
||||
},
|
||||
{
|
||||
"Running precreate checks.",
|
||||
"precreate",
|
||||
h.Driver.PreCreateCheck,
|
||||
},
|
||||
{
|
||||
"Saving driver.",
|
||||
"saving",
|
||||
func() error {
|
||||
return api.Save(h)
|
||||
},
|
||||
},
|
||||
{
|
||||
"Creating VM.",
|
||||
"creating",
|
||||
h.Driver.Create,
|
||||
},
|
||||
{
|
||||
"Waiting for VM to start.",
|
||||
"waiting",
|
||||
func() error {
|
||||
if h.Driver.DriverName() == "none" {
|
||||
return nil
|
||||
|
@ -193,7 +192,7 @@ func (api *LocalClient) Create(h *host.Host) error {
|
|||
},
|
||||
},
|
||||
{
|
||||
"Provisioning VM.",
|
||||
"provisioning",
|
||||
func() error {
|
||||
if h.Driver.DriverName() == "none" {
|
||||
return nil
|
||||
|
@ -206,7 +205,7 @@ func (api *LocalClient) Create(h *host.Host) error {
|
|||
|
||||
for _, step := range steps {
|
||||
if err := step.f(); err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Error executing step: %s\n", step.name))
|
||||
return errors.Wrap(err, step.name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ func TestRunDriver(t *testing.T) {
|
|||
}
|
||||
os.Stdout = old
|
||||
|
||||
fmt.Prinln(string(addr))
|
||||
fmt.Println(string(addr))
|
||||
|
||||
// Now that we got the port, make sure we can connect.
|
||||
if _, err := net.Dial("tcp", string(addr)); err != nil {
|
||||
|
|
|
@ -74,8 +74,7 @@ type URLHandlerCorrect struct {
|
|||
func (h *URLHandlerCorrect) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
b, err := json.Marshal(h.releases)
|
||||
if err != nil {
|
||||
// TODO(tstrombxerg): Do something else with this?
|
||||
fmt.ErrLn(err)
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
|
|
|
@ -48,25 +48,43 @@ func NewCodeWriter() *CodeWriter {
|
|||
}
|
||||
|
||||
// WriteGoFile appends the buffer with the total size of all created structures
|
||||
// and writes it as a Go file to the the given file with the given package name.
|
||||
// and writes it as a Go file to the given file with the given package name.
|
||||
func (w *CodeWriter) WriteGoFile(filename, pkg string) {
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err = w.WriteGo(f, pkg); err != nil {
|
||||
if _, err = w.WriteGo(f, pkg, ""); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteVersionedGoFile appends the buffer with the total size of all created
|
||||
// structures and writes it as a Go file to the given file with the given
|
||||
// package name and build tags for the current Unicode version,
|
||||
func (w *CodeWriter) WriteVersionedGoFile(filename, pkg string) {
|
||||
tags := buildTags()
|
||||
if tags != "" {
|
||||
filename = insertVersion(filename, UnicodeVersion())
|
||||
}
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err = w.WriteGo(f, pkg, tags); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteGo appends the buffer with the total size of all created structures and
|
||||
// writes it as a Go file to the the given writer with the given package name.
|
||||
func (w *CodeWriter) WriteGo(out io.Writer, pkg string) (n int, err error) {
|
||||
// writes it as a Go file to the given writer with the given package name.
|
||||
func (w *CodeWriter) WriteGo(out io.Writer, pkg, tags string) (n int, err error) {
|
||||
sz := w.Size
|
||||
w.WriteComment("Total table size %d bytes (%dKiB); checksum: %X\n", sz, sz/1024, w.Hash.Sum32())
|
||||
defer w.buf.Reset()
|
||||
return WriteGo(out, pkg, w.buf.Bytes())
|
||||
return WriteGo(out, pkg, tags, w.buf.Bytes())
|
||||
}
|
||||
|
||||
func (w *CodeWriter) printf(f string, x ...interface{}) {
|
||||
|
@ -181,7 +199,6 @@ func (w *CodeWriter) writeValue(v reflect.Value) {
|
|||
|
||||
// WriteString writes a string literal.
|
||||
func (w *CodeWriter) WriteString(s string) {
|
||||
s = strings.Replace(s, `\`, `\\`, -1)
|
||||
io.WriteString(w.Hash, s) // content hash
|
||||
w.Size += len(s)
|
||||
|
||||
|
@ -232,6 +249,9 @@ func (w *CodeWriter) WriteString(s string) {
|
|||
out = fmt.Sprintf("\\U%08x", r)
|
||||
}
|
||||
chars = len(out)
|
||||
} else if r == '\\' {
|
||||
out = "\\" + string(r)
|
||||
chars = 2
|
||||
}
|
||||
if n -= chars; n < 0 {
|
||||
nLines++
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
// This package defines command line flags that are common to most generation
|
||||
// tools. The flags allow for specifying specific Unicode and CLDR versions
|
||||
// in the public Unicode data repository (http://www.unicode.org/Public).
|
||||
// in the public Unicode data repository (https://www.unicode.org/Public).
|
||||
//
|
||||
// A local Unicode data mirror can be set through the flag -local or the
|
||||
// environment variable UNICODE_DIR. The former takes precedence. The local
|
||||
|
@ -31,6 +31,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
|
@ -39,7 +40,7 @@ import (
|
|||
|
||||
var (
|
||||
url = flag.String("url",
|
||||
"http://www.unicode.org/Public",
|
||||
"https://www.unicode.org/Public",
|
||||
"URL of Unicode database directory")
|
||||
iana = flag.String("iana",
|
||||
"http://www.iana.org",
|
||||
|
@ -69,8 +70,6 @@ func Init() {
|
|||
|
||||
const header = `// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
package %s
|
||||
|
||||
`
|
||||
|
||||
// UnicodeVersion reports the requested Unicode version.
|
||||
|
@ -78,11 +77,33 @@ func UnicodeVersion() string {
|
|||
return *unicodeVersion
|
||||
}
|
||||
|
||||
// UnicodeVersion reports the requested CLDR version.
|
||||
// CLDRVersion reports the requested CLDR version.
|
||||
func CLDRVersion() string {
|
||||
return *cldrVersion
|
||||
}
|
||||
|
||||
var tags = []struct{ version, buildTags string }{
|
||||
{"10.0.0", "go1.10"},
|
||||
{"", "!go1.10"},
|
||||
}
|
||||
|
||||
// buildTags reports the build tags used for the current Unicode version.
|
||||
func buildTags() string {
|
||||
v := UnicodeVersion()
|
||||
for _, x := range tags {
|
||||
// We should do a numeric comparison, but including the collate package
|
||||
// would create an import cycle. We approximate it by assuming that
|
||||
// longer version strings are later.
|
||||
if len(x.version) <= len(v) {
|
||||
return x.buildTags
|
||||
}
|
||||
if len(x.version) == len(v) && x.version <= v {
|
||||
return x.buildTags
|
||||
}
|
||||
}
|
||||
return tags[0].buildTags
|
||||
}
|
||||
|
||||
// IsLocal reports whether data files are available locally.
|
||||
func IsLocal() bool {
|
||||
dir, err := localReadmeFile()
|
||||
|
@ -243,15 +264,46 @@ func WriteGoFile(filename, pkg string, b []byte) {
|
|||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer w.Close()
|
||||
if _, err = WriteGo(w, pkg, b); err != nil {
|
||||
if _, err = WriteGo(w, pkg, "", b); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
func insertVersion(filename, version string) string {
|
||||
suffix := ".go"
|
||||
if strings.HasSuffix(filename, "_test.go") {
|
||||
suffix = "_test.go"
|
||||
}
|
||||
return fmt.Sprint(filename[:len(filename)-len(suffix)], version, suffix)
|
||||
}
|
||||
|
||||
// WriteVersionedGoFile prepends a standard file comment, adds build tags to
|
||||
// version the file for the current Unicode version, and package statement to
|
||||
// the given bytes, applies gofmt, and writes them to a file with the given
|
||||
// name. It will call log.Fatal if there are any errors.
|
||||
func WriteVersionedGoFile(filename, pkg string, b []byte) {
|
||||
tags := buildTags()
|
||||
if tags != "" {
|
||||
filename = insertVersion(filename, UnicodeVersion())
|
||||
}
|
||||
w, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer w.Close()
|
||||
if _, err = WriteGo(w, pkg, tags, b); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteGo prepends a standard file comment and package statement to the given
|
||||
// bytes, applies gofmt, and writes them to w.
|
||||
func WriteGo(w io.Writer, pkg string, b []byte) (n int, err error) {
|
||||
src := []byte(fmt.Sprintf(header, pkg))
|
||||
func WriteGo(w io.Writer, pkg, tags string, b []byte) (n int, err error) {
|
||||
src := []byte(header)
|
||||
if tags != "" {
|
||||
src = append(src, fmt.Sprintf("// +build %s\n\n", tags)...)
|
||||
}
|
||||
src = append(src, fmt.Sprintf("package %s\n\n", pkg)...)
|
||||
src = append(src, b...)
|
||||
formatted, err := format.Source(src)
|
||||
if err != nil {
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
// Indexes of starter blocks in case of multiple trie roots.
|
||||
//
|
||||
// It is recommended that users test the generated trie by checking the returned
|
||||
// value for every rune. Such exhaustive tests are possible as the the number of
|
||||
// value for every rune. Such exhaustive tests are possible as the number of
|
||||
// runes in Unicode is limited.
|
||||
package triegen // import "golang.org/x/text/internal/triegen"
|
||||
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ucd provides a parser for Unicode Character Database files, the
|
||||
// format of which is defined in http://www.unicode.org/reports/tr44/. See
|
||||
// http://www.unicode.org/Public/UCD/latest/ucd/ for example files.
|
||||
// format of which is defined in https://www.unicode.org/reports/tr44/. See
|
||||
// https://www.unicode.org/Public/UCD/latest/ucd/ for example files.
|
||||
//
|
||||
// It currently does not support substitutions of missing fields.
|
||||
package ucd // import "golang.org/x/text/internal/ucd"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"regexp"
|
||||
|
@ -92,10 +92,11 @@ type Parser struct {
|
|||
keepRanges bool // Don't expand rune ranges in field 0.
|
||||
|
||||
err error
|
||||
comment []byte
|
||||
field [][]byte
|
||||
comment string
|
||||
field []string
|
||||
// parsedRange is needed in case Range(0) is called more than once for one
|
||||
// field. In some cases this requires scanning ahead.
|
||||
line int
|
||||
parsedRange bool
|
||||
rangeStart, rangeEnd rune
|
||||
|
||||
|
@ -103,15 +104,19 @@ type Parser struct {
|
|||
commentHandler func(s string)
|
||||
}
|
||||
|
||||
func (p *Parser) setError(err error) {
|
||||
if p.err == nil {
|
||||
p.err = err
|
||||
func (p *Parser) setError(err error, msg string) {
|
||||
if p.err == nil && err != nil {
|
||||
if msg == "" {
|
||||
p.err = fmt.Errorf("ucd:line:%d: %v", p.line, err)
|
||||
} else {
|
||||
p.err = fmt.Errorf("ucd:line:%d:%s: %v", p.line, msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) getField(i int) []byte {
|
||||
func (p *Parser) getField(i int) string {
|
||||
if i >= len(p.field) {
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
return p.field[i]
|
||||
}
|
||||
|
@ -139,65 +144,66 @@ func (p *Parser) Next() bool {
|
|||
p.rangeStart++
|
||||
return true
|
||||
}
|
||||
p.comment = nil
|
||||
p.comment = ""
|
||||
p.field = p.field[:0]
|
||||
p.parsedRange = false
|
||||
|
||||
for p.scanner.Scan() {
|
||||
b := p.scanner.Bytes()
|
||||
if len(b) == 0 {
|
||||
for p.scanner.Scan() && p.err == nil {
|
||||
p.line++
|
||||
s := p.scanner.Text()
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
if b[0] == '#' {
|
||||
if s[0] == '#' {
|
||||
if p.commentHandler != nil {
|
||||
p.commentHandler(strings.TrimSpace(string(b[1:])))
|
||||
p.commentHandler(strings.TrimSpace(s[1:]))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse line
|
||||
if i := bytes.IndexByte(b, '#'); i != -1 {
|
||||
p.comment = bytes.TrimSpace(b[i+1:])
|
||||
b = b[:i]
|
||||
if i := strings.IndexByte(s, '#'); i != -1 {
|
||||
p.comment = strings.TrimSpace(s[i+1:])
|
||||
s = s[:i]
|
||||
}
|
||||
if b[0] == '@' {
|
||||
if s[0] == '@' {
|
||||
if p.partHandler != nil {
|
||||
p.field = append(p.field, bytes.TrimSpace(b[1:]))
|
||||
p.field = append(p.field, strings.TrimSpace(s[1:]))
|
||||
p.partHandler(p)
|
||||
p.field = p.field[:0]
|
||||
}
|
||||
p.comment = nil
|
||||
p.comment = ""
|
||||
continue
|
||||
}
|
||||
for {
|
||||
i := bytes.IndexByte(b, ';')
|
||||
i := strings.IndexByte(s, ';')
|
||||
if i == -1 {
|
||||
p.field = append(p.field, bytes.TrimSpace(b))
|
||||
p.field = append(p.field, strings.TrimSpace(s))
|
||||
break
|
||||
}
|
||||
p.field = append(p.field, bytes.TrimSpace(b[:i]))
|
||||
b = b[i+1:]
|
||||
p.field = append(p.field, strings.TrimSpace(s[:i]))
|
||||
s = s[i+1:]
|
||||
}
|
||||
if !p.keepRanges {
|
||||
p.rangeStart, p.rangeEnd = p.getRange(0)
|
||||
}
|
||||
return true
|
||||
}
|
||||
p.setError(p.scanner.Err())
|
||||
p.setError(p.scanner.Err(), "scanner failed")
|
||||
return false
|
||||
}
|
||||
|
||||
func parseRune(b []byte) (rune, error) {
|
||||
func parseRune(b string) (rune, error) {
|
||||
if len(b) > 2 && b[0] == 'U' && b[1] == '+' {
|
||||
b = b[2:]
|
||||
}
|
||||
x, err := strconv.ParseUint(string(b), 16, 32)
|
||||
x, err := strconv.ParseUint(b, 16, 32)
|
||||
return rune(x), err
|
||||
}
|
||||
|
||||
func (p *Parser) parseRune(b []byte) rune {
|
||||
x, err := parseRune(b)
|
||||
p.setError(err)
|
||||
func (p *Parser) parseRune(s string) rune {
|
||||
x, err := parseRune(s)
|
||||
p.setError(err, "failed to parse rune")
|
||||
return x
|
||||
}
|
||||
|
||||
|
@ -211,13 +217,13 @@ func (p *Parser) Rune(i int) rune {
|
|||
|
||||
// Runes interprets and returns field i as a sequence of runes.
|
||||
func (p *Parser) Runes(i int) (runes []rune) {
|
||||
add := func(b []byte) {
|
||||
if b = bytes.TrimSpace(b); len(b) > 0 {
|
||||
runes = append(runes, p.parseRune(b))
|
||||
add := func(s string) {
|
||||
if s = strings.TrimSpace(s); len(s) > 0 {
|
||||
runes = append(runes, p.parseRune(s))
|
||||
}
|
||||
}
|
||||
for b := p.getField(i); ; {
|
||||
i := bytes.IndexByte(b, ' ')
|
||||
i := strings.IndexByte(b, ' ')
|
||||
if i == -1 {
|
||||
add(b)
|
||||
break
|
||||
|
@ -247,7 +253,7 @@ func (p *Parser) Range(i int) (first, last rune) {
|
|||
|
||||
func (p *Parser) getRange(i int) (first, last rune) {
|
||||
b := p.getField(i)
|
||||
if k := bytes.Index(b, []byte("..")); k != -1 {
|
||||
if k := strings.Index(b, ".."); k != -1 {
|
||||
return p.parseRune(b[:k]), p.parseRune(b[k+2:])
|
||||
}
|
||||
// The first field may not be a rune, in which case we may ignore any error
|
||||
|
@ -260,23 +266,24 @@ func (p *Parser) getRange(i int) (first, last rune) {
|
|||
p.keepRanges = true
|
||||
}
|
||||
// Special case for UnicodeData that was retained for backwards compatibility.
|
||||
if i == 0 && len(p.field) > 1 && bytes.HasSuffix(p.field[1], []byte("First>")) {
|
||||
if i == 0 && len(p.field) > 1 && strings.HasSuffix(p.field[1], "First>") {
|
||||
if p.parsedRange {
|
||||
return p.rangeStart, p.rangeEnd
|
||||
}
|
||||
mf := reRange.FindStringSubmatch(p.scanner.Text())
|
||||
p.line++
|
||||
if mf == nil || !p.scanner.Scan() {
|
||||
p.setError(errIncorrectLegacyRange)
|
||||
p.setError(errIncorrectLegacyRange, "")
|
||||
return x, x
|
||||
}
|
||||
// Using Bytes would be more efficient here, but Text is a lot easier
|
||||
// and this is not a frequent case.
|
||||
ml := reRange.FindStringSubmatch(p.scanner.Text())
|
||||
if ml == nil || mf[2] != ml[2] || ml[3] != "Last" || mf[4] != ml[4] {
|
||||
p.setError(errIncorrectLegacyRange)
|
||||
p.setError(errIncorrectLegacyRange, "")
|
||||
return x, x
|
||||
}
|
||||
p.rangeStart, p.rangeEnd = x, p.parseRune(p.scanner.Bytes()[:len(ml[1])])
|
||||
p.rangeStart, p.rangeEnd = x, p.parseRune(p.scanner.Text()[:len(ml[1])])
|
||||
p.parsedRange = true
|
||||
return p.rangeStart, p.rangeEnd
|
||||
}
|
||||
|
@ -298,34 +305,34 @@ var bools = map[string]bool{
|
|||
|
||||
// Bool parses and returns field i as a boolean value.
|
||||
func (p *Parser) Bool(i int) bool {
|
||||
b := p.getField(i)
|
||||
f := p.getField(i)
|
||||
for s, v := range bools {
|
||||
if bstrEq(b, s) {
|
||||
if f == s {
|
||||
return v
|
||||
}
|
||||
}
|
||||
p.setError(strconv.ErrSyntax)
|
||||
p.setError(strconv.ErrSyntax, "error parsing bool")
|
||||
return false
|
||||
}
|
||||
|
||||
// Int parses and returns field i as an integer value.
|
||||
func (p *Parser) Int(i int) int {
|
||||
x, err := strconv.ParseInt(string(p.getField(i)), 10, 64)
|
||||
p.setError(err)
|
||||
p.setError(err, "error parsing int")
|
||||
return int(x)
|
||||
}
|
||||
|
||||
// Uint parses and returns field i as an unsigned integer value.
|
||||
func (p *Parser) Uint(i int) uint {
|
||||
x, err := strconv.ParseUint(string(p.getField(i)), 10, 64)
|
||||
p.setError(err)
|
||||
p.setError(err, "error parsing uint")
|
||||
return uint(x)
|
||||
}
|
||||
|
||||
// Float parses and returns field i as a decimal value.
|
||||
func (p *Parser) Float(i int) float64 {
|
||||
x, err := strconv.ParseFloat(string(p.getField(i)), 64)
|
||||
p.setError(err)
|
||||
p.setError(err, "error parsing float")
|
||||
return x
|
||||
}
|
||||
|
||||
|
@ -353,24 +360,12 @@ var errUndefinedEnum = errors.New("ucd: undefined enum value")
|
|||
// Enum interprets and returns field i as a value that must be one of the values
|
||||
// in enum.
|
||||
func (p *Parser) Enum(i int, enum ...string) string {
|
||||
b := p.getField(i)
|
||||
f := p.getField(i)
|
||||
for _, s := range enum {
|
||||
if bstrEq(b, s) {
|
||||
if f == s {
|
||||
return s
|
||||
}
|
||||
}
|
||||
p.setError(errUndefinedEnum)
|
||||
p.setError(errUndefinedEnum, "error parsing enum")
|
||||
return ""
|
||||
}
|
||||
|
||||
func bstrEq(b []byte, s string) bool {
|
||||
if len(b) != len(s) {
|
||||
return false
|
||||
}
|
||||
for i, c := range b {
|
||||
if c != s[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -155,6 +155,7 @@ func DirectionString(s string) bidi.Direction {
|
|||
e, sz := bidi.LookupString(s[i:])
|
||||
if sz == 0 {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
c := e.Class()
|
||||
if c == bidi.R || c == bidi.AL || c == bidi.AN {
|
||||
|
@ -202,13 +203,6 @@ func (t *Transformer) isRTL() bool {
|
|||
return t.seen&isRTL != 0
|
||||
}
|
||||
|
||||
func (t *Transformer) isFinal() bool {
|
||||
if !t.isRTL() {
|
||||
return true
|
||||
}
|
||||
return t.state == ruleLTRFinal || t.state == ruleRTLFinal || t.state == ruleInitial
|
||||
}
|
||||
|
||||
// Reset implements transform.Transformer.
|
||||
func (t *Transformer) Reset() { *t = Transformer{} }
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ type SpanningTransformer interface {
|
|||
// considering the error err.
|
||||
//
|
||||
// A nil error means that all input bytes are known to be identical to the
|
||||
// output produced by the Transformer. A nil error can be be returned
|
||||
// regardless of whether atEOF is true. If err is nil, then then n must
|
||||
// output produced by the Transformer. A nil error can be returned
|
||||
// regardless of whether atEOF is true. If err is nil, then n must
|
||||
// equal len(src); the converse is not necessarily true.
|
||||
//
|
||||
// ErrEndOfSpan means that the Transformer output may differ from the
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// Package bidi contains functionality for bidirectional text support.
|
||||
//
|
||||
// See http://www.unicode.org/reports/tr9.
|
||||
// See https://www.unicode.org/reports/tr9.
|
||||
//
|
||||
// NOTE: UNDER CONSTRUCTION. This API may change in backwards incompatible ways
|
||||
// and without notice.
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
// This file contains a port of the reference implementation of the
|
||||
// Bidi Parentheses Algorithm:
|
||||
// http://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/BidiPBAReference.java
|
||||
// https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/BidiPBAReference.java
|
||||
//
|
||||
// The implementation in this file covers definitions BD14-BD16 and rule N0
|
||||
// of UAX#9.
|
||||
|
@ -246,7 +246,7 @@ func (p *bracketPairer) getStrongTypeN0(index int) Class {
|
|||
// assuming the given embedding direction.
|
||||
//
|
||||
// It returns ON if no strong type is found. If a single strong type is found,
|
||||
// it returns this this type. Otherwise it returns the embedding direction.
|
||||
// it returns this type. Otherwise it returns the embedding direction.
|
||||
//
|
||||
// TODO: use separate type for "strong" directionality.
|
||||
func (p *bracketPairer) classifyPairContent(loc bracketPair, dirEmbed Class) Class {
|
||||
|
|
|
@ -7,7 +7,7 @@ package bidi
|
|||
import "log"
|
||||
|
||||
// This implementation is a port based on the reference implementation found at:
|
||||
// http://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/
|
||||
// https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/
|
||||
//
|
||||
// described in Unicode Bidirectional Algorithm (UAX #9).
|
||||
//
|
||||
|
|
|
@ -26,7 +26,7 @@ func main() {
|
|||
}
|
||||
|
||||
// bidiClass names and codes taken from class "bc" in
|
||||
// http://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt
|
||||
// https://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt
|
||||
var bidiClass = map[string]Class{
|
||||
"AL": AL, // ArabicLetter
|
||||
"AN": AN, // ArabicNumber
|
||||
|
@ -59,7 +59,7 @@ func genTables() {
|
|||
log.Fatalf("Too many Class constants (%#x > 0x0F).", numClass)
|
||||
}
|
||||
w := gen.NewCodeWriter()
|
||||
defer w.WriteGoFile(*outputFile, "bidi")
|
||||
defer w.WriteVersionedGoFile(*outputFile, "bidi")
|
||||
|
||||
gen.WriteUnicodeVersion(w)
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
// These tables are hand-extracted from:
|
||||
// http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt
|
||||
// https://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt
|
||||
func visitDefaults(fn func(r rune, c Class)) {
|
||||
// first write default values for ranges listed above.
|
||||
visitRunes(fn, AL, []rune{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -62,6 +62,11 @@ func (e *Common) Default() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// Element returns the XML element name.
|
||||
func (e *Common) Element() string {
|
||||
return e.name
|
||||
}
|
||||
|
||||
// GetCommon returns e. It is provided such that Common implements Elem.
|
||||
func (e *Common) GetCommon() *Common {
|
||||
return e
|
||||
|
|
|
@ -5,14 +5,15 @@
|
|||
//go:generate go run makexml.go -output xml.go
|
||||
|
||||
// Package cldr provides a parser for LDML and related XML formats.
|
||||
// This package is intended to be used by the table generation tools
|
||||
// for the various internationalization-related packages.
|
||||
// As the XML types are generated from the CLDR DTD, and as the CLDR standard
|
||||
// is periodically amended, this package may change considerably over time.
|
||||
// This mostly means that data may appear and disappear between versions.
|
||||
// That is, old code should keep compiling for newer versions, but data
|
||||
// may have moved or changed.
|
||||
// CLDR version 22 is the first version supported by this package.
|
||||
//
|
||||
// This package is intended to be used by the table generation tools for the
|
||||
// various packages in x/text and is not internal for historical reasons.
|
||||
//
|
||||
// As the XML types are generated from the CLDR DTD, and as the CLDR standard is
|
||||
// periodically amended, this package may change considerably over time. This
|
||||
// mostly means that data may appear and disappear between versions. That is,
|
||||
// old code should keep compiling for newer versions, but data may have moved or
|
||||
// changed. CLDR version 22 is the first version supported by this package.
|
||||
// Older versions may not work.
|
||||
package cldr // import "golang.org/x/text/unicode/cldr"
|
||||
|
||||
|
@ -94,6 +95,12 @@ func (cldr *CLDR) RawLDML(loc string) *LDML {
|
|||
|
||||
// LDML returns the fully resolved LDML XML for loc, which must be one of
|
||||
// the strings returned by Locales.
|
||||
//
|
||||
// Deprecated: use RawLDML and implement inheritance manually or using the
|
||||
// internal cldrtree package.
|
||||
// Inheritance has changed quite a bit since the onset of this package and in
|
||||
// practice data often represented in a way where knowledge of how it was
|
||||
// inherited is relevant.
|
||||
func (cldr *CLDR) LDML(loc string) (*LDML, error) {
|
||||
return cldr.resolve(loc)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ const (
|
|||
// cldrIndex is a Unicode-reserved sentinel value used to mark the start
|
||||
// of a grouping within an index.
|
||||
// We ignore any rule that starts with this rune.
|
||||
// See http://unicode.org/reports/tr35/#Collation_Elements for details.
|
||||
// See https://unicode.org/reports/tr35/#Collation_Elements for details.
|
||||
cldrIndex = "\uFDD0"
|
||||
|
||||
// specialAnchor is the format in which to represent logical reset positions,
|
||||
|
@ -51,7 +51,7 @@ func (c Collation) Process(p RuleProcessor) (err error) {
|
|||
}
|
||||
|
||||
// processRules parses rules in the Collation Rule Syntax defined in
|
||||
// http://www.unicode.org/reports/tr35/tr35-collation.html#Collation_Tailorings.
|
||||
// https://www.unicode.org/reports/tr35/tr35-collation.html#Collation_Tailorings.
|
||||
func processRules(p RuleProcessor, s string) (err error) {
|
||||
chk := func(s string, e error) string {
|
||||
if err == nil {
|
||||
|
|
|
@ -47,7 +47,7 @@ type Loader interface {
|
|||
Reader(i int) (io.ReadCloser, error)
|
||||
}
|
||||
|
||||
var fileRe = regexp.MustCompile(".*/(.*)/(.*)\\.xml")
|
||||
var fileRe = regexp.MustCompile(`.*[/\\](.*)[/\\](.*)\.xml`)
|
||||
|
||||
// Decode loads and decodes the files represented by l.
|
||||
func (d *Decoder) Decode(l Loader) (cldr *CLDR, err error) {
|
||||
|
@ -58,9 +58,10 @@ func (d *Decoder) Decode(l Loader) (cldr *CLDR, err error) {
|
|||
if len(d.dirFilter) > 0 && !in(d.dirFilter, m[1]) {
|
||||
continue
|
||||
}
|
||||
var r io.Reader
|
||||
var r io.ReadCloser
|
||||
if r, err = l.Reader(i); err == nil {
|
||||
err = d.decode(m[1], m[2], r)
|
||||
r.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -100,7 +101,7 @@ func (d *Decoder) decode(dir, id string, r io.Reader) error {
|
|||
if l.Identity == nil {
|
||||
return fmt.Errorf("%s/%s: missing identity element", dir, id)
|
||||
}
|
||||
// TODO: verify when CLDR bug http://unicode.org/cldr/trac/ticket/8970
|
||||
// TODO: verify when CLDR bug https://unicode.org/cldr/trac/ticket/8970
|
||||
// is resolved.
|
||||
// path := strings.Split(id, "_")
|
||||
// if lang := l.Identity.Language.Type; lang != path[0] {
|
||||
|
|
|
@ -153,7 +153,7 @@ var comments = map[string]string{
|
|||
// Dates contains information regarding the format and parsing of dates and times.
|
||||
`,
|
||||
"localeDisplayNames": `
|
||||
// LocaleDisplayNames specifies localized display names for for scripts, languages,
|
||||
// LocaleDisplayNames specifies localized display names for scripts, languages,
|
||||
// countries, currencies, and variants.
|
||||
`,
|
||||
"numbers": `
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
package cldr
|
||||
|
||||
// This file implements the various inheritance constructs defined by LDML.
|
||||
// See http://www.unicode.org/reports/tr35/#Inheritance_and_Validity
|
||||
// See https://www.unicode.org/reports/tr35/#Inheritance_and_Validity
|
||||
// for more details.
|
||||
|
||||
import (
|
||||
|
@ -309,7 +309,7 @@ func in(set []string, s string) bool {
|
|||
}
|
||||
|
||||
// attrKey computes a key based on the distinguishable attributes of
|
||||
// an element and it's values.
|
||||
// an element and its values.
|
||||
func attrKey(v reflect.Value, exclude ...string) string {
|
||||
parts := []string{}
|
||||
ename := v.Interface().(Elem).GetCommon().name
|
||||
|
|
|
@ -636,6 +636,13 @@ type SupplementalData struct {
|
|||
Path string `xml:"path,attr"`
|
||||
} `xml:"rgPath"`
|
||||
} `xml:"rgScope"`
|
||||
LanguageGroups *struct {
|
||||
Common
|
||||
LanguageGroup []*struct {
|
||||
Common
|
||||
Parent string `xml:"parent,attr"`
|
||||
} `xml:"languageGroup"`
|
||||
} `xml:"languageGroups"`
|
||||
}
|
||||
|
||||
// LDML is the top-level type for locale-specific data.
|
||||
|
@ -1230,7 +1237,7 @@ type TimeZoneNames struct {
|
|||
} `xml:"metazone"`
|
||||
}
|
||||
|
||||
// LocaleDisplayNames specifies localized display names for for scripts, languages,
|
||||
// LocaleDisplayNames specifies localized display names for scripts, languages,
|
||||
// countries, currencies, and variants.
|
||||
type LocaleDisplayNames struct {
|
||||
Common
|
||||
|
@ -1484,4 +1491,4 @@ type Numbers struct {
|
|||
}
|
||||
|
||||
// Version is the version of CLDR from which the XML definitions are generated.
|
||||
const Version = "31"
|
||||
const Version = "32"
|
||||
|
|
|
@ -407,7 +407,7 @@ func decomposeHangul(buf []byte, r rune) int {
|
|||
|
||||
// decomposeHangul algorithmically decomposes a Hangul rune into
|
||||
// its Jamo components.
|
||||
// See http://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul.
|
||||
// See https://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul.
|
||||
func (rb *reorderBuffer) decomposeHangul(r rune) {
|
||||
r -= hangulBase
|
||||
x := r % jamoTCount
|
||||
|
@ -420,7 +420,7 @@ func (rb *reorderBuffer) decomposeHangul(r rune) {
|
|||
}
|
||||
|
||||
// combineHangul algorithmically combines Jamo character components into Hangul.
|
||||
// See http://unicode.org/reports/tr15/#Hangul for details on combining Hangul.
|
||||
// See https://unicode.org/reports/tr15/#Hangul for details on combining Hangul.
|
||||
func (rb *reorderBuffer) combineHangul(s, i, k int) {
|
||||
b := rb.rune[:]
|
||||
bn := rb.nrune
|
||||
|
@ -461,6 +461,10 @@ func (rb *reorderBuffer) combineHangul(s, i, k int) {
|
|||
// It should only be used to recompose a single segment, as it will not
|
||||
// handle alternations between Hangul and non-Hangul characters correctly.
|
||||
func (rb *reorderBuffer) compose() {
|
||||
// Lazily load the map used by the combine func below, but do
|
||||
// it outside of the loop.
|
||||
recompMapOnce.Do(buildRecompMap)
|
||||
|
||||
// UAX #15, section X5 , including Corrigendum #5
|
||||
// "In any character sequence beginning with starter S, a character C is
|
||||
// blocked from S if and only if there is some character B between S
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package norm
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// This file contains Form-specific logic and wrappers for data in tables.go.
|
||||
|
||||
// Rune info is stored in a separate trie per composing form. A composing form
|
||||
|
@ -178,6 +180,17 @@ func (p Properties) TrailCCC() uint8 {
|
|||
return ccc[p.tccc]
|
||||
}
|
||||
|
||||
func buildRecompMap() {
|
||||
recompMap = make(map[uint32]rune, len(recompMapPacked)/8)
|
||||
var buf [8]byte
|
||||
for i := 0; i < len(recompMapPacked); i += 8 {
|
||||
copy(buf[:], recompMapPacked[i:i+8])
|
||||
key := binary.BigEndian.Uint32(buf[:4])
|
||||
val := binary.BigEndian.Uint32(buf[4:])
|
||||
recompMap[key] = rune(val)
|
||||
}
|
||||
}
|
||||
|
||||
// Recomposition
|
||||
// We use 32-bit keys instead of 64-bit for the two codepoint keys.
|
||||
// This clips off the bits of three entries, but we know this will not
|
||||
|
@ -186,8 +199,14 @@ func (p Properties) TrailCCC() uint8 {
|
|||
// Note that the recomposition map for NFC and NFKC are identical.
|
||||
|
||||
// combine returns the combined rune or 0 if it doesn't exist.
|
||||
//
|
||||
// The caller is responsible for calling
|
||||
// recompMapOnce.Do(buildRecompMap) sometime before this is called.
|
||||
func combine(a, b rune) rune {
|
||||
key := uint32(uint16(a))<<16 + uint32(uint16(b))
|
||||
if recompMap == nil {
|
||||
panic("caller error") // see func comment
|
||||
}
|
||||
return recompMap[key]
|
||||
}
|
||||
|
||||
|
|
|
@ -128,8 +128,9 @@ func (i *Iter) Next() []byte {
|
|||
func nextASCIIBytes(i *Iter) []byte {
|
||||
p := i.p + 1
|
||||
if p >= i.rb.nsrc {
|
||||
p0 := i.p
|
||||
i.setDone()
|
||||
return i.rb.src.bytes[i.p:p]
|
||||
return i.rb.src.bytes[p0:p]
|
||||
}
|
||||
if i.rb.src.bytes[p] < utf8.RuneSelf {
|
||||
p0 := i.p
|
||||
|
|
|
@ -12,6 +12,7 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -261,7 +262,7 @@ func compactCCC() {
|
|||
|
||||
// CompositionExclusions.txt has form:
|
||||
// 0958 # ...
|
||||
// See http://unicode.org/reports/tr44/ for full explanation
|
||||
// See https://unicode.org/reports/tr44/ for full explanation
|
||||
func loadCompositionExclusions() {
|
||||
f := gen.OpenUCDFile("CompositionExclusions.txt")
|
||||
defer f.Close()
|
||||
|
@ -735,6 +736,8 @@ func makeTables() {
|
|||
max = n
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(w, `import "sync"`)
|
||||
fmt.Fprintln(w)
|
||||
|
||||
fmt.Fprintln(w, "const (")
|
||||
fmt.Fprintln(w, "\t// Version is the Unicode edition from which the tables are derived.")
|
||||
|
@ -782,20 +785,27 @@ func makeTables() {
|
|||
sz := nrentries * 8
|
||||
size += sz
|
||||
fmt.Fprintf(w, "// recompMap: %d bytes (entries only)\n", sz)
|
||||
fmt.Fprintln(w, "var recompMap = map[uint32]rune{")
|
||||
fmt.Fprintln(w, "var recompMap map[uint32]rune")
|
||||
fmt.Fprintln(w, "var recompMapOnce sync.Once\n")
|
||||
fmt.Fprintln(w, `const recompMapPacked = "" +`)
|
||||
var buf [8]byte
|
||||
for i, c := range chars {
|
||||
f := c.forms[FCanonical]
|
||||
d := f.decomp
|
||||
if !f.isOneWay && len(d) > 0 {
|
||||
key := uint32(uint16(d[0]))<<16 + uint32(uint16(d[1]))
|
||||
fmt.Fprintf(w, "0x%.8X: 0x%.4X,\n", key, i)
|
||||
binary.BigEndian.PutUint32(buf[:4], key)
|
||||
binary.BigEndian.PutUint32(buf[4:], uint32(i))
|
||||
fmt.Fprintf(w, "\t\t%q + // 0x%.8X: 0x%.8X\n", string(buf[:]), key, uint32(i))
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(w, "}\n\n")
|
||||
// hack so we don't have to special case the trailing plus sign
|
||||
fmt.Fprintf(w, ` ""`)
|
||||
fmt.Fprintln(w)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "// Total size of tables: %dKB (%d bytes)\n", (size+512)/1024, size)
|
||||
gen.WriteGoFile("tables.go", "norm", w.Bytes())
|
||||
gen.WriteVersionedGoFile("tables.go", "norm", w.Bytes())
|
||||
}
|
||||
|
||||
func printChars() {
|
||||
|
@ -857,7 +867,7 @@ func verifyComputed() {
|
|||
// DerivedNormalizationProps.txt has form:
|
||||
// 00C0..00C5 ; NFD_QC; N # ...
|
||||
// 0374 ; NFD_QC; N # ...
|
||||
// See http://unicode.org/reports/tr44/ for full explanation
|
||||
// See https://unicode.org/reports/tr44/ for full explanation
|
||||
func testDerived() {
|
||||
f := gen.OpenUCDFile("DerivedNormalizationProps.txt")
|
||||
defer f.Close()
|
||||
|
@ -972,5 +982,5 @@ func printTestdata() {
|
|||
}
|
||||
}
|
||||
fmt.Fprintln(w, "}")
|
||||
gen.WriteGoFile("data_test.go", "norm", w.Bytes())
|
||||
gen.WriteVersionedGoFile("data_test.go", "norm", w.Bytes())
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ import (
|
|||
// proceed independently on both sides:
|
||||
// f(x) == append(f(x[0:n]), f(x[n:])...)
|
||||
//
|
||||
// References: http://unicode.org/reports/tr15/ and
|
||||
// http://unicode.org/notes/tn5/.
|
||||
// References: https://unicode.org/reports/tr15/ and
|
||||
// https://unicode.org/notes/tn5/.
|
||||
type Form int
|
||||
|
||||
const (
|
||||
|
|
|
@ -60,8 +60,8 @@ func (w *normWriter) Close() error {
|
|||
}
|
||||
|
||||
// Writer returns a new writer that implements Write(b)
|
||||
// by writing f(b) to w. The returned writer may use an
|
||||
// an internal buffer to maintain state across Write calls.
|
||||
// by writing f(b) to w. The returned writer may use an
|
||||
// internal buffer to maintain state across Write calls.
|
||||
// Calling its Close method writes any buffered data to w.
|
||||
func (f Form) Writer(w io.Writer) io.WriteCloser {
|
||||
wr := &normWriter{rb: reorderBuffer{}, w: w}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,7 +18,6 @@ func (Form) Reset() {}
|
|||
// Users should either catch ErrShortDst and allow dst to grow or have dst be at
|
||||
// least of size MaxTransformChunkSize to be guaranteed of progress.
|
||||
func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||
n := 0
|
||||
// Cap the maximum number of src bytes to check.
|
||||
b := src
|
||||
eof := atEOF
|
||||
|
@ -27,20 +26,21 @@ func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error)
|
|||
eof = false
|
||||
b = b[:ns]
|
||||
}
|
||||
i, ok := formTable[f].quickSpan(inputBytes(b), n, len(b), eof)
|
||||
n += copy(dst[n:], b[n:i])
|
||||
i, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), eof)
|
||||
n := copy(dst, b[:i])
|
||||
if !ok {
|
||||
nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF)
|
||||
return nDst + n, nSrc + n, err
|
||||
}
|
||||
if n < len(src) && !atEOF {
|
||||
|
||||
if err == nil && n < len(src) && !atEOF {
|
||||
err = transform.ErrShortSrc
|
||||
}
|
||||
return n, n, err
|
||||
}
|
||||
|
||||
func flushTransform(rb *reorderBuffer) bool {
|
||||
// Write out (must fully fit in dst, or else it is a ErrShortDst).
|
||||
// Write out (must fully fit in dst, or else it is an ErrShortDst).
|
||||
if len(rb.out) < rb.nrune*utf8.UTFMax {
|
||||
return false
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error)
|
|||
nSrc += n
|
||||
nDst += n
|
||||
if ok {
|
||||
if n < rb.nsrc && !atEOF {
|
||||
if err == nil && n < rb.nsrc && !atEOF {
|
||||
err = transform.ErrShortSrc
|
||||
}
|
||||
return nDst, nSrc, err
|
||||
|
|
|
@ -13,12 +13,13 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/text/collate"
|
||||
"golang.org/x/text/internal/gen"
|
||||
"golang.org/x/text/internal/ucd"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/unicode/rangetable"
|
||||
)
|
||||
|
||||
|
@ -30,15 +31,16 @@ To bootstrap the code generation, run:
|
|||
go run gen.go --versions=4.1.0,5.0.0,6.0.0,6.1.0,6.2.0,6.3.0,7.0.0
|
||||
|
||||
and ensure that the latest versions are included by checking:
|
||||
http://www.unicode.org/Public/`
|
||||
https://www.unicode.org/Public/`
|
||||
|
||||
func getVersions() []string {
|
||||
if *versionList == "" {
|
||||
log.Fatal(bootstrapMessage)
|
||||
}
|
||||
|
||||
c := collate.New(language.Und, collate.Numeric)
|
||||
versions := strings.Split(*versionList, ",")
|
||||
sort.Strings(versions)
|
||||
c.SortStrings(versions)
|
||||
|
||||
// Ensure that at least the current version is included.
|
||||
for _, v := range versions {
|
||||
|
@ -48,7 +50,7 @@ func getVersions() []string {
|
|||
}
|
||||
|
||||
versions = append(versions, gen.UnicodeVersion())
|
||||
sort.Strings(versions)
|
||||
c.SortStrings(versions)
|
||||
return versions
|
||||
}
|
||||
|
||||
|
@ -74,7 +76,7 @@ func main() {
|
|||
for _, v := range versions {
|
||||
assigned := []rune{}
|
||||
|
||||
r := gen.Open("http://www.unicode.org/Public/", "", v+"/ucd/UnicodeData.txt")
|
||||
r := gen.Open("https://www.unicode.org/Public/", "", v+"/ucd/UnicodeData.txt")
|
||||
ucd.Parse(r, func(p *ucd.Parser) {
|
||||
assigned = append(assigned, p.Rune(0))
|
||||
})
|
||||
|
@ -93,7 +95,7 @@ func main() {
|
|||
|
||||
fmt.Fprintf(w, "// Total size %d bytes (%d KiB)\n", size, size/1024)
|
||||
|
||||
gen.WriteGoFile("tables.go", "rangetable", w.Bytes())
|
||||
gen.WriteVersionedGoFile("tables.go", "rangetable", w.Bytes())
|
||||
}
|
||||
|
||||
func print(w io.Writer, rt *unicode.RangeTable) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue