Exemple #1
0
// loadPackage is like loadImport but is used for command-line arguments,
// not for paths found in import statements.  In addition to ordinary import paths,
// loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
// in the Go command directory, as well as paths to those directories.
func loadPackage(arg string, stk *importStack) *Package {
	if build.IsLocalImport(arg) {
		dir := arg
		if !filepath.IsAbs(dir) {
			if abs, err := filepath.Abs(dir); err == nil {
				// interpret relative to current directory
				dir = abs
			}
		}
		if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") {
			arg = sub
		}
	}
	if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") {
		if p := cmdCache[arg]; p != nil {
			return p
		}
		stk.push(arg)
		defer stk.pop()

		bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0)
		bp.ImportPath = arg
		bp.Goroot = true
		bp.BinDir = gorootBin
		if gobin != "" {
			bp.BinDir = gobin
		}
		bp.Root = goroot
		bp.SrcRoot = gorootSrc
		p := new(Package)
		cmdCache[arg] = p
		p.load(stk, bp, err)
		if p.Error == nil && p.Name != "main" {
			p.Error = &PackageError{
				ImportStack: stk.copy(),
				Err:         fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir),
			}
		}
		return p
	}

	// Wasn't a command; must be a package.
	// If it is a local import path but names a standard package,
	// we treat it as if the user specified the standard package.
	// This lets you run go test ./ioutil in package io and be
	// referring to io/ioutil rather than a hypothetical import of
	// "./ioutil".
	if build.IsLocalImport(arg) {
		bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
		if bp.ImportPath != "" && bp.ImportPath != "." {
			arg = bp.ImportPath
		}
	}

	return loadImport(arg, cwd, stk, nil)
}
Exemple #2
0
func (i *Instrumentable) instrumentPatchable(outdir, relpath string, pkg *patch.PatchablePkg, f func(file *patch.PatchableFile) patch.Patches) error {
	path := ""
	if build.IsLocalImport(relpath) {
		path = filepath.Join("locals", relpath)
		path = strings.Replace(path, "..", "__", -1)
	} else if relpath != "" {
		path = filepath.Join("gopath", i.pkg.ImportPath)
	}
	if err := os.MkdirAll(filepath.Join(outdir, path), 0755); err != nil {
		return err
	}
	for filename, file := range pkg.Files {
		if outfile, err := os.Create(filepath.Join(outdir, path, filepath.Base(filename))); err != nil {
			return err
		} else {
			patches := f(file)
			// TODO(elazar): check the relative path from current location (aka relpath, path), to the import path
			// (aka v)
			for _, imp := range file.File.Imports {
				switch v := imp.Path.Value[1 : len(imp.Path.Value)-1]; {
				case v == i.pkg.ImportPath:
					patches = appendNoContradict(patches, patch.Replace(imp.Path, `"."`))
				case !i.relevantImport(v):
					continue
				case build.IsLocalImport(v):
					rel, err := filepath.Rel(path, filepath.Join("locals", v))
					if err != nil {
						return err
					}
					patches = appendNoContradict(patches, patch.Replace(imp.Path, `"./`+rel+`"`))
				default:
					if v == i.name {
						v = ""
					} else {
						v = filepath.Join("gopath", v)
					}
					rel, err := filepath.Rel(path, v)
					if err != nil {
						return err
					}
					patches = appendNoContradict(patches, patch.Replace(imp.Path, `"./`+rel+`"`))
				}
			}
			file.FprintPatched(outfile, file.File, patches)
			if err := outfile.Close(); err != nil {
				return err
			}
		}
	}
	return nil
}
Exemple #3
0
// Import imports a gc-generated package given its import path, adds the
// corresponding package object to the packages map, and returns the object.
// Local import paths are interpreted relative to the current working directory.
// The packages map must contain all packages already imported.
//
func Import(packages map[string]*types.Package, path string) (pkg *types.Package, err error) {
	// package "unsafe" is handled by the type checker
	if path == "unsafe" {
		panic(`gcimporter.Import called for package "unsafe"`)
	}

	srcDir := "."
	if build.IsLocalImport(path) {
		srcDir, err = os.Getwd()
		if err != nil {
			return
		}
	}

	filename, id := FindPkg(path, srcDir)
	if filename == "" {
		err = fmt.Errorf("can't find import: %s", id)
		return
	}

	// no need to re-import if the package was imported completely before
	if pkg = packages[id]; pkg != nil && pkg.Complete() {
		return
	}

	// open file
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer func() {
		f.Close()
		if err != nil {
			// add file name to error
			err = fmt.Errorf("reading export data: %s: %v", filename, err)
		}
	}()

	var hdr string
	buf := bufio.NewReader(f)
	if hdr, err = FindExportData(buf); err != nil {
		return
	}

	switch hdr {
	case "$$\n":
		return ImportData(packages, filename, id, buf)
	case "$$B\n":
		var data []byte
		data, err = ioutil.ReadAll(buf)
		if err == nil {
			_, pkg, err = BImportData(packages, data, path)
			return
		}
	default:
		err = fmt.Errorf("unknown export data header: %q", hdr)
	}

	return
}
Exemple #4
0
func (imp *Importer) importPkg(imports map[string]*types.Package, path string) (*types.Package, error) {
	if path == "unsafe" {
		return types.Unsafe, nil
	}

	var (
		srcDir string
		err    error
	)

	if build.IsLocalImport(path) {
		srcDir, err = os.Getwd()
		if err != nil {
			return nil, err
		}
	}

	bp, err := buildCtx.Import(path, srcDir, build.AllowBinary)
	if err != nil {
		return nil, err
	}

	if pkg := imports[path]; pkg != nil && pkg.Complete() {
		return pkg, nil
	}

	buf, err := loadExports(bp)
	if err != nil {
		return nil, err
	}
	_, pkg, err := importer.ImportData(imports, buf)
	return pkg, err
}
Exemple #5
0
func retrieveImport(importMap map[string]bool, path string, dir string) error {
	build.Default.SrcDirs()
	pkg, err := build.Import(path, dir, build.AllowBinary)
	if err != nil {
		if _, ok := err.(*build.NoGoError); ok {
			return nil
		} else {
			return err
		}
	}

	for _, path := range pkg.Imports {
		if isStandardImport(path) {
			continue
		}
		if importMap[path] {
			continue
		}

		if !build.IsLocalImport(path) {
			importMap[path] = true
		}

		err := retrieveImport(importMap, path, pkg.Dir)
		if err != nil {
			return err
		}
	}
	return nil
}
Exemple #6
0
// ImportPaths returns the import paths to use for the given command line.
func ImportPaths(args []string) ([]string, []error) {
	args = ImportPathsNoDotExpansion(args)
	var out []string
	var errs []error
	for _, a := range args {
		if strings.Contains(a, "...") {
			if build.IsLocalImport(a) {
				all, err := AllPackagesInFS(a)
				out = append(out, all...)
				if err != nil {
					errs = append(errs, err)
				}
			} else {
				all, err := AllPackages(a)
				out = append(out, all...)
				if err != nil {
					errs = append(errs, err)
				}
			}
			continue
		}
		out = append(out, a)
	}
	return out, errs
}
Exemple #7
0
func scanDirectory(path, srcDir string) (ret []string, err error) {
	pkg, err := build.Import(path, srcDir, build.AllowBinary)
	if err != nil {
		return ret, err
	}

	for _, imp := range pkg.Imports {
		switch {
		case isStandardImport(imp):
			// Ignore standard packages
		case !build.IsLocalImport(imp):
			// Add the external package
			ret = appendPkg(ret, imp)
			fallthrough
		default:
			// Does the recursive walk
			pkgs, err := scanDirectory(imp, pkg.Dir)
			if err != nil {
				return ret, err
			}
			ret = appendPkgs(ret, pkgs)
		}
	}

	return ret, err
}
Exemple #8
0
func localize(pkg string) string {
	if build.IsLocalImport(pkg) {
		// TODO(elazar): check if `import "./a/../a"` is equivalent to "./a"
		pkg := filepath.Clean(pkg)
		return filepath.Join(".", "locals", strings.Replace(pkg, ".", "_", -1))
	}
	return filepath.Join("gopath", pkg)
}
Exemple #9
0
// relevantImport will determine whether this import should be instrumented as well
func (i *Instrumentable) relevantImport(imp string) bool {
	if i.basepkg == "*" || build.IsLocalImport(imp) {
		return true
	} else if i.IsInGopath() || i.basepkg != "" {
		return filepath.HasPrefix(imp, i.basepkg) || filepath.HasPrefix(i.basepkg, imp)
	}
	return false
}
Exemple #10
0
// loadPackage recursively resolves path and its imports and if successful
// stores those packages in the Context's internal package cache.
func loadPackage(c *Context, stack []string, path string) (*Package, error) {
	if build.IsLocalImport(path) {
		// sanity check
		return nil, fmt.Errorf("%q is not a valid import path", path)
	}
	if pkg, ok := c.pkgs[path]; ok {
		// already loaded, just return
		return pkg, nil
	}

	push := func(path string) {
		stack = append(stack, path)
	}
	pop := func(path string) {
		stack = stack[:len(stack)-1]
	}
	onStack := func(path string) bool {
		for _, p := range stack {
			if p == path {
				return true
			}
		}
		return false
	}

	p, err := c.Context.Import(path, c.Projectdir(), 0)
	if err != nil {
		return nil, err
	}

	standard := p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".")
	push(path)
	var stale bool
	for _, i := range p.Imports {
		if c.shouldignore(i) {
			continue
		}
		if onStack(i) {
			push(i)
			return nil, fmt.Errorf("import cycle detected: %s", strings.Join(stack, " -> "))
		}
		pkg, err := loadPackage(c, stack, i)
		if err != nil {
			return nil, err
		}
		stale = stale || pkg.Stale
	}
	pop(path)

	pkg := Package{
		Context:  c,
		Package:  p,
		Standard: standard,
	}
	pkg.Stale = stale || isStale(&pkg)
	c.pkgs[path] = &pkg
	return &pkg, nil
}
Exemple #11
0
// loadPackage recursively resolves path and its imports and if successful
// stores those packages in the Context's internal package cache.
func (c *Context) loadPackage(stack []string, path string) (*Package, error) {
	if build.IsLocalImport(path) {
		// sanity check
		return nil, fmt.Errorf("%q is not a valid import path", path)
	}
	if pkg, ok := c.pkgs[path]; ok {
		// already loaded, just return
		return pkg, nil
	}

	push := func(path string) {
		stack = append(stack, path)
	}
	pop := func(path string) {
		stack = stack[:len(stack)-1]
	}
	onStack := func(path string) bool {
		for _, p := range stack {
			if p == path {
				return true
			}
		}
		return false
	}

	p, err := c.Context.Import(path, c.Projectdir(), 0)
	if err != nil {
		return nil, err
	}
	push(path)
	var stale bool
	for _, i := range p.Imports {
		if Stdlib[i] {
			continue
		}
		if onStack(i) {
			push(i)
			return nil, fmt.Errorf("import cycle detected: %s", strings.Join(stack, " -> "))
		}
		pkg, err := c.loadPackage(stack, i)
		if err != nil {
			return nil, err
		}
		stale = stale || pkg.Stale
	}
	pop(path)

	pkg := Package{
		Context: c,
		Package: p,
	}
	pkg.Stale = stale || isStale(&pkg)
	Debugf("loadPackage: %v %v (%v)", path, pkg.Stale, pkg.Dir)
	c.pkgs[path] = &pkg
	return &pkg, nil
}
Exemple #12
0
func main() {
	_ = go11tag
	flag.Usage = usage
	flag.Parse()
	log.SetFlags(0)

	args := flag.Args()
	if len(args) < 1 {
		usage()
	}

	if args[0] == "help" {
		help(args[1:])
		return
	}

	// Diagnose common mistake: GOPATH==GOROOT.
	// This setting is equivalent to not setting GOPATH at all,
	// which is not what most people want when they do it.
	if gopath := os.Getenv("GOPATH"); gopath == runtime.GOROOT() {
		fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
	} else {
		for _, p := range filepath.SplitList(gopath) {
			// Note: using HasPrefix instead of Contains because a ~ can appear
			// in the middle of directory elements, such as /tmp/git-1.8.2~rc3
			// or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
			if strings.HasPrefix(p, "~") {
				fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
				os.Exit(2)
			}
			if build.IsLocalImport(p) {
				fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nRun 'go help gopath' for usage.\n", p)
				os.Exit(2)
			}
		}
	}

	for _, cmd := range commands {
		if cmd.Name() == args[0] && cmd.Run != nil {
			cmd.Flag.Usage = func() { cmd.Usage() }
			if cmd.CustomFlags {
				args = args[1:]
			} else {
				cmd.Flag.Parse(args[1:])
				args = cmd.Flag.Args()
			}
			cmd.Run(cmd, args)
			exit()
			return
		}
	}

	fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0])
	setExitStatus(2)
	exit()
}
Exemple #13
0
func (i *Instrumentable) doimport(pkg string) (*Instrumentable, error) {
	if build.IsLocalImport(pkg) {
		return ImportDir(i.basepkg, filepath.Join(i.pkg.Dir, pkg))
	}
	// TODO: A bit hackish
	r, err := Import(i.basepkg, pkg)
	if err != nil {
		return r, err
	}
	r.name = i.name
	return r, nil
}
Exemple #14
0
// loadImport scans the directory named by path, which must be an import path,
// but possibly a local import path (an absolute file system path or one beginning
// with ./ or ../).  A local relative path is interpreted relative to srcDir.
// It returns a *Package describing the package found in that directory.
func loadImport(path string, srcDir string, stk *importStack, importPos []token.Position) *Package {
	stk.push(path)
	defer stk.pop()

	// Determine canonical identifier for this package.
	// For a local import the identifier is the pseudo-import path
	// we create from the full directory to the package.
	// Otherwise it is the usual import path.
	importPath := path
	isLocal := build.IsLocalImport(path)
	if isLocal {
		importPath = dirToImportPath(filepath.Join(srcDir, path))
	}
	if p := packageCache[importPath]; p != nil {
		if perr := disallowInternal(srcDir, p, stk); perr != p {
			return perr
		}
		return reusePackage(p, stk)
	}

	p := new(Package)
	p.local = isLocal
	p.ImportPath = importPath
	packageCache[importPath] = p

	// Load package.
	// Import always returns bp != nil, even if an error occurs,
	// in order to return partial information.
	//
	// TODO: After Go 1, decide when to pass build.AllowBinary here.
	// See issue 3268 for mistakes to avoid.
	bp, err := buildContext.Import(path, srcDir, build.ImportComment)
	bp.ImportPath = importPath
	if gobin != "" {
		bp.BinDir = gobin
	}
	if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path {
		err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
	}
	p.load(stk, bp, err)
	if p.Error != nil && len(importPos) > 0 {
		pos := importPos[0]
		pos.Filename = shortPath(pos.Filename)
		p.Error.Pos = pos.String()
	}

	if perr := disallowInternal(srcDir, p, stk); perr != p {
		return perr
	}

	return p
}
Exemple #15
0
func main() {
	flag.Usage = usage
	flag.Parse()
	log.SetFlags(0)

	args := flag.Args()
	if len(args) < 1 {
		usage()
	}

	if args[0] == "help" {
		help(args[1:])
		return
	}

	// Diagnose common mistake: GOPATH==GOROOT.
	// This setting is equivalent to not setting GOPATH at all,
	// which is not what most people want when they do it.
	if gopath := os.Getenv("GOPATH"); gopath == runtime.GOROOT() {
		fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
	} else {
		for _, p := range filepath.SplitList(gopath) {
			if strings.Contains(p, "~") && runtime.GOOS != "windows" {
				fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot contain shell metacharacter '~': %q\n", p)
				os.Exit(2)
			}
			if build.IsLocalImport(p) {
				fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nRun 'go help gopath' for usage.\n", p)
				os.Exit(2)
			}
		}
	}

	for _, cmd := range commands {
		if cmd.Name() == args[0] && cmd.Run != nil {
			cmd.Flag.Usage = func() { cmd.Usage() }
			if cmd.CustomFlags {
				args = args[1:]
			} else {
				cmd.Flag.Parse(args[1:])
				args = cmd.Flag.Args()
			}
			cmd.Run(cmd, args)
			exit()
			return
		}
	}

	fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0])
	setExitStatus(2)
	exit()
}
Exemple #16
0
// RecursiveImports recursively imports a set of Go targets, returning a map from each package to
// its path.
func RecursiveImports(args ...string) map[string]string {
	imports := map[string]string{}
	for _, arg := range args {
		var p *build.Package
		if build.IsLocalImport(arg) {
			p, _ = build.Default.ImportDir(arg, build.AllowBinary)
		} else {
			p, _ = build.Default.Import(arg, "", build.AllowBinary)
		}
		recursiveImport(p, arg, imports)
	}
	return imports
}
Exemple #17
0
// relevantImport will determine whether this import should be instrumented as well
func (i *Instrumentable) relevantImport(imp string) bool {
	switch {
	case imp == "C":
		return false
	case i.gorootPkgs[imp] && !i.InstrumentGoroot:
		return false
	case i.basepkg == "*" || build.IsLocalImport(imp):
		return true
	case i.IsInGopath() || i.basepkg != "":
		return filepath.HasPrefix(imp, i.basepkg) || filepath.HasPrefix(i.basepkg, imp)
	}
	return false
}
Exemple #18
0
/*
    This is how godoc does it:

	// Determine paths.
	//
	// If we are passed an operating system path like . or ./foo or /foo/bar or c:\mysrc,
	// we need to map that path somewhere in the fs name space so that routines
	// like getPageInfo will see it.  We use the arbitrarily-chosen virtual path "/target"
	// for this.  That is, if we get passed a directory like the above, we map that
	// directory so that getPageInfo sees it as /target.
	const target = "/target"
	const cmdPrefix = "cmd/"
	path := flag.Arg(0)
	var forceCmd bool
	var abspath, relpath string
	if filepath.IsAbs(path) {
		fs.Bind(target, OS(path), "/", bindReplace)
		abspath = target
	} else if build.IsLocalImport(path) {
		cwd, _ := os.Getwd() // ignore errors
		path = filepath.Join(cwd, path)
		fs.Bind(target, OS(path), "/", bindReplace)
		abspath = target
	} else if strings.HasPrefix(path, cmdPrefix) {
		path = path[len(cmdPrefix):]
		forceCmd = true
	} else if bp, _ := build.Import(path, "", build.FindOnly); bp.Dir != "" && bp.ImportPath != "" {
		fs.Bind(target, OS(bp.Dir), "/", bindReplace)
		abspath = target
		relpath = bp.ImportPath
	} else {
		abspath = pathpkg.Join(pkgHandler.fsRoot, path)
	}
	if relpath == "" {
		relpath = abspath
	}
*/
func buildImport(target string) (*build.Package, error) {
	if filepath.IsAbs(target) {
		return build.Default.ImportDir(target, build.FindOnly)
	} else if build.IsLocalImport(target) {
		base, _ := os.Getwd()
		path := filepath.Join(base, target)
		return build.Default.ImportDir(path, build.FindOnly)
	} else if pkg, _ := build.Default.Import(target, "", build.FindOnly); pkg.Dir != "" && pkg.ImportPath != "" {
		return pkg, nil
	}
	path, _ := filepath.Abs(target) // Even if there is an error, still try?
	return build.Default.ImportDir(path, build.FindOnly)
}
Exemple #19
0
Fichier : main.go Projet : kr/vexp
// loadPackage is like loadImport but is used for command-line arguments,
// not for paths found in import statements.  In addition to ordinary import paths,
// loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
// in the Go command directory, as well as paths to those directories.
func loadPackage(arg string, stk *importStack) *Package {
	// If it is a local import path but names a standard package,
	// we treat it as if the user specified the standard package.
	// This lets you run go test ./ioutil in package io and be
	// referring to io/ioutil rather than a hypothetical import of
	// "./ioutil".
	if build.IsLocalImport(arg) {
		bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
		if bp.ImportPath != "" && bp.ImportPath != "." {
			arg = bp.ImportPath
		}
	}
	return loadImport(arg, cwd, nil, stk, nil)
}
Exemple #20
0
func egc(ppath string) error {
	srcDir := ""
	if build.IsLocalImport(ppath) {
		var err error
		if srcDir, err = os.Getwd(); err != nil {
			return err
		}
	}
	bp, err := buildCtx.Import(ppath, srcDir, 0)
	if err != nil {
		return err
	}
	return compile(bp)
}
Exemple #21
0
// FindPkg returns the filename and unique package id for an import
// path based on package information provided by build.Import (using
// the build.Default build.Context). A relative srcDir is interpreted
// relative to the current working directory.
// If no file was found, an empty filename is returned.
//
func FindPkg(path, srcDir string) (filename, id string) {
	if path == "" {
		return
	}

	var noext string
	switch {
	default:
		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
		// Don't require the source files to be present.
		if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
			srcDir = abs
		}
		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
		if bp.PkgObj == "" {
			return
		}
		noext = strings.TrimSuffix(bp.PkgObj, ".a")
		id = bp.ImportPath

	case build.IsLocalImport(path):
		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
		noext = filepath.Join(srcDir, path)
		id = noext

	case filepath.IsAbs(path):
		// for completeness only - go/build.Import
		// does not support absolute imports
		// "/x" -> "/x.ext", "/x"
		noext = path
		id = path
	}

	if false { // for debugging
		if path != id {
			fmt.Printf("%s -> %s\n", path, id)
		}
	}

	// try extensions
	for _, ext := range pkgExts {
		filename = noext + ext
		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
			return
		}
	}

	filename = "" // not found
	return
}
Exemple #22
0
func (i *Instrumentable) instrumentTo(processed map[string]bool, istest bool, outdir, relpath string, f func(file *patch.PatchableFile) patch.Patches) error {
	if processed[relpath] {
		return nil
	}
	processed[i.pkg.ImportPath] = true
	imps := i.pkg.Imports
	if istest {
		imps = append(imps, i.pkg.TestImports...)
		imps = append(imps, i.pkg.XTestImports...)
	}
	for _, imp := range imps {
		if i.relevantImport(imp) {
			pkg, err := i.doimport(imp)
			if err != nil {
				return err
			}
			if build.IsLocalImport(imp) {
				imp = "./" + filepath.Join(relpath, imp)
			}
			if err := pkg.instrumentTo(processed, false, outdir, imp, f); err != nil {
				return err
			}
		}
	}
	if !istest {
		pkg := patch.NewPatchablePkg()
		if err := pkg.ParseFiles(i.Files()...); err != nil {
			return err
		}
		if err := i.instrumentPatchable(outdir, relpath, pkg, f); err != nil {
			return err
		}
	} else {
		pkg := patch.NewPatchablePkg()
		if err := pkg.ParseFiles(i.TestFiles()...); err != nil {
			return err
		}
		if err := i.instrumentPatchable(outdir, relpath, pkg, f); err != nil {
			return err
		}
		pkg = patch.NewPatchablePkg()
		if err := pkg.ParseFiles(i.XTestFiles()...); err != nil {
			return err
		}
		if err := i.instrumentPatchable(outdir, relpath, pkg, f); err != nil {
			return err
		}
	}
	return nil
}
Exemple #23
0
// Start watches changes in directories of compiled packages. If there
// is any change, enters in the directory of the command to compile, and it is
// sent a signal Restart.
//
// The argument cmdPath is the import path of source code for the command to run
// by gostart.
// Whether the logger is nil then it is created one by default. The logger
// is always returned.
// Each path in pkgTowatch has to be an import or filesystem path found in
// $GOROOT or $GOPATH.
func Start(cmdPath string, l *log.Logger, pkgTowatch ...string) (*pkgWatcher, error) {
	srv := new(pkgWatcher)
	if l == nil {
		srv.Log = log.New(os.Stdout, LOG_PREFIX, log.LstdFlags)
	}

	// Command
	if cmdPath == "" || build.IsLocalImport(cmdPath) {
		return srv, errors.New("FAIL! import path of command can not be local")
	} else {
		pkg, err := build.Import(cmdPath, build.Default.GOPATH, 0)
		if err != nil {
			return srv, fmt.Errorf("FAIL! at getting command directory: %s", err)
		}

		if !pkg.IsCommand() {
			return srv, fmt.Errorf("FAIL! no command: %s", cmdPath)
		}
		cmdPath = pkg.Dir
	}

	// Packages
	pkgTowatch, pkgFiles, err := checkPkgPath(pkgTowatch, srv.Log)
	if err != nil {
		return srv, err
	}

	w, err := sysWatcher(cmdPath, pkgTowatch, srv.Log)
	if err != nil {
		return srv, err
	}

	if USE_KERNEL {
		go w.watcher(pkgTowatch)
	} else {
		if err = w.watcher(pkgFiles); err != nil {
			return srv, err
		}
	}

	if *Verbose {
		srv.Log.Print("Start " + _WATCHER_NAME + " watcher for compiled packages")

		for _, p := range pkgTowatch {
			srv.Log.Printf("Watching %q", p)
		}
	}
	return w, nil
}
Exemple #24
0
func getChildPkgs(ctx *cli.Context, cpath string, ppkg *doc.Pkg, cachePkgs map[string]*doc.Pkg, isTest bool) error {
	log.Trace("Current Path: 1 %s", cpath)
	pkgs, err := getGopmPkgs(cpath, isTest)
	if err != nil {
		return errors.New("Fail to get gopmfile deps: " + err.Error())
	}
	for name, pkg := range pkgs {
		pkg.RootPath = doc.GetProjectPath(pkg.ImportPath)
		if !pkgInCache(pkg.RootPath, cachePkgs) {
			var newPath string
			if !build.IsLocalImport(name) && pkg.Type != doc.LOCAL {
				suf := versionSuffix(pkg.Value)
				pkgPath := strings.Replace(
					pkg.ImportPath, pkg.RootPath, pkg.RootPath+suf, 1)
				newPath = filepath.Join(installRepoPath, pkgPath)
				if len(suf) == 0 && !ctx.Bool("remote") &&
					com.IsDir(filepath.Join(installGopath, pkgPath)) {
					newPath = filepath.Join(installGopath, pkgPath)
				}
				if pkgName != "" && strings.HasPrefix(pkg.ImportPath, pkgName) {
					newPath = filepath.Join(curPath, strings.TrimPrefix(pkg.ImportPath, pkgName))
				} else {
					if !com.IsExist(newPath) || ctx.Bool("update") {
						node := doc.NewNode(pkg.ImportPath, pkg.ImportPath,
							pkg.Type, pkg.Value, true)
						nodes := []*doc.Node{node}
						downloadPackages(ctx, nodes)
						// TODO: Should handler download failed
					}
				}
			} else {
				if pkg.Type == doc.LOCAL {
					newPath, err = filepath.Abs(pkg.Value)
				} else {
					newPath, err = filepath.Abs(name)
				}
				if err != nil {
					return err
				}
			}
			cachePkgs[pkg.RootPath] = pkg
			err = getChildPkgs(ctx, newPath, pkg, cachePkgs, false)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
Exemple #25
0
func (r *Runner) makePkgTree() (*pkg, error) {
	nodes := make(map[string]*pkg)

	var walkImports func(*build.Package) (*pkg, error)
	walkImports = func(p *build.Package) (*pkg, error) {
		root, err := r.makePkg(p)
		if err != nil {
			return nil, err
		}

		for _, path := range p.Imports {
			if stdLib[path] {
				continue
			}

			idx := path
			if build.IsLocalImport(path) {
				idx = filepath.Clean(filepath.Join(p.Dir, path))
			}
			if nodes[idx] == nil {
				pp, err := build.Import(path, p.Dir, 0)
				if err != nil {
					return nil, err
				}

				if pp.Goroot {
					stdLib[path] = true
					continue
				}

				node, err := walkImports(pp)
				if err != nil {
					return nil, err
				}
				nodes[idx] = node
			}
			root.Imports[path] = nodes[idx]
		}

		return root, nil
	}

	p, err := build.ImportDir(r.Dir, 0)
	if err != nil {
		return nil, err
	}

	return walkImports(p)
}
Exemple #26
0
// importPaths returns the import paths to use for the given command line.
// $GOROOT/src/cmd/main.go:366
func importPaths(args []string) []string {
	args = importPathsNoDotExpansion(args)
	var out []string
	for _, a := range args {
		if strings.Contains(a, "...") {
			if build.IsLocalImport(a) {
				out = append(out, allPackagesInFS(a)...)
			} else {
				out = append(out, allPackages(a)...)
			}
			continue
		}
		out = append(out, a)
	}
	return out
}
Exemple #27
0
// Import imports a gc-generated package given its import path, adds the
// corresponding package object to the imports map, and returns the object.
// Local import paths are interpreted relative to the current working directory.
// The imports map must contains all packages already imported.
//
func Import(imports map[string]*types.Package, path string) (pkg *types.Package, err error) {
	// package "unsafe" is handled by the type checker
	if path == "unsafe" {
		panic(`gcimporter.Import called for package "unsafe"`)
	}

	srcDir := "."
	if build.IsLocalImport(path) {
		srcDir, err = os.Getwd()
		if err != nil {
			return
		}
	}

	filename, id := FindPkg(path, srcDir)
	if filename == "" {
		err = fmt.Errorf("can't find import: %s", id)
		return
	}

	// no need to re-import if the package was imported completely before
	if pkg = imports[id]; pkg != nil && pkg.Complete() {
		return
	}

	// open file
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer func() {
		f.Close()
		if err != nil {
			// add file name to error
			err = fmt.Errorf("reading export data: %s: %v", filename, err)
		}
	}()

	buf := bufio.NewReader(f)
	if err = FindExportData(buf); err != nil {
		return
	}

	pkg, err = ImportData(imports, filename, id, buf)

	return
}
Exemple #28
0
// paths determines the paths to use.
//
// If we are passed an operating system path like . or ./foo or /foo/bar or c:\mysrc,
// we need to map that path somewhere in the fs name space so that routines
// like getPageInfo will see it.  We use the arbitrarily-chosen virtual path "/target"
// for this.  That is, if we get passed a directory like the above, we map that
// directory so that getPageInfo sees it as /target.
// Returns the absolute and relative paths.
func paths(fs vfs.NameSpace, pres *Presentation, path string) (string, string) {
	if filepath.IsAbs(path) {
		fs.Bind(target, vfs.OS(path), "/", vfs.BindReplace)
		return target, target
	}
	if build.IsLocalImport(path) {
		cwd, _ := os.Getwd() // ignore errors
		path = filepath.Join(cwd, path)
		fs.Bind(target, vfs.OS(path), "/", vfs.BindReplace)
		return target, target
	}
	if bp, _ := build.Import(path, "", build.FindOnly); bp.Dir != "" && bp.ImportPath != "" {
		fs.Bind(target, vfs.OS(bp.Dir), "/", vfs.BindReplace)
		return target, bp.ImportPath
	}
	return pathpkg.Join(pres.PkgFSRoot(), path), path
}
Exemple #29
0
// GcImport imports a gc-generated package given its import path, adds the
// corresponding package object to the imports map, and returns the object.
// Local import paths are interpreted relative to the current working directory.
// The imports map must contains all packages already imported.
// GcImport satisfies the ast.Importer signature.
//
func GcImport(imports map[string]*Package, path string) (pkg *Package, err error) {
	if path == "unsafe" {
		return Unsafe, nil
	}

	srcDir := "."
	if build.IsLocalImport(path) {
		srcDir, err = os.Getwd()
		if err != nil {
			return
		}
	}

	filename, id := FindPkg(path, srcDir)
	if filename == "" {
		err = errors.New("can't find import: " + id)
		return
	}

	// no need to re-import if the package was imported completely before
	if pkg = imports[id]; pkg != nil && pkg.Complete {
		return
	}

	// open file
	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer func() {
		f.Close()
		if err != nil {
			// add file name to error
			err = fmt.Errorf("reading export data: %s: %v", filename, err)
		}
	}()

	buf := bufio.NewReader(f)
	if err = FindGcExportData(buf); err != nil {
		return
	}

	pkg, err = GcImportData(imports, filename, id, buf)

	return
}
Exemple #30
0
func main() {
	flag.Usage = usage
	flag.Parse()

	if flag.NArg() == 0 {
		report("no package name, path, or file provided")
	}

	imp := tryImports
	if *source != "" {
		imp = lookup(*source)
		if imp == nil {
			report("source (-s argument) must be one of: " + strings.Join(sources, ", "))
		}
	}

	for _, arg := range flag.Args() {
		path, name := splitPathIdent(arg)
		logf("\tprocessing %q: path = %q, name = %s\n", arg, path, name)

		// generate possible package path prefixes
		// (at the moment we do this for each argument - should probably cache the generated prefixes)
		prefixes := make(chan string)
		go genPrefixes(prefixes, !filepath.IsAbs(path) && !build.IsLocalImport(path))

		// import package
		pkg, err := tryPrefixes(packages, prefixes, path, imp)
		if err != nil {
			logf("\t=> ignoring %q: %s\n", path, err)
			continue
		}

		// filter objects if needed
		var filter func(types.Object) bool
		if name != "" {
			filter = func(obj types.Object) bool {
				// TODO(gri) perhaps use regular expression matching here?
				return obj.Name() == name
			}
		}

		// print contents
		print(os.Stdout, pkg, filter)
	}
}