mirror of
https://github.com/golang/go
synced 2024-11-18 23:24:39 -07:00
go/package/gopackages: update gopackages to use the new tool library for its main function
Change-Id: I06f13024c021d14e4a759ca9ec24aa54f9d1b97f Reviewed-on: https://go-review.googlesource.com/c/154558 Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
e063def13b
commit
7cb465e007
@ -9,116 +9,73 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/types"
|
"go/types"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"runtime/pprof"
|
|
||||||
"runtime/trace"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
|
"golang.org/x/tools/internal/tool"
|
||||||
)
|
)
|
||||||
|
|
||||||
// flags
|
func main() {
|
||||||
var (
|
tool.Main(context.Background(), &application{Mode: "imports"}, os.Args[1:])
|
||||||
depsFlag = flag.Bool("deps", false, "show dependencies too")
|
|
||||||
testFlag = flag.Bool("test", false, "include any tests implied by the patterns")
|
|
||||||
mode = flag.String("mode", "imports", "mode (one of files, imports, types, syntax, allsyntax)")
|
|
||||||
private = flag.Bool("private", false, "show non-exported declarations too")
|
|
||||||
printJSON = flag.Bool("json", false, "print package in JSON form")
|
|
||||||
|
|
||||||
cpuprofile = flag.String("cpuprofile", "", "write CPU profile to this file")
|
|
||||||
memprofile = flag.String("memprofile", "", "write memory profile to this file")
|
|
||||||
traceFlag = flag.String("trace", "", "write trace log to this file")
|
|
||||||
|
|
||||||
buildFlags stringListValue
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Var(&buildFlags, "buildflag", "pass argument to underlying build system (may be repeated)")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func usage() {
|
type application struct {
|
||||||
fmt.Fprintln(os.Stderr, `Usage: gopackages [-deps] [-cgo] [-mode=...] [-private] package...
|
// Embed the basic profiling flags supported by the tool package
|
||||||
|
tool.Profile
|
||||||
|
|
||||||
The gopackages command loads, parses, type-checks,
|
Deps bool `flag:"deps" help:"show dependencies too"`
|
||||||
and prints one or more Go packages.
|
Test bool `flag:"test" help:"include any tests implied by the patterns"`
|
||||||
|
Mode string `flag:"mode" help:"mode (one of files, imports, types, syntax, allsyntax)"`
|
||||||
|
Private bool `flag:"private" help:"show non-exported declarations too"`
|
||||||
|
PrintJSON bool `flag:"json" help:"print package in JSON form"`
|
||||||
|
BuildFlags stringListValue `flag:"buildflag" help:"pass argument to underlying build system (may be repeated)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements tool.Application returning the binary name.
|
||||||
|
func (app *application) Name() string { return "gopackages" }
|
||||||
|
|
||||||
|
// Usage implements tool.Application returning empty extra argument usage.
|
||||||
|
func (app *application) Usage() string { return "package..." }
|
||||||
|
|
||||||
|
// ShortHelp implements tool.Application returning the main binary help.
|
||||||
|
func (app *application) ShortHelp() string {
|
||||||
|
return "gopackages loads, parses, type-checks, and prints one or more Go packages."
|
||||||
|
}
|
||||||
|
|
||||||
|
// DetailedHelp implements tool.Application returning the main binary help.
|
||||||
|
func (app *application) DetailedHelp(f *flag.FlagSet) {
|
||||||
|
fmt.Fprint(f.Output(), `
|
||||||
Packages are specified using the notation of "go list",
|
Packages are specified using the notation of "go list",
|
||||||
or other underlying build system.
|
or other underlying build system.
|
||||||
|
|
||||||
Flags:`)
|
Flags:
|
||||||
flag.PrintDefaults()
|
`)
|
||||||
|
f.PrintDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
// Run takes the args after flag processing and performs the specified query.
|
||||||
log.SetPrefix("gopackages: ")
|
func (app *application) Run(ctx context.Context, args ...string) error {
|
||||||
log.SetFlags(0)
|
if len(args) == 0 {
|
||||||
flag.Usage = usage
|
return tool.CommandLineErrorf("not enough arguments")
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if len(flag.Args()) == 0 {
|
|
||||||
usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if *cpuprofile != "" {
|
|
||||||
f, err := os.Create(*cpuprofile)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := pprof.StartCPUProfile(f); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// NB: profile won't be written in case of error.
|
|
||||||
defer pprof.StopCPUProfile()
|
|
||||||
}
|
|
||||||
|
|
||||||
if *traceFlag != "" {
|
|
||||||
f, err := os.Create(*traceFlag)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := trace.Start(f); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// NB: trace log won't be written in case of error.
|
|
||||||
defer func() {
|
|
||||||
trace.Stop()
|
|
||||||
log.Printf("To view the trace, run:\n$ go tool trace view %s", *traceFlag)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if *memprofile != "" {
|
|
||||||
f, err := os.Create(*memprofile)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
// NB: memprofile won't be written in case of error.
|
|
||||||
defer func() {
|
|
||||||
runtime.GC() // get up-to-date statistics
|
|
||||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
|
||||||
log.Fatalf("Writing memory profile: %v", err)
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load, parse, and type-check the packages named on the command line.
|
// Load, parse, and type-check the packages named on the command line.
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: packages.LoadSyntax,
|
Mode: packages.LoadSyntax,
|
||||||
Tests: *testFlag,
|
Tests: app.Test,
|
||||||
BuildFlags: buildFlags,
|
BuildFlags: app.BuildFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
// -mode flag
|
// -mode flag
|
||||||
switch strings.ToLower(*mode) {
|
switch strings.ToLower(app.Mode) {
|
||||||
case "files":
|
case "files":
|
||||||
cfg.Mode = packages.LoadFiles
|
cfg.Mode = packages.LoadFiles
|
||||||
case "imports":
|
case "imports":
|
||||||
@ -130,16 +87,16 @@ func main() {
|
|||||||
case "allsyntax":
|
case "allsyntax":
|
||||||
cfg.Mode = packages.LoadAllSyntax
|
cfg.Mode = packages.LoadAllSyntax
|
||||||
default:
|
default:
|
||||||
log.Fatalf("invalid mode: %s", *mode)
|
return tool.CommandLineErrorf("invalid mode: %s", app.Mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
lpkgs, err := packages.Load(cfg, flag.Args()...)
|
lpkgs, err := packages.Load(cfg, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// -deps: print dependencies too.
|
// -deps: print dependencies too.
|
||||||
if *depsFlag {
|
if app.Deps {
|
||||||
// We can't use packages.All because
|
// We can't use packages.All because
|
||||||
// we need an ordered traversal.
|
// we need an ordered traversal.
|
||||||
var all []*packages.Package // postorder
|
var all []*packages.Package // postorder
|
||||||
@ -169,12 +126,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, lpkg := range lpkgs {
|
for _, lpkg := range lpkgs {
|
||||||
print(lpkg)
|
app.print(lpkg)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func print(lpkg *packages.Package) {
|
func (app *application) print(lpkg *packages.Package) {
|
||||||
if *printJSON {
|
if app.PrintJSON {
|
||||||
data, _ := json.MarshalIndent(lpkg, "", "\t")
|
data, _ := json.MarshalIndent(lpkg, "", "\t")
|
||||||
os.Stdout.Write(data)
|
os.Stdout.Write(data)
|
||||||
return
|
return
|
||||||
@ -237,14 +195,14 @@ func print(lpkg *packages.Package) {
|
|||||||
scope := lpkg.Types.Scope()
|
scope := lpkg.Types.Scope()
|
||||||
for _, name := range scope.Names() {
|
for _, name := range scope.Names() {
|
||||||
obj := scope.Lookup(name)
|
obj := scope.Lookup(name)
|
||||||
if !obj.Exported() && !*private {
|
if !obj.Exported() && !app.Private {
|
||||||
continue // skip unexported names
|
continue // skip unexported names
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("\t%s\n", types.ObjectString(obj, qual))
|
fmt.Printf("\t%s\n", types.ObjectString(obj, qual))
|
||||||
if _, ok := obj.(*types.TypeName); ok {
|
if _, ok := obj.(*types.TypeName); ok {
|
||||||
for _, meth := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
|
for _, meth := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
|
||||||
if !meth.Obj().Exported() && !*private {
|
if !meth.Obj().Exported() && !app.Private {
|
||||||
continue // skip unexported names
|
continue // skip unexported names
|
||||||
}
|
}
|
||||||
fmt.Printf("\t%s\n", types.SelectionString(meth, qual))
|
fmt.Printf("\t%s\n", types.SelectionString(meth, qual))
|
||||||
|
Loading…
Reference in New Issue
Block a user