func findModule()

in tool/preprocess/preprocess.go [451:520]


func findModule(buildCmd []string) ([]*packages.Package, error) {
	candidates := make([]*packages.Package, 0)
	found := false

	// Find from build arguments e.g. go build test.go or go build cmd/app
	for i := len(buildCmd) - 1; i >= 0; i-- {
		buildArg := buildCmd[i]

		// Stop canary when we see a build flag or a "build" command
		if strings.HasPrefix("-", buildArg) || buildArg == "build" {
			break
		}

		// Special case. If the file named with test_ prefix, we create a fake
		// package for it. This is a workaround for the case that the test file
		// is compiled with other normal files.
		if strings.HasSuffix(buildArg, ".go") &&
			strings.HasPrefix(buildArg, "test_") {
			artificialPkg := &packages.Package{
				GoFiles: []string{buildArg},
				Name:    "main",
			}
			candidates = append(candidates, artificialPkg)
			found = true
			continue
		}

		// Trying to load package from the build argument, error is tolerated
		// because we dont know what the build argument is. One exception is
		// when we already found packages, in this case, we expect subsequent
		// build arguments are packages, so we should not tolerate any error.
		pkgs, err := tryLoadPackage(buildArg)
		if err != nil {
			if found {
				// If packages are already found, we expect subsequent build
				// arguments are packages, so we should not tolerate any error
				break
			}
			util.Log("Cannot load package from %v", buildArg)
			continue
		}
		for _, pkg := range pkgs {
			if pkg.Errors != nil {
				continue
			}
			found = true
			candidates = append(candidates, pkg)
		}
	}

	// If no import paths are given, the action applies to the package in the
	// current directory.
	if !found {
		pkgs, err := tryLoadPackage(".")
		if err != nil {
			return nil, err
		}
		for _, pkg := range pkgs {
			if pkg.Errors != nil {
				continue
			}
			candidates = append(candidates, pkg)
		}
	}
	if len(candidates) == 0 {
		return nil, errc.New(errc.ErrPreprocess, "no package found")
	}

	return candidates, nil
}