//Import is for importing command line arguments. //It uses the following rules: // If args is len 0, try to import the current directory. // Otherwise, for each argument: // If it ends with ..., use goutil.ImportTree (unless notree is true) // Otherwise, use goutil.Import //Regardless, the ctx is passed as is to the various importers. // //Import returns a list of any errors that resulted from attmepting to import. //If you only care about the first error, wrap the call in FirstError. func Import(notree bool, ctx *build.Context, args []string) (pkgs []goutil.Packages, errs []error) { push := func(ps goutil.Packages, err error) { if len(ps) > 0 { pkgs = append(pkgs, ps) } if err != nil { errs = append(errs, err) } } if len(args) == 0 { push(imports(ctx, "")) return } for _, arg := range args { if filepath.Base(arg) == "..." { if notree { push(nil, errors.New("cannot use ... imports")) } else { push(goutil.ImportTree(ctx, filepath.Dir(arg))) } } else { push(imports(ctx, arg)) } } return }
//Import finds all the repo roots of all the dependencies of every //package in the root of path, excluding standard library. func Import(ctx *build.Context, path string) (*Root, []*Root, error) { pkg, err := goutil.Import(nil, path) if err != nil { return nil, nil, err } root, err := repoRoot(pkg) if err != nil { return nil, nil, err } tree := filepath.Join(pkg.Build.Root, "src", root.path) pkgs, err := goutil.ImportTree(ctx, tree) if err != nil { return nil, nil, err } var deps goutil.Packages for _, pkg := range pkgs { ps, err := pkg.ImportDeps() if err != nil { return nil, nil, err } deps = append(deps, ps...) } deps = deps.NoStdlib().Uniq() var roots []*Root seen := map[string]bool{root.path: true} for _, dep := range deps { root, err := repoRoot(dep) if err != nil { return nil, nil, err } if !seen[root.path] { seen[root.path] = true roots = append(roots, root) } } return root, roots, nil }
//Usage: %name %flags regexp [package|directory] func main() { log.SetFlags(0) fatal := log.Fatalln flag.Usage = Usage flag.Parse() args := flag.Args() if len(args) == 0 || len(args) > 2 { Usage() os.Exit(2) } re, err := regexp.Compile(args[0]) if err != nil { fatal(err) } if *l { re.Longest() } var m goutil.StringMatcher = re if *v { m = negmatcher{re} } tree := false imp := "." if len(args) > 1 { imp = args[1] if d, f := filepath.Split(imp); f == "..." { tree = true imp = d } } var pkgs goutil.Packages switch { case tree && *r: pkgs, err := goutil.ImportTree(nil, imp) if err != nil { log.Println(err) } var ps goutil.Packages for _, p := range pkgs { t, err := p.ImportDeps() if err != nil { fatal(err) } ps = append(ps, t...) } pkgs = append(pkgs, ps...).Uniq() case tree: pkgs, err = goutil.ImportTree(nil, imp) if err != nil { log.Println(err) } case *r: pkgs, err = goutil.ImportRec(nil, imp) if err != nil { fatal(err) } default: p, err := goutil.Import(nil, imp) if err != nil { fatal(err) } pkgs = goutil.Packages{p} } if *nostdlib { pkgs = pkgs.NoStdlib() } err = pkgs.Parse(false) if err != nil { fatal(err) } multiples := len(pkgs) > 1 for _, pkg := range pkgs { for _, d := range pkg.Decls().SplitSpecs().Named(m) { print(multiples, pkg, d) } } }