Esempio n. 1
0
// installPackage installs the specified package and its dependencies.
func installPackage(pkg, parent string, tree *build.Tree, retry bool) (installErr error) {
	printf("%s: install\n", pkg)

	// Read package information.
	dir := filepath.Join(tree.SrcDir(), filepath.FromSlash(pkg))
	dirInfo, err := build.ScanDir(dir)
	if err != nil {
		return &PackageError{pkg, err}
	}

	// We reserve package main to identify commands.
	if parent != "" && dirInfo.Package == "main" {
		return &PackageError{pkg, fmt.Errorf("found only package main in %s; cannot import", dir)}
	}

	// Run gofix if we fail to build and -fix is set.
	defer func() {
		if retry || installErr == nil || !*doGofix {
			return
		}
		if e, ok := (installErr).(*DependencyError); ok {
			// If this package failed to build due to a
			// DependencyError, only attempt to gofix it if its
			// dependency failed for some reason other than a
			// DependencyError or BuildError.
			// (If a dep or one of its deps doesn't build there's
			// no way that gofixing this package can help.)
			switch e.err.(type) {
			case *DependencyError:
				return
			case *BuildError:
				return
			}
		}
		gofix(pkg, dir, dirInfo)
		installErr = installPackage(pkg, parent, tree, true) // retry
	}()

	// Install prerequisites.
	for _, p := range dirInfo.Imports {
		if p == "C" {
			continue
		}
		if err := install(p, pkg); err != nil {
			return &DependencyError{pkg, err}
		}
	}

	// Install this package.
	err = domake(dir, pkg, tree, dirInfo.IsCommand())
	if err != nil {
		return &BuildError{pkg, err}
	}
	return nil
}