func()

in internal/changelog/builder.go [49:168]


func (b Builder) Build(owner, repo string) error {
	log.Printf("building changelog for version: %s\n", b.changelog.Version)
	log.Printf("collecting fragments from %s\n", b.src)

	var files []string
	err := afero.Walk(b.fs, b.src, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() && info.Name() == "fixtures" {
			return filepath.SkipDir
		}

		return collectFragment(b.fs, path, info, err, &files)
	})
	if err != nil {
		return fmt.Errorf("cannot walk path %s: %w", b.src, err)
	}

	if len(files) == 0 {
		return errNoFragments
	}

	for _, file := range files {
		log.Printf("parsing %s", file)

		f, err := fragment.Load(b.fs, file)
		if err != nil {
			return fmt.Errorf("cannot load fragment from file %s: %w", file, err)
		}

		b.changelog.Entries = append(b.changelog.Entries, EntryFromFragment(f))
	}

	hc, err := github.GetHTTPClient(b.fs)
	if err != nil {
		return fmt.Errorf("cannot initialize http client: %w", err)
	}

	c := github.NewClient(hc)
	graphqlClient := github.NewGraphQLClient(hc)

	log.Println("Verifying entries:")

	for i, entry := range b.changelog.Entries {
		// Filling empty PR fields
		if len(entry.LinkedPR) == 0 {

			commitHash, err := GetLatestCommitHash(entry.File.Name)
			if err != nil {
				log.Printf("%s: cannot find commit hash, fill the PR field in changelog", entry.File.Name)
				continue
			}

			prIDs, err := FillEmptyPRField(commitHash, owner, repo, c)
			if err != nil {
				log.Printf("%s: fill the PR field in changelog", entry.File.Name)
				continue
			}

			if len(prIDs) > 1 {
				log.Printf("%s: multiple PRs found, please remove all but one of them", entry.File.Name)
			}

			b.changelog.Entries[i].LinkedPR = prIDs
		} else {
			// Applying heuristics to PR fields
			owner, repo, err := ExtractOwnerRepo(entry.LinkedPR[0])
			if err != nil {
				log.Printf("%s: check if the PR field is correct in changelog: %s", entry.File.Name, err.Error())
				continue
			}

			originalPR, err := FindOriginalPR(entry.LinkedPR[0], owner, repo, c)
			if err != nil {
				log.Printf("%s: check if the PR field is correct in changelog: %s", entry.File.Name, err.Error())
				continue
			}

			b.changelog.Entries[i].LinkedPR = []string{originalPR}
		}

		if len(entry.LinkedIssue) == 0 && len(b.changelog.Entries[i].LinkedPR) > 0 {
			linkedIssues := []string{}

			for _, prURL := range b.changelog.Entries[i].LinkedPR {
				owner, repo, err := ExtractOwnerRepo(prURL)
				if err != nil {
					log.Printf("%s: check if the PR field is correct in changelog: %s", entry.File.Name, err.Error())
					continue
				}

				tempIssues, err := FindIssues(graphqlClient, context.Background(), owner, repo, prURL, 50)
				if err != nil {
					log.Printf("%s: could not find linked issues for pr: %s: %s", entry.File.Name, entry.LinkedPR, err.Error())
					continue
				}

				linkedIssues = append(linkedIssues, tempIssues...)
				if len(linkedIssues) > 1 {
					log.Printf("%s: multiple issues found, please remove all but one of them", entry.File.Name)
				}
			}

			b.changelog.Entries[i].LinkedIssue = linkedIssues
		} else if len(entry.LinkedIssue) == 1 {
			_, err = ExtractEventNumber("issue", entry.LinkedIssue[0])
			if err != nil {
				log.Printf("%s: check if the issue field is correct in changelog: %s", entry.File.Name, err.Error())
			}
		}

	}

	data, err := yaml.Marshal(&b.changelog)
	if err != nil {
		return fmt.Errorf("cannot marshall changelog: %w", err)
	}

	outFile := path.Join(b.dest, b.filename)
	log.Printf("saving changelog in: %s\n", outFile)
	return afero.WriteFile(b.fs, outFile, data, changelogFilePerm)
}