blob: 20206e33dd1a912a8467e3aa5d24da89237fa2b9 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The following enables go generate to generate the doc.go file.
//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .
package main
import (
"strings"
"v.io/jiri"
"v.io/jiri/profiles/profilescmdline"
"v.io/jiri/profiles/profilesreader"
"v.io/jiri/tool"
"v.io/x/lib/cmdline"
)
func main() {
cmdline.Main(cmdRoot)
}
var (
interfacesFlag string
progressFlag bool
gofmtFlag bool
diffOnlyFlag bool
useContextFlag bool
removeCallFlag string
injectCallFlag string
injectCallImportFlag string
mergePoliciesFlag profilesreader.MergePolicies
)
const (
apilogCall = "LogCall"
apilogImport = "v.io/x/ref/lib/apilog"
apilogRemoveCall = "apilog.LogCall"
)
func init() {
cmdCheck.Flags.StringVar(&interfacesFlag, "interface", "", "Comma-separated list of interface packages (required).")
cmdCheck.Flags.StringVar(&injectCallFlag, "call", apilogCall, "The function call to be checked for as defer <pkg>.<call>()() and defer <pkg>.<call>f(...)(...). The value of <pkg> is determined from --import.")
cmdCheck.Flags.StringVar(&injectCallImportFlag, "import", apilogImport, "Import path for the injected call.")
cmdInject.Flags.StringVar(&interfacesFlag, "interface", "", "Comma-separated list of interface packages (required).")
cmdInject.Flags.BoolVar(&gofmtFlag, "gofmt", true, "Automatically run gofmt on the modified files.")
cmdInject.Flags.BoolVar(&diffOnlyFlag, "diff-only", false, "Show changes that would be made without actually making them.")
cmdInject.Flags.StringVar(&injectCallFlag, "call", apilogCall, "The function call to be injected as defer <pkg>.<call>()() and defer <pkg>.<call>f(...)(...). The value of <pkg> is determined from --import.")
cmdInject.Flags.StringVar(&injectCallImportFlag, "import", apilogImport, "Import path for the injected call.")
cmdRemove.Flags.BoolVar(&gofmtFlag, "gofmt", true, "Automatically run gofmt on the modified files.")
cmdRemove.Flags.BoolVar(&diffOnlyFlag, "diff-only", false, "Show changes that would be made without actually making them.")
cmdRemove.Flags.StringVar(&removeCallFlag, "call", apilogRemoveCall, "The function call to be removed. Note, that the package selector must be included. No attempt is made to remove the import declaration if the package is no longer used as a result of the removal.")
cmdRoot.Flags.BoolVar(&progressFlag, "progress", false, "Print verbose progress information.")
cmdRoot.Flags.BoolVar(&useContextFlag, "use-v23-context", true, "Pass a context.T argument (which must be of type v.io/v23/context.T), if available, to the injected call as its first parameter.")
mergePoliciesFlag = profilesreader.JiriMergePolicies()
profilescmdline.RegisterMergePoliciesFlag(&cmdRoot.Flags, &mergePoliciesFlag)
tool.InitializeRunFlags(&cmdRoot.Flags)
}
var cmdRoot = &cmdline.Command{
Name: "gologcop",
Short: "Tool for checking and injecting log statements in code",
Long: `
Command gologcop checks for and injects logging statements into Go source code.
When checking, it ensures that all implementations in <packages> of all exported
interfaces declared in packages passed to the -interface flag have an
appropriate logging construct.
When injecting or removing, it modifies the source code to inject or remove
such logging constructs.
LIMITATIONS:
Removal will not automatically remove the package import for the call to
be removed.
`,
Children: []*cmdline.Command{cmdCheck, cmdInject, cmdRemove},
}
// cmdCheck represents the 'check' command of the gologcop tool.
var cmdCheck = &cmdline.Command{
Runner: jiri.RunnerFunc(runCheck),
Name: "check",
Short: "Check for log statements in public API implementations",
Long: "Check for log statements in public API implementations.",
ArgsName: "<packages>",
ArgsLong: "<packages> is the list of packages to be checked.",
}
// splitCommaSeparatedValues splits a comma-separated string
// containing a list of components to a slice of strings.
// It also cleans the whitespaces in each component and
// ignores empty components, so that "x, y,z," would be
// parsed to ["x", "y", "z"].
func splitCommaSeparatedValues(s string) []string {
result := []string{}
for _, v := range strings.Split(s, ",") {
trimmed := strings.TrimSpace(v)
if len(trimmed) > 0 {
result = append(result, trimmed)
}
}
return result
}
// runCheck handles the "check" command and executes
// the log injector in check-only mode.
func runCheck(jirix *jiri.X, args []string) error {
interfacePackageList := splitCommaSeparatedValues(interfacesFlag)
implementationPackageList := args
if len(interfacePackageList) == 0 {
return jirix.UsageErrorf("no interface packages listed")
}
if len(implementationPackageList) == 0 {
return jirix.UsageErrorf("no implementation package listed")
}
return runInjector(jirix, nil, interfacePackageList, implementationPackageList, true)
}
// cmdInject represents the 'inject' command of the gologcop tool.
var cmdInject = &cmdline.Command{
Runner: jiri.RunnerFunc(runInject),
Name: "inject",
Short: "Inject log statements in public API implementations",
Long: `Inject log statements in public API implementations.
Note that inject modifies <packages> in-place. It is a good idea
to commit changes to version control before running this tool so
you can see the diff or revert the changes.
`,
ArgsName: "<packages>",
ArgsLong: "<packages> is the list of packages to inject log statements in.",
}
// runInject handles the "inject" command and executes
// the log injector in injection mode.
func runInject(jirix *jiri.X, args []string) error {
return runInjector(jirix, nil, splitCommaSeparatedValues(interfacesFlag), args, false)
}
// cmdRemove represents the 'remove' command of the gologcop tool.
var cmdRemove = &cmdline.Command{
Runner: jiri.RunnerFunc(runRemove),
Name: "remove",
Short: "Remove log statements",
Long: `Remove log statements.
Note that remove modifies <packages> in-place. It is a good idea
to commit changes to version control before running this tool so
you can see the diff or revert the changes.
`,
ArgsName: "<packages>",
ArgsLong: "<packages> is the list of packages to remove log statements from.",
}
// runRemove handles the "remove" command.
func runRemove(jirix *jiri.X, args []string) error {
return runRemover(jirix, nil, args)
}