mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-16 01:22:00 +00:00
e2fb37c0ac
The coverage pages led with a percentage and an "x of y" count, and every table listed the modelled operations Spinifex does not implement, which reads as a scorecard against AWS rather than a statement of what the platform serves. A published page now opens with the operation count alone, tables the operations the gateway serves, and carries a separate not-applicable table with each reason inline instead of footnotes. The unimplemented operations and the counts move to docs/coverage/internal-report.md, which no docs-site slug points at. A service with no implemented operations has no publishable page.
92 lines
2.4 KiB
Go
92 lines
2.4 KiB
Go
package awsmodel
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
const (
|
|
pagesFile = "pages.json"
|
|
introFile = "intro.md"
|
|
pageFile = "README.md"
|
|
internalFile = "internal-report.md"
|
|
)
|
|
|
|
// WritePages renders the publishable coverage pages into outputDir, which must
|
|
// already hold pages.json. A service without page metadata is skipped, and any
|
|
// README.md already there is overwritten: only pages.json and the intro.md
|
|
// files are hand-maintained.
|
|
func WritePages(outputDir string, coverages []OperationCoverage) error {
|
|
contents, err := os.ReadFile(filepath.Join(outputDir, pagesFile))
|
|
if err != nil {
|
|
return fmt.Errorf("awsmodel: read coverage page metadata: %w", err)
|
|
}
|
|
pages, err := ParsePageSet(contents)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, coverage := range coverages {
|
|
page, ok := pages.Services[coverage.Service]
|
|
if !ok {
|
|
continue
|
|
}
|
|
intro, err := readIntro(outputDir, page.Slug)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
body, err := RenderServicePage(coverage, pages, intro)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := writePage(outputDir, page.Slug, body); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
intro, err := readIntro(outputDir, pages.Index.Slug)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
body, err := RenderIndexPage(coverages, pages, intro)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := writePage(outputDir, pages.Index.Slug, body); err != nil {
|
|
return err
|
|
}
|
|
|
|
report := RenderInternalReport(coverages)
|
|
if err := os.WriteFile(filepath.Join(outputDir, internalFile), []byte(report), 0o600); err != nil {
|
|
return fmt.Errorf("awsmodel: write internal coverage report: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// readIntro returns the hand-written prose for a page, or "" where the page has
|
|
// none. An intro is optional by design: most services have nothing to add.
|
|
func readIntro(outputDir, slug string) (string, error) {
|
|
contents, err := os.ReadFile(filepath.Join(outputDir, slug, introFile))
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
return "", nil
|
|
}
|
|
if err != nil {
|
|
return "", fmt.Errorf("awsmodel: read %s intro: %w", slug, err)
|
|
}
|
|
return string(contents), nil
|
|
}
|
|
|
|
func writePage(outputDir, slug, body string) error {
|
|
dir := filepath.Join(outputDir, slug)
|
|
if err := os.MkdirAll(dir, 0o750); err != nil {
|
|
return fmt.Errorf("awsmodel: create %s page directory: %w", slug, err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dir, pageFile), []byte(body), 0o600); err != nil {
|
|
return fmt.Errorf("awsmodel: write %s page: %w", slug, err)
|
|
}
|
|
return nil
|
|
}
|