1
0
mirror of https://github.com/coreos/mantle.git synced 2026-02-05 18:45:05 +01:00
Files
mantle/cli/cli.go
Euan Kemp f13fb5a397 cli: fix --debug flag not working
cobra's PersistentPreRun's are designed such that each new one overrides
all parent ones.

We're using a PersistentPreRun to setup logging though, and clearly want
that to cascade all the way.

This adds a small helper function so each override is done by pushing a
new function onto a stack rather than by replacing the previous one.
2017-01-25 15:14:01 -08:00

123 lines
3.5 KiB
Go

// Copyright 2014 CoreOS, Inc.
//
// 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 cli
import (
"os"
"github.com/coreos/pkg/capnslog"
"github.com/spf13/cobra"
"github.com/coreos/mantle/system/exec"
"github.com/coreos/mantle/version"
)
var (
versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number and exit.",
Run: func(cmd *cobra.Command, args []string) {
cmd.Printf("mantle/%s version %s\n",
cmd.Root().Name(), version.Version)
},
}
logDebug bool
logVerbose bool
logLevel = capnslog.NOTICE
plog = capnslog.NewPackageLogger("github.com/coreos/mantle", "cli")
)
// Execute sets up common features that all mantle commands should share
// and then executes the command. It does not return.
func Execute(main *cobra.Command) {
// If we were invoked via a multicall entrypoint run it instead.
// TODO(marineam): should we figure out a way to initialize logging?
exec.MaybeExec()
main.AddCommand(versionCmd)
// TODO(marineam): pflags defines the Value interface differently,
// update capnslog accordingly...
main.PersistentFlags().Var(&logLevel, "log-level",
"Set global log level.")
main.PersistentFlags().BoolVarP(&logVerbose, "verbose", "v", false,
"Alias for --log-level=INFO")
main.PersistentFlags().BoolVarP(&logDebug, "debug", "d", false,
"Alias for --log-level=DEBUG")
WrapPreRun(main, func(cmd *cobra.Command, args []string) error {
startLogging(cmd)
return nil
})
if err := main.Execute(); err != nil {
plog.Fatal(err)
}
os.Exit(0)
}
func setRepoLogLevel(repo string, l capnslog.LogLevel) {
r, err := capnslog.GetRepoLogger(repo)
if err != nil {
return // don't care if it isn't linked in
}
r.SetRepoLogLevel(l)
}
func startLogging(cmd *cobra.Command) {
switch {
case logDebug:
logLevel = capnslog.DEBUG
case logVerbose:
logLevel = capnslog.INFO
}
capnslog.SetFormatter(capnslog.NewStringFormatter(cmd.Out()))
capnslog.SetGlobalLogLevel(logLevel)
// In the context of the internally linked etcd, the NOTICE messages
// aren't really interesting, so translate NOTICE to WARNING instead.
if logLevel == capnslog.NOTICE {
// etcd sure has a lot of repos in its repo
setRepoLogLevel("github.com/coreos/etcd", capnslog.WARNING)
setRepoLogLevel("github.com/coreos/etcd/etcdserver", capnslog.WARNING)
setRepoLogLevel("github.com/coreos/etcd/etcdserver/etcdhttp", capnslog.WARNING)
setRepoLogLevel("github.com/coreos/etcd/pkg", capnslog.WARNING)
}
plog.Infof("Started logging at level %s", logLevel)
}
type PreRunEFunc func(cmd *cobra.Command, args []string) error
func WrapPreRun(root *cobra.Command, f PreRunEFunc) {
preRun, preRunE := root.PersistentPreRun, root.PersistentPreRunE
root.PersistentPreRun, root.PersistentPreRunE = nil, nil
root.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
if err := f(cmd, args); err != nil {
return err
}
if preRun != nil {
preRun(cmd, args)
} else if preRunE != nil {
return preRunE(cmd, args)
}
return nil
}
}