mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
b89334d76f
The internal report listed every unimplemented operation together, so the 87 EC2 operations declared not applicable sat in the same list as the work, where anything reading it for candidates would pick them up. They are now listed apart, grouped under the reason they were declared with, and the counts line reports them as not applicable rather than as gaps.
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, pages)
|
|
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
|
|
}
|