Skip to content
Merged
104 changes: 104 additions & 0 deletions cmd/stl-docs/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

package main

import (
"context"
"fmt"
"log"
"os"

"github.com/stainless-api/stainless-api-cli/pkg/cmd"
docs "github.com/urfave/cli-docs/v3"

"github.com/urfave/cli/v3"
)

func main() {
app := &cli.Command{
Name: "stl-docs",
Usage: "Generate STL documentation in manpage and/or markdown formats",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "manpage",
Usage: "generate manpage documentation `FILE`",
Value: "stl.1",
},
&cli.StringFlag{
Name: "markdown",
Usage: "generate markdown documentation `FILE`",
Value: "usage.md",
},
},
Action: generateDocs,
}

if err := app.Run(context.Background(), os.Args); err != nil {
log.Fatal(err)
}
}

func generateDocs(ctx context.Context, c *cli.Command) error {
manpageRequested := c.IsSet("manpage")
markdownRequested := c.IsSet("markdown")

if !manpageRequested && !markdownRequested {
return cli.ShowAppHelp(c)
}

if manpageRequested {
if err := generateManpage(c.String("manpage")); err != nil {
return fmt.Errorf("failed to generate manpage: %w", err)
}
}

if markdownRequested {
if err := generateMarkdown(c.String("markdown")); err != nil {
return fmt.Errorf("failed to generate markdown: %w", err)
}
}

return nil
}

func generateManpage(filename string) error {
fmt.Printf("Generating manpage: %s\n", filename)

app := cmd.Command

manpage, err := docs.ToMan(app)
if err != nil {
return err
}

file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
if _, err := file.WriteString(manpage); err != nil {
panic(err)
}
return nil
}

func generateMarkdown(filename string) error {
fmt.Printf("Generating markdown: %s\n", filename)

app := cmd.Command

md, err := docs.ToMarkdown(app)
if err != nil {
return err
}

file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
if _, err := file.WriteString("# Stainless CLI\n\n" + md); err != nil {
return err
}
return nil
}
2 changes: 2 additions & 0 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ stl builds create --branch <branch>`,

&devCommand,

&lintCommand,

{
Name: "@manpages",
Usage: "Generate documentation for 'man'",
Expand Down
62 changes: 62 additions & 0 deletions pkg/cmd/configwatcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package cmd

import (
"context"
"fmt"
"os"
"time"

"github.com/urfave/cli/v3"
)

type configChangedEvent struct{}

func waitTillConfigChanges(ctx context.Context, cmd *cli.Command, cc *apiCommandContext) error {
openapiSpecPath := cc.workspaceConfig.OpenAPISpec
if cmd.IsSet("openapi-spec") {
openapiSpecPath = cmd.String("openapi-spec")
}
stainlessConfigPath := cc.workspaceConfig.StainlessConfig
if cmd.IsSet("stainless-config") {
stainlessConfigPath = cmd.String("stainless-config")
}

// Get initial file modification times
openapiSpecInfo, err := os.Stat(openapiSpecPath)
if err != nil {
return fmt.Errorf("failed to get file info for %s: %v", openapiSpecPath, err)
}
openapiSpecModTime := openapiSpecInfo.ModTime()

stainlessConfigInfo, err := os.Stat(stainlessConfigPath)
if err != nil {
return fmt.Errorf("failed to get file info for %s: %v", stainlessConfigPath, err)
}
stainlessConfigModTime := stainlessConfigInfo.ModTime()

// Poll for file changes every 250ms
ticker := time.NewTicker(250 * time.Millisecond)
defer ticker.Stop()

for {
select {
case <-ticker.C:
// Check OpenAPI spec file
if info, err := os.Stat(openapiSpecPath); err == nil {
if info.ModTime().After(openapiSpecModTime) {
return nil
}
}

// Check Stainless config file
if info, err := os.Stat(stainlessConfigPath); err == nil {
if info.ModTime().After(stainlessConfigModTime) {
return nil
}
}

case <-ctx.Done():
return ctx.Err()
}
}
}
Loading