magefiles/packages/docs.go (99 lines of code) (raw):

package packages import ( "errors" "fmt" "io" "maps" "os" "slices" "strings" "gitlab.com/gitlab-org/gitlab-runner/magefiles/docutils" "golang.org/x/text/cases" "golang.org/x/text/language" ) const ( startSupportedOSDocs = "<!-- supported_os_versions_list_start -->" endSupportedOSDocs = "<!-- supported_os_versions_list_end -->" docsFilePath = "docs/install/linux-repository.md" ) // This type is to reuse existing code that would otherwise cause a circular dependency. type distListFunc func(string, string) ([]string, error) func GenerateSupportedOSDocs(f distListFunc) error { debDists, rpmDists, err := getDistributionLists(f) if err != nil { return err } rendered := render(debDists, rpmDists) origContent, err := os.ReadFile(docsFilePath) if err != nil { return err } newContent, err := replace( startSupportedOSDocs, endSupportedOSDocs, string(origContent), rendered) if err != nil { return err } if err := os.WriteFile(docsFilePath, []byte(newContent), 0o644); err != nil { return fmt.Errorf("error while writing new content for %q file: %w", origContent, err) } return nil } func getDistributionLists(f distListFunc) ([]string, []string, error) { debOSs, derr := f("deb", "stable") rpmOSs, rerr := f("rpm", "stable") return debOSs, rpmOSs, errors.Join(derr, rerr) } func render(debDists, rpmDists []string) string { buf := strings.Builder{} buf.WriteString(startSupportedOSDocs) buf.WriteString("\n### Deb-based Distributions\n\n") renderTable(debDists, &buf) buf.WriteString("\n### Rpm-based Distributions\n\n") renderTable(rpmDists, &buf) buf.WriteString("\n") buf.WriteString(endSupportedOSDocs) buf.WriteString("\n") return buf.String() } var properDistNames = map[string]string{ "ubuntu": "Ubuntu", "debian": "Debian", "linuxmint": "LinuxMint", "raspbian": "Raspbian", "el": "Red Hat Enterprise Linux", "fedora": "Fedora", "ol": "Oracle Linux", "opensuse": "openSUSE", "sles": "SUSE Linux Enterprise Server", "amazon": "Amazon Linux", } //nolint:errcheck func renderTable(dists []string, dest io.StringWriter) { versByOS := map[string][]string{} for _, f := range dists { toks := strings.Split(f, "/") os := toks[0] ver := cases.Title(language.English, cases.Compact).String(toks[1]) versByOS[os] = append(versByOS[os], ver) } dest.WriteString("| Distribution | Supported Versions |\n") dest.WriteString("|-|-|\n") for _, dist := range slices.Sorted(maps.Keys(versByOS)) { vers := versByOS[dist] dist = properDistNames[dist] dest.WriteString("| ") dest.WriteString(dist) dest.WriteString(" | ") dest.WriteString(strings.Join(vers, ", ")) dest.WriteString(" |\n") } } func replace(placeholderStart, placeholderEnd, fileContent, content string) (string, error) { replacer := docutils.NewBlockLineReplacer(placeholderStart, placeholderEnd, fileContent, content) newContent, err := replacer.Replace() if err != nil { return "", fmt.Errorf("error while replacing the content: %w", err) } return newContent, nil }