repo/repo.go
func ListRepositories(workspace *rule.File) (repos []Repo, repoNamesByFile map[*rule.File][]string, err error) {
	repoNamesByFile = make(map[*rule.File][]string)
	repos, repoNamesByFile[workspace] = getRepos(workspace.Rules)
	for _, d := range workspace.Directives {
		switch d.Key {
		case "repository_macro":
			f, defName, err := parseRepositoryMacroDirective(d.Value)
			if err != nil {
				return nil, nil, err
			}
			f = filepath.Join(filepath.Dir(workspace.Path), filepath.Clean(f))
			macroFile, err := rule.LoadMacroFile(f, "", defName)
			if err != nil {
				return nil, nil, err
			}
			currRepos, names := getRepos(macroFile.Rules)
			repoNamesByFile[macroFile] = names
			repos = append(repos, currRepos...)
		}
	}

	return repos, repoNamesByFile, nil
}
func ListRepositories(workspace *rule.File) (repos []Repo, repoNamesByFile map[*rule.File][]string, err error) {
	repoNamesByFile = make(map[*rule.File][]string)
	repos, repoNamesByFile[workspace] = getRepos(workspace.Rules)
	for _, d := range workspace.Directives {
		switch d.Key {
		case "repository_macro":
			f, defName, err := parseRepositoryMacroDirective(d.Value)
			if err != nil {
				return nil, nil, err
			}
			f = filepath.Join(filepath.Dir(workspace.Path), filepath.Clean(f))
			macroFile, err := rule.LoadMacroFile(f, "", defName)
			if err != nil {
				return nil, nil, err
			}
			currRepos, names := getRepos(macroFile.Rules)
			repoNamesByFile[macroFile] = names
			repos = append(repos, currRepos...)
		}
	}

	return repos, repoNamesByFile, nil
}
// ListRepositories extracts metadata about repositories declared in a
// file.