prow/spyglass/spyglass.go
func (sg *Spyglass) ExtraLinks(src string) ([]ExtraLink, error) {
	artifacts, err := sg.FetchArtifacts(src, "", 1000000, []string{"started.json"})
	// Failing to find started.json is okay, just return nothing quietly.
	if err != nil || len(artifacts) == 0 {
		logrus.WithError(err).Debugf("Failed to find started.json while looking for extra links.")
		return nil, nil
	}
	// Failing to read an artifact we already know to exist shouldn't happen, so that's an error.
	content, err := artifacts[0].ReadAll()
	if err != nil {
		return nil, err
	}
	// Being unable to parse a successfully fetched started.json correctly is also an error.
	started := metadata.Started{}
	if err := json.Unmarshal(content, &started); err != nil {
		return nil, err
	}
	// Not having any links is fine.
	links, ok := started.Metadata.Meta("links")
	if !ok {
		return nil, nil
	}
	extraLinks := make([]ExtraLink, 0, len(*links))
	for _, name := range links.Keys() {
		m, ok := links.Meta(name)
		if !ok {
			// This should never happen, because Keys() should only return valid Metas.
			logrus.Debugf("Got bad link key %q from %s, but that should be impossible.", name, artifacts[0].CanonicalLink())
			continue
		}
		s := m.Strings()
		link := ExtraLink{
			Name:        name,
			URL:         s["url"],
			Description: s["description"],
		}
		if link.URL == "" || link.Name == "" {
			continue
		}
		extraLinks = append(extraLinks, link)
	}
	return extraLinks, nil
}
func (sg *Spyglass) ExtraLinks(src string) ([]ExtraLink, error) {
	artifacts, err := sg.FetchArtifacts(src, "", 1000000, []string{"started.json"})
	// Failing to find started.json is okay, just return nothing quietly.
	if err != nil || len(artifacts) == 0 {
		logrus.WithError(err).Debugf("Failed to find started.json while looking for extra links.")
		return nil, nil
	}
	// Failing to read an artifact we already know to exist shouldn't happen, so that's an error.
	content, err := artifacts[0].ReadAll()
	if err != nil {
		return nil, err
	}
	// Being unable to parse a successfully fetched started.json correctly is also an error.
	started := metadata.Started{}
	if err := json.Unmarshal(content, &started); err != nil {
		return nil, err
	}
	// Not having any links is fine.
	links, ok := started.Metadata.Meta("links")
	if !ok {
		return nil, nil
	}
	extraLinks := make([]ExtraLink, 0, len(*links))
	for _, name := range links.Keys() {
		m, ok := links.Meta(name)
		if !ok {
			// This should never happen, because Keys() should only return valid Metas.
			logrus.Debugf("Got bad link key %q from %s, but that should be impossible.", name, artifacts[0].CanonicalLink())
			continue
		}
		s := m.Strings()
		link := ExtraLink{
			Name:        name,
			URL:         s["url"],
			Description: s["description"],
		}
		if link.URL == "" || link.Name == "" {
			continue
		}
		extraLinks = append(extraLinks, link)
	}
	return extraLinks, nil
}
// ExtraLinks fetches started.json and extracts links from metadata.links.