func fetchMainDetails()

in internal/frontend/main.go [108:226]


func fetchMainDetails(ctx context.Context, ds internal.DataSource, um *internal.UnitMeta,
	requestedVersion string, expandReadme bool, bc internal.BuildContext) (_ *MainDetails, err error) {
	defer middleware.ElapsedStat(ctx, "fetchMainDetails")()

	unit, err := ds.GetUnit(ctx, um, internal.WithMain, bc)
	if err != nil {
		return nil, err
	}
	subdirectories := getSubdirectories(um, unit.Subdirectories, requestedVersion)
	if err != nil {
		return nil, err
	}
	nestedModules, err := getNestedModules(ctx, ds, um, subdirectories)
	if err != nil {
		return nil, err
	}
	readme, err := readmeContent(ctx, unit)
	if err != nil {
		return nil, err
	}
	var (
		docParts           = &dochtml.Parts{}
		docLinks, modLinks []link
		files              []*File
		synopsis           string
		goos, goarch       string
		buildContexts      []internal.BuildContext
	)

	unit.Documentation = cleanDocumentation(unit.Documentation)
	// There should be at most one Documentation.
	var doc *internal.Documentation
	if len(unit.Documentation) > 0 {
		doc = unit.Documentation[0]
	}

	if doc != nil {
		synopsis = doc.Synopsis
		goos = doc.GOOS
		goarch = doc.GOARCH
		buildContexts = unit.BuildContexts
		end := middleware.ElapsedStat(ctx, "DecodePackage")
		docPkg, err := godoc.DecodePackage(doc.Source)
		end()
		if err != nil {
			if errors.Is(err, godoc.ErrInvalidEncodingType) {
				// Instead of returning a 500, return a 404 so the user can
				// reprocess the documentation.
				log.Errorf(ctx, "fetchMainDetails(%q, %q, %q): %v", um.Path, um.ModulePath, um.Version, err)
				return nil, errUnitNotFoundWithoutFetch
			}
			return nil, err
		}

		docParts, err = getHTML(ctx, unit, docPkg, unit.SymbolHistory, bc)
		// If err  is ErrTooLarge, then docBody will have an appropriate message.
		if err != nil && !errors.Is(err, dochtml.ErrTooLarge) {
			return nil, err
		}
		for _, l := range docParts.Links {
			docLinks = append(docLinks, link{Href: l.Href, Body: l.Text})
		}
		end = middleware.ElapsedStat(ctx, "sourceFiles")
		files = sourceFiles(unit, docPkg)
		end()
	}
	// If the unit is not a module, fetch the module readme to extract its
	// links.
	// In the unlikely event that the module is redistributable but the unit is
	// not, we will not show the module links on the unit page.
	if unit.Path != unit.ModulePath && unit.IsRedistributable {
		modReadme, err := ds.GetModuleReadme(ctx, unit.ModulePath, unit.Version)
		if err != nil && !errors.Is(err, derrors.NotFound) {
			return nil, err
		}
		if err == nil {
			rm, err := processReadme(ctx, modReadme, um.SourceInfo)
			if err != nil {
				return nil, err
			}
			modLinks = rm.Links
		}
	}

	versionType, err := version.ParseType(um.Version)
	if err != nil {
		return nil, err
	}
	isTaggedVersion := versionType != version.TypePseudo
	isStableVersion := semver.Major(um.Version) != "v0" && versionType == version.TypeRelease
	pr := message.NewPrinter(middleware.LanguageTag(ctx))
	return &MainDetails{
		ExpandReadme:      expandReadme,
		Directories:       unitDirectories(append(subdirectories, nestedModules...)),
		Licenses:          transformLicenseMetadata(um.Licenses),
		CommitTime:        absoluteTime(um.CommitTime),
		Readme:            readme.HTML,
		ReadmeOutline:     readme.Outline,
		ReadmeLinks:       readme.Links,
		DocLinks:          docLinks,
		ModuleReadmeLinks: modLinks,
		DocOutline:        docParts.Outline,
		DocBody:           docParts.Body,
		DocSynopsis:       synopsis,
		GOOS:              goos,
		GOARCH:            goarch,
		BuildContexts:     buildContexts,
		SourceFiles:       files,
		RepositoryURL:     um.SourceInfo.RepoURL(),
		SourceURL:         um.SourceInfo.DirectoryURL(internal.Suffix(um.Path, um.ModulePath)),
		MobileOutline:     docParts.MobileOutline,
		NumImports:        pr.Sprint(unit.NumImports),
		ImportedByCount:   pr.Sprint(unit.NumImportedBy),
		IsPackage:         unit.IsPackage(),
		ModFileURL:        um.SourceInfo.ModuleURL() + "/go.mod",
		IsTaggedVersion:   isTaggedVersion,
		IsStableVersion:   isStableVersion,
	}, nil
}