Skip to content

Commit

Permalink
Support for generating separate files for each group (#67)
Browse files Browse the repository at this point in the history
This adds a new flag `output-mode` to control whether API docs is generated
in one single file or in separate files for each API group.
  • Loading branch information
airycanon committed Mar 7, 2024
1 parent c844843 commit 83e2ff3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 9 deletions.
6 changes: 6 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,19 @@ type KnownType struct {
Link string `json:"link"`
}

const (
OutputModeSingle = "single"
OutputModeGroup = "group"
)

type Flags struct {
Config string
LogLevel string
OutputPath string
Renderer string
SourcePath string
TemplatesDir string
OutputMode string
MaxDepth int
}

Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func main() {
cmd.Flags().StringVar(&args.TemplatesDir, "templates-dir", "", "Path to the directory containing template files")
cmd.Flags().StringVar(&args.Renderer, "renderer", "asciidoctor", "Renderer to use ('asciidoctor' or 'markdown')")
cmd.Flags().StringVar(&args.OutputPath, "output-path", ".", "Path to output the rendered result")
cmd.Flags().StringVar(&args.OutputMode, "output-mode", "single", "Output mode to generate a single file or one file per group ('group' or 'single')")
cmd.Flags().IntVar(&args.MaxDepth, "max-depth", 10, "Maximum recursion level for type discovery")

cmd.Execute()
Expand Down
5 changes: 1 addition & 4 deletions renderer/asciidoctor.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@ func (adr *AsciidoctorRenderer) Render(gvd []types.GroupVersionDetails) error {
return err
}

f, err := createOutFile(adr.conf.OutputPath, "out.asciidoc")
defer f.Close()

return tmpl.ExecuteTemplate(f, mainTemplate, gvd)
return renderTemplate(tmpl, adr.conf, "asciidoc", gvd)
}

func (adr *AsciidoctorRenderer) ToFuncMap() template.FuncMap {
Expand Down
5 changes: 1 addition & 4 deletions renderer/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,7 @@ func (m *MarkdownRenderer) Render(gvd []types.GroupVersionDetails) error {
return err
}

f, err := createOutFile(m.conf.OutputPath, "out.md")
defer f.Close()

return tmpl.ExecuteTemplate(f, mainTemplate, gvd)
return renderTemplate(tmpl, m.conf, "md", gvd)
}

func (m *MarkdownRenderer) ToFuncMap() template.FuncMap {
Expand Down
43 changes: 42 additions & 1 deletion renderer/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,55 @@ func combinedFuncMap(funcs ...funcMap) template.FuncMap {
return m
}

func createOutFile(outputPath string, defaultFileName string) (*os.File, error) {
// renderTemplate applies a given template to a set of GroupVersionDetails and writes the output to files, it supports
// two output modes as specified in the configuration: single mode or group mode.
// In single mode, all data is rendered into one output file.
// In group mode, separate files are created for each group.
func renderTemplate(tmpl *template.Template, conf *config.Config, fileExtension string, gvds []types.GroupVersionDetails) error {
switch conf.OutputMode {
case config.OutputModeSingle:
fileName := fmt.Sprintf("%s.%s", "out", fileExtension)
file, err := createOutFile(conf.OutputPath, false, fileName)
defer file.Close()
if err != nil {
return err
}

if err := tmpl.ExecuteTemplate(file, mainTemplate, gvds); err != nil {
return err
}

case config.OutputModeGroup:
for _, gvd := range gvds {
fileName := fmt.Sprintf("%s.%s", gvd.Group, fileExtension)
file, err := createOutFile(conf.OutputPath, true, fileName)
defer file.Close()
if err != nil {
return err
}

if err := tmpl.ExecuteTemplate(file, mainTemplate, []types.GroupVersionDetails{gvd}); err != nil {
return err
}
}
}

return nil
}

// createOutFile creates the file pointed to by outputPath if it does not exist, or if it exists and is a directory,
// then creates a file in the directory using the given defaultFilename. If expectedDir is true, outputPath must be an
// existing directory where defaultFileName is created.
func createOutFile(outputPath string, expectedDir bool, defaultFileName string) (*os.File, error) {
finfo, err := os.Stat(outputPath)
if err != nil && !os.IsNotExist(err) {
return nil, err
}

if finfo != nil && finfo.IsDir() {
outputPath = filepath.Join(outputPath, defaultFileName)
} else if expectedDir {
return nil, fmt.Errorf("output path must point to an existing directory")
}

return os.Create(outputPath)
Expand Down

0 comments on commit 83e2ff3

Please sign in to comment.