func initRunfiles()

in go/tools/bazel/runfiles.go [356:458]


func initRunfiles() {
	manifest := os.Getenv("RUNFILES_MANIFEST_FILE")
	if manifest != "" {
		// On Windows, Bazel doesn't create a symlink tree of runfiles because
		// Windows doesn't support symbolic links by default. Instead, runfile
		// locations are written to a manifest file.
		runfiles.index = newIndex()
		data, err := ioutil.ReadFile(manifest)
		if err != nil {
			runfiles.err = err
			return
		}
		lineno := 0
		for len(data) > 0 {
			i := bytes.IndexByte(data, '\n')
			var line []byte
			if i < 0 {
				line = data
				data = nil
			} else {
				line = data[:i]
				data = data[i+1:]
			}
			lineno++

			// Only TrimRight newlines. Do not TrimRight() completely, because that would remove spaces too.
			// This is necessary in order to have at least one space in every manifest line.
			// Some manifest entries don't have any path after this space, namely the "__init__.py" entries.
			// original comment sourced from: https://github.com/bazelbuild/bazel/blob/09c621e4cf5b968f4c6cdf905ab142d5961f9ddc/src/test/py/bazel/runfiles_test.py#L225
			line = bytes.TrimRight(line, "\r\n")
			if len(line) == 0 {
				continue
			}

			spaceIndex := bytes.IndexByte(line, ' ')
			if spaceIndex < 0 {
				runfiles.err = fmt.Errorf(
					"error parsing runfiles manifest: %s:%d: no space: '%s'", manifest, lineno, line)
				return
			}
			shortPath := string(line[0:spaceIndex])
			abspath := ""
			if len(line) > spaceIndex+1 {
				abspath = string(line[spaceIndex+1:])
			}

			entry := RunfileEntry{ShortPath: shortPath, Path: abspath}
			if i := strings.IndexByte(entry.ShortPath, '/'); i >= 0 {
				entry.Workspace = entry.ShortPath[:i]
				entry.ShortPath = entry.ShortPath[i+1:]
			}
			if strings.HasPrefix(entry.ShortPath, "external/") {
				entry.ShortPath = entry.ShortPath[len("external/"):]
				if i := strings.IndexByte(entry.ShortPath, '/'); i >= 0 {
					entry.Workspace = entry.ShortPath[:i]
					entry.ShortPath = entry.ShortPath[i+1:]
				}
			}

			runfiles.list = append(runfiles.list, entry)
			runfiles.index.Put(&entry)
		}
	}

	runfiles.workspace = os.Getenv("TEST_WORKSPACE")

	if dir := os.Getenv("RUNFILES_DIR"); dir != "" {
		runfiles.dir = dir
	} else if dir = os.Getenv("TEST_SRCDIR"); dir != "" {
		runfiles.dir = dir
	} else if runtime.GOOS != "windows" {
		dir, err := os.Getwd()
		if err != nil {
			runfiles.err = fmt.Errorf("error locating runfiles dir: %v", err)
			return
		}

		parent := filepath.Dir(dir)
		if strings.HasSuffix(parent, ".runfiles") {
			runfiles.dir = parent
			if runfiles.workspace == "" {
				runfiles.workspace = filepath.Base(dir)
			}
		} else {
			runfiles.err = errors.New("could not locate runfiles directory")
			return
		}
	}

	if runfiles.dir != "" {
		fis, err := ioutil.ReadDir(runfiles.dir)
		if err != nil {
			runfiles.err = fmt.Errorf("could not open runfiles directory: %v", err)
			return
		}
		for _, fi := range fis {
			if fi.IsDir() {
				runfiles.workspaces = append(runfiles.workspaces, fi.Name())
			}
		}
		sort.Strings(runfiles.workspaces)
	}
}