newt/cli/target_cfg_cmds.go (832 lines of code) (raw):

/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ // Implements commands that show or modify a target's configuration. package cli import ( "bytes" "fmt" "io" "io/ioutil" "sort" "strings" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "mynewt.apache.org/newt/newt/builder" "mynewt.apache.org/newt/newt/dump" "mynewt.apache.org/newt/newt/logcfg" "mynewt.apache.org/newt/newt/newtutil" "mynewt.apache.org/newt/newt/pkg" "mynewt.apache.org/newt/newt/resolve" "mynewt.apache.org/newt/newt/stage" "mynewt.apache.org/newt/newt/syscfg" "mynewt.apache.org/newt/newt/sysdown" "mynewt.apache.org/newt/newt/sysinit" "mynewt.apache.org/newt/newt/val" "mynewt.apache.org/newt/util" ) func printSetting(entry syscfg.CfgEntry) { util.StatusMessage(util.VERBOSITY_DEFAULT, " * Setting: %s\n", entry.Name) util.StatusMessage(util.VERBOSITY_DEFAULT, " * Description: %s\n", entry.Description) util.StatusMessage(util.VERBOSITY_DEFAULT, " * Value: %s", entry.Value) util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") if len(entry.History) > 1 { util.StatusMessage(util.VERBOSITY_DEFAULT, " * Overridden: ") for i := 1; i < len(entry.History); i++ { var fullName string lpkg := entry.History[i].Source if lpkg == nil { fullName = "<command line>" } else { fullName = lpkg.FullName() } util.StatusMessage(util.VERBOSITY_DEFAULT, "%s, ", fullName) } util.StatusMessage(util.VERBOSITY_DEFAULT, "default=%s\n", entry.History[0].Value) } if len(entry.ValueRefName) > 0 { util.StatusMessage(util.VERBOSITY_DEFAULT, " * Copied from: %s\n", entry.ValueRefName) } } func printBriefSetting(entry syscfg.CfgEntry) { util.StatusMessage(util.VERBOSITY_DEFAULT, " %s: %s", entry.Name, entry.Value) var extras []string if len(entry.History) > 1 { var fullName string lpkg := entry.History[len(entry.History)-1].Source if lpkg == nil { fullName = "<command line>" } else { fullName = lpkg.FullName() } s := fmt.Sprintf("overridden by %s", fullName) extras = append(extras, s) } if len(entry.ValueRefName) > 0 { s := fmt.Sprintf("copied from %s", entry.ValueRefName) extras = append(extras, s) } if len(extras) > 0 { util.StatusMessage(util.VERBOSITY_DEFAULT, " (%s)", strings.Join(extras, ", ")) } util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } func printPkgCfg(pkgName string, cfg syscfg.Cfg, entries []syscfg.CfgEntry) { util.StatusMessage(util.VERBOSITY_DEFAULT, "* PACKAGE: %s\n", pkgName) settingNames := make([]string, len(entries)) for i, entry := range entries { settingNames[i] = entry.Name } sort.Strings(settingNames) for _, name := range settingNames { printSetting(cfg.Settings[name]) } } func printCfg(targetName string, cfg syscfg.Cfg) { if errText := cfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } util.StatusMessage(util.VERBOSITY_DEFAULT, "Syscfg for %s:\n", targetName) pkgNameEntryMap := syscfg.EntriesByPkg(cfg) pkgNames := make([]string, 0, len(pkgNameEntryMap)) for pkgName, _ := range pkgNameEntryMap { pkgNames = append(pkgNames, pkgName) } sort.Strings(pkgNames) for i, pkgName := range pkgNames { if i > 0 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } printPkgCfg(pkgName, cfg, pkgNameEntryMap[pkgName]) } } func printPkgBriefCfg(pkgName string, cfg syscfg.Cfg, entries []syscfg.CfgEntry) { util.StatusMessage(util.VERBOSITY_DEFAULT, "[%s]\n", pkgName) settingNames := make([]string, len(entries)) for i, entry := range entries { settingNames[i] = entry.Name } sort.Strings(settingNames) for _, name := range settingNames { printBriefSetting(cfg.Settings[name]) } } func printBriefCfg(targetName string, cfg syscfg.Cfg) { if errText := cfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } util.StatusMessage(util.VERBOSITY_DEFAULT, "Brief syscfg for %s:\n", targetName) pkgNameEntryMap := syscfg.EntriesByPkg(cfg) pkgNames := make([]string, 0, len(pkgNameEntryMap)) for pkgName, _ := range pkgNameEntryMap { pkgNames = append(pkgNames, pkgName) } sort.Strings(pkgNames) for i, pkgName := range pkgNames { if i > 0 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } printPkgBriefCfg(pkgName, cfg, pkgNameEntryMap[pkgName]) } } func printFlatCfg(targetName string, cfg syscfg.Cfg) { if errText := cfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } settings := cfg.SettingValues().ToMap() names := make([]string, 0, len(settings)) for name, _ := range settings { names = append(names, name) } sort.Strings(names) for _, name := range names { util.StatusMessage(util.VERBOSITY_DEFAULT, "%s: %s\n", name, settings[name]) } } func yamlPkgCfg(w io.Writer, pkgName string, cfg syscfg.Cfg, entries []syscfg.CfgEntry) { settingNames := make([]string, len(entries)) for i, entry := range entries { settingNames[i] = entry.Name } sort.Strings(settingNames) fmt.Fprintf(w, " ### %s\n", pkgName) for _, name := range settingNames { fmt.Fprintf(w, " %s: '%s'\n", name, cfg.Settings[name].Value) } } func yamlCfg(cfg syscfg.Cfg) string { if errText := cfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } pkgNameEntryMap := syscfg.EntriesByPkg(cfg) pkgNames := make([]string, 0, len(pkgNameEntryMap)) for pkgName, _ := range pkgNameEntryMap { pkgNames = append(pkgNames, pkgName) } sort.Strings(pkgNames) buf := bytes.Buffer{} fmt.Fprintf(&buf, "syscfg.vals:\n") for i, pkgName := range pkgNames { if i > 0 { fmt.Fprintf(&buf, "\n") } yamlPkgCfg(&buf, pkgName, cfg, pkgNameEntryMap[pkgName]) } return string(buf.Bytes()) } func targetBuilderConfigResolve(b *builder.TargetBuilder) *resolve.Resolution { res, err := b.Resolve() if err != nil { NewtUsage(nil, err) } warningText := strings.TrimSpace(res.WarningText()) if warningText != "" { log.Warn(warningText + "\n") } return res } func targetConfigShowCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printCfg(b.GetTarget().Name(), res.Cfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func targetConfigBriefCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printBriefCfg(b.GetTarget().Name(), res.Cfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func targetConfigFlatCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printFlatCfg(b.GetTarget().Name(), res.Cfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func valSettingString(vs val.ValSetting) string { intVal, _ := vs.IntVal() s := fmt.Sprintf("%d", intVal) if vs.RefName != "" { s += fmt.Sprintf("%*s [%s]", 16-len(s), "", vs.RefName) } return s } func logLevelString(ls val.ValSetting) string { intVal, _ := ls.IntVal() s := fmt.Sprintf("%d (%s)", intVal, logcfg.LogLevelString(intVal)) if ls.RefName != "" { s += fmt.Sprintf("%*s [%s]", 16-len(s), "", ls.RefName) } return s } func printLogCfgOne(l logcfg.Log) { util.StatusMessage(util.VERBOSITY_DEFAULT, "%s:\n", l.Name) util.StatusMessage(util.VERBOSITY_DEFAULT, " Package: %s\n", l.Source.FullName()) util.StatusMessage(util.VERBOSITY_DEFAULT, " Module: %s\n", valSettingString(l.Module)) util.StatusMessage(util.VERBOSITY_DEFAULT, " Level: %s\n", logLevelString(l.Level)) } func printLogCfg(targetName string, lcfg logcfg.LCfg) { if errText := lcfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } util.StatusMessage(util.VERBOSITY_DEFAULT, "Log config for %s:\n", targetName) logNames := make([]string, 0, len(lcfg.Logs)) for name, _ := range lcfg.Logs { logNames = append(logNames, name) } sort.Strings(logNames) for i, logName := range logNames { if i > 0 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } printLogCfgOne(lcfg.Logs[logName]) } } func targetLogShowCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printLogCfg(b.GetTarget().Name(), res.LCfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func printLogCfgBriefOne(l logcfg.Log, colWidth int) { intMod, _ := l.Module.IntVal() intLevel, _ := l.Level.IntVal() levelStr := fmt.Sprintf("%d (%s)", intLevel, logcfg.LogLevelString(intLevel)) util.StatusMessage(util.VERBOSITY_DEFAULT, "%*s | %-8d | %-12s\n", colWidth, l.Name, intMod, levelStr) } func printLogCfgBrief(targetName string, lcfg logcfg.LCfg) { if errText := lcfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } util.StatusMessage(util.VERBOSITY_DEFAULT, "Brief log config for %s:\n", targetName) modules := make([]int, 0, len(lcfg.Logs)) modMap := make(map[int]logcfg.Log, len(lcfg.Logs)) // Keep track of the longest log name. This allows the output to be // properly aligned. longest := 6 // Map each module to its log, and build a sorted slice of module IDs. for name, log := range lcfg.Logs { modInt, _ := log.Module.IntVal() modules = append(modules, modInt) modMap[modInt] = log if len(name) > longest { longest = len(name) } } sort.Ints(modules) // Print logs, sorted by module ID. colWidth := longest + 4 util.StatusMessage(util.VERBOSITY_DEFAULT, "%*s | MODULE | LEVEL\n", colWidth, "LOG") util.StatusMessage(util.VERBOSITY_DEFAULT, "%s-+----------+--------------\n", strings.Repeat("-", colWidth)) for _, module := range modules { printLogCfgBriefOne(modMap[module], colWidth) } } func targetLogBriefCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printLogCfgBrief(b.GetTarget().Name(), res.LCfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func printStage(sf stage.StageFunc) { util.StatusMessage(util.VERBOSITY_DEFAULT, "%s:\n", sf.Name) util.StatusMessage(util.VERBOSITY_DEFAULT, " Package: %s\n", sf.Pkg.FullName()) if len(sf.Stage.Afters) > 0 || len(sf.Stage.Befores) > 0 { for _, s := range sf.Stage.Afters { util.StatusMessage(util.VERBOSITY_DEFAULT, " After: %s\n", s) } for _, s := range sf.Stage.Befores { util.StatusMessage(util.VERBOSITY_DEFAULT, " Before: %s\n", s) } } else { util.StatusMessage(util.VERBOSITY_DEFAULT, " Stage: %s\n", valSettingString(sf.Stage)) } } func printStageBriefOne(sf stage.StageFunc, stageWidth int, pkgWidth int, fnWidth int, settingWidth int) { util.StatusMessage(util.VERBOSITY_DEFAULT, " %-*s | %-*s | %-*s | %-*s\n", stageWidth, sf.Stage.Value, pkgWidth, sf.Pkg.FullName(), fnWidth, sf.Name, settingWidth, sf.Stage.RefName) } func printStageBriefTable(sfs []stage.StageFunc) { longestStage := 5 longestPkg := 7 longestFn := 8 longestSetting := 7 for _, sf := range sfs { if len(sf.Stage.Value) > longestStage { longestStage = len(sf.Stage.Value) } if len(sf.Pkg.FullName()) > longestPkg { longestPkg = len(sf.Pkg.FullName()) } if len(sf.Name) > longestFn { longestFn = len(sf.Name) } if len(sf.Stage.RefName) > longestSetting { longestSetting = len(sf.Stage.RefName) } } stageWidth := longestStage + 2 pkgWidth := longestPkg + 2 fnWidth := longestFn + 2 settingWidth := longestSetting + 2 util.StatusMessage(util.VERBOSITY_DEFAULT, " %-*s | %-*s | %-*s | %-*s\n", stageWidth, "STAGE", pkgWidth, "PACKAGE", fnWidth, "FUNCTION", settingWidth, "SETTING") util.StatusMessage(util.VERBOSITY_DEFAULT, "-%s-+-%s-+-%s-+-%s-\n", strings.Repeat("-", stageWidth), strings.Repeat("-", pkgWidth), strings.Repeat("-", fnWidth), strings.Repeat("-", settingWidth)) for _, sf := range sfs { printStageBriefOne(sf, stageWidth, pkgWidth, fnWidth, settingWidth) } } func printSysinitCfg(targetName string, scfg sysinit.SysinitCfg) { util.StatusMessage(util.VERBOSITY_DEFAULT, "Sysinit config for %s:\n", targetName) if errText := scfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } for i, sf := range scfg.StageFuncs { if i > 0 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } printStage(sf) } } func printSysinitBrief(targetName string, scfg sysinit.SysinitCfg) { if errText := scfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } util.StatusMessage(util.VERBOSITY_DEFAULT, "Brief sysinit config for %s:\n", targetName) printStageBriefTable(scfg.StageFuncs) } func printSysinitGraphviz(targetName string, scfg sysinit.SysinitCfg) { if errText := scfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } fmt.Printf("digraph sysinit {\n") for _, sf := range scfg.StageFuncs { if len(sf.Stage.Afters) == 0 && len(sf.Stage.Befores) == 0 { stage, _ := sf.Stage.IntVal() fmt.Printf(" %s [label=\"%s (%d)\"];\n", sf.Name, sf.Name, stage) } for _, depSf := range sf.DepsI { fmt.Printf(" %s -> %s;\n", sf.Name, depSf.Name) } for _, depStr := range sf.Stage.Afters { fmt.Printf(" %s -> %s [label=\"$after:%s\"];\n", depStr, sf.Name, depStr) } for _, depStr := range sf.Stage.Befores { fmt.Printf(" %s -> %s [label=\"$before:%s\"];\n", sf.Name, depStr, depStr) } } fmt.Printf("}\n") } func targetSysinitShowCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printSysinitCfg(b.GetTarget().Name(), res.SysinitCfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func targetSysinitBriefCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printSysinitBrief(b.GetTarget().Name(), res.SysinitCfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func targetSysinitGraphvizCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printSysinitGraphviz(b.GetTarget().Name(), res.SysinitCfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func printSysdownCfg(targetName string, scfg sysdown.SysdownCfg) { util.StatusMessage(util.VERBOSITY_DEFAULT, "Sysdown config for %s:\n", targetName) if errText := scfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } for i, sf := range scfg.StageFuncs { if i > 0 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } printStage(sf) } } func targetSysdownShowCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printSysdownCfg(b.GetTarget().Name(), res.SysdownCfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func printSysdownBrief(targetName string, scfg sysdown.SysdownCfg) { if errText := scfg.ErrorText(); errText != "" { util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText) } util.StatusMessage(util.VERBOSITY_DEFAULT, "Brief sysdown config for %s:\n", targetName) printStageBriefTable(scfg.StageFuncs) } func targetSysdownBriefCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for i, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } res := targetBuilderConfigResolve(b) printSysdownBrief(b.GetTarget().Name(), res.SysdownCfg) if i < len(args)-1 { util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") } } } func targetConfigInitCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } type entry struct { lpkg *pkg.LocalPackage path string b *builder.TargetBuilder exists bool } TryGetProject() anyExist := false entries := make([]entry, len(args)) for i, pkgName := range args { e := &entries[i] b, err := TargetBuilderForTargetOrUnittest(pkgName) if err != nil { NewtUsage(cmd, err) } e.b = b e.lpkg = b.GetTestPkg() if e.lpkg == nil { e.lpkg = b.GetTarget().Package() } e.path = builder.PkgSyscfgPath(e.lpkg.BasePath()) if util.NodeExist(e.path) { e.exists = true anyExist = true } } if anyExist && !newtutil.NewtForce { util.StatusMessage(util.VERBOSITY_DEFAULT, "Configuration files already exist:\n") for _, e := range entries { if e.exists { util.StatusMessage(util.VERBOSITY_DEFAULT, " * %s\n", e.path) } } util.StatusMessage(util.VERBOSITY_DEFAULT, "\n") fmt.Printf("Overwrite them? (y/N): ") rsp := PromptYesNo(false) if !rsp { return } } for _, e := range entries { res := targetBuilderConfigResolve(e.b) yaml := yamlCfg(res.Cfg) if err := ioutil.WriteFile(e.path, []byte(yaml), 0644); err != nil { NewtUsage(nil, util.FmtNewtError("Error writing file \"%s\"; %s", e.path, err.Error())) } } } func targetDumpCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { NewtUsage(cmd, util.NewNewtError("Must specify target or unittest name")) } TryGetProject() for _, arg := range args { b, err := TargetBuilderForTargetOrUnittest(arg) if err != nil { NewtUsage(cmd, err) } rpt, err := dump.NewReport(b) if err != nil { NewtUsage(nil, err) } s, err := rpt.JSON() if err != nil { NewtUsage(nil, err) } util.StatusMessage(util.VERBOSITY_DEFAULT, s+"\n") } } func targetCfgCmdAll() []*cobra.Command { cmds := []*cobra.Command{} configHelpText := "View or populate a target's system configuration" configCmd := &cobra.Command{ Use: "config", Short: configHelpText, Long: configHelpText, Run: func(cmd *cobra.Command, args []string) { cmd.Usage() }, } cmds = append(cmds, configCmd) configShowCmd := &cobra.Command{ Use: "show <target> [target...]", Short: "View a target's system configuration", Long: "View a target's system configuration", Run: targetConfigShowCmd, } configShowCmd.Flags().StringVarP(&util.InjectSyscfg, "syscfg", "S", "", "Injected syscfg settings, key=value pairs separated by colon") configCmd.AddCommand(configShowCmd) AddTabCompleteFn(configShowCmd, func() []string { return append(targetList(), unittestList()...) }) configBriefCmd := &cobra.Command{ Use: "brief <target> [target...]", Short: "View a summary of target's system configuration", Long: "View a summary of target's system configuration", Run: targetConfigBriefCmd, } configBriefCmd.Flags().StringVarP(&util.InjectSyscfg, "syscfg", "S", "", "Injected syscfg settings, key=value pairs separated by colon") configCmd.AddCommand(configBriefCmd) AddTabCompleteFn(configBriefCmd, func() []string { return append(targetList(), unittestList()...) }) configFlatCmd := &cobra.Command{ Use: "flat <target> [target...]", Short: "View a flat table of target's system configuration", Long: "View a flat table of target's system configuration", Run: targetConfigFlatCmd, } configFlatCmd.Flags().StringVarP(&util.InjectSyscfg, "syscfg", "S", "", "Injected syscfg settings, key=value pairs separated by colon") configCmd.AddCommand(configFlatCmd) AddTabCompleteFn(configFlatCmd, func() []string { return append(targetList(), unittestList()...) }) configInitCmd := &cobra.Command{ Use: "init", Short: "Populate a target's system configuration file", Long: "Populate a target's system configuration file (syscfg). " + "Unspecified settings are given default values.", Run: targetConfigInitCmd, } configInitCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce, "force", "f", false, "Force overwrite of target configuration") configCmd.AddCommand(configInitCmd) AddTabCompleteFn(configInitCmd, func() []string { return append(targetList(), unittestList()...) }) logHelpText := "View a target's log configuration" logCmd := &cobra.Command{ Use: "logcfg", Short: logHelpText, Long: logHelpText, Run: func(cmd *cobra.Command, args []string) { cmd.Usage() }, } cmds = append(cmds, logCmd) logShowCmd := &cobra.Command{ Use: "show <target> [target...]", Short: "View a target's log configuration", Long: "View a target's log configuration", Run: targetLogShowCmd, } logCmd.AddCommand(logShowCmd) AddTabCompleteFn(logShowCmd, func() []string { return append(targetList(), unittestList()...) }) logBriefCmd := &cobra.Command{ Use: "brief <target> [target...]", Short: "View a summary of target's log configuration", Long: "View a summary of target's log configuration", Run: targetLogBriefCmd, } logCmd.AddCommand(logBriefCmd) AddTabCompleteFn(logBriefCmd, func() []string { return append(targetList(), unittestList()...) }) sysinitHelpText := "View a target's sysinit configuration" sysinitCmd := &cobra.Command{ Use: "sysinit", Short: sysinitHelpText, Long: sysinitHelpText, Run: func(cmd *cobra.Command, args []string) { cmd.Usage() }, } cmds = append(cmds, sysinitCmd) sysinitShowCmd := &cobra.Command{ Use: "show <target> [target...]", Short: "View a target's sysinit configuration", Long: "View a target's sysinit configuration", Run: targetSysinitShowCmd, } sysinitCmd.AddCommand(sysinitShowCmd) AddTabCompleteFn(sysinitShowCmd, func() []string { return append(targetList(), unittestList()...) }) sysinitBriefCmd := &cobra.Command{ Use: "brief <target> [target...]", Short: "View a summary of target's sysinit configuration", Long: "View a summary of target's sysinit configuration", Run: targetSysinitBriefCmd, } sysinitCmd.AddCommand(sysinitBriefCmd) AddTabCompleteFn(sysinitBriefCmd, func() []string { return append(targetList(), unittestList()...) }) sysinitGraphvizCmd := &cobra.Command{ Use: "graphviz <target> [target...]", Short: "Print a graph representation of target's sysinit configuration (DOT format)", Long: "Print a graph representation of target's sysinit configuration (DOT format)", Run: targetSysinitGraphvizCmd, } sysinitCmd.AddCommand(sysinitGraphvizCmd) AddTabCompleteFn(sysinitGraphvizCmd, func() []string { return append(targetList(), unittestList()...) }) sysdownHelpText := "View a target's sysdown configuration" sysdownCmd := &cobra.Command{ Use: "sysdown", Short: sysdownHelpText, Long: sysdownHelpText, Run: func(cmd *cobra.Command, args []string) { cmd.Usage() }, } cmds = append(cmds, sysdownCmd) sysdownShowCmd := &cobra.Command{ Use: "show <target> [target...]", Short: "View a target's sysdown configuration", Long: "View a target's sysdown configuration", Run: targetSysdownShowCmd, } sysdownCmd.AddCommand(sysdownShowCmd) AddTabCompleteFn(sysdownShowCmd, func() []string { return append(targetList(), unittestList()...) }) sysdownBriefCmd := &cobra.Command{ Use: "brief <target> [target...]", Short: "View a summary of target's sysdown configuration", Long: "View a summary of target's sysdown configuration", Run: targetSysdownBriefCmd, } sysdownCmd.AddCommand(sysdownBriefCmd) AddTabCompleteFn(sysdownBriefCmd, func() []string { return append(targetList(), unittestList()...) }) dumpCmd := &cobra.Command{ Use: "dump <target> [target...]", Short: "Dump a target's intermediate form in JSON", Run: targetDumpCmd, } cmds = append(cmds, dumpCmd) AddTabCompleteFn(dumpCmd, func() []string { return append(targetList(), unittestList()...) }) return cmds }