Skip to content

Commit

Permalink
tools: add doc generate command (#126)
Browse files Browse the repository at this point in the history
* tools: add doc generate command

* fix doc generate command unit test on windows os

* more docs and examples of kcl-doc command
  • Loading branch information
amyXia1994 authored Aug 3, 2023
1 parent 88ec03a commit be46045
Show file tree
Hide file tree
Showing 7 changed files with 353 additions and 26 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ __pycache__
profile.cov

.idea/
docs/
110 changes: 94 additions & 16 deletions cmds/kcl-go/command/cmd_doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,107 @@ package command

import (
"fmt"
"os"
"os/exec"

"github.com/urfave/cli/v2"
"kcl-lang.io/kcl-go/pkg/kclvm_runtime"
"kcl-lang.io/kcl-go/pkg/tools/doc"
)

const version = "v0.0.1"

func NewDocCmd() *cli.Command {
return &cli.Command{
Hidden: false,
SkipFlagParsing: true,
Name: "doc",
Usage: "show documentation for package or symbol",
Hidden: true,
Name: "doc",
Usage: "show documentation for package or symbol",
UsageText: `# Generate document for current package
kcl-go doc generate
# Start a local KCL document server
kcl-go doc start`,
Subcommands: []*cli.Command{
{
Name: "generate",
Usage: "generates documents from code and examples",
UsageText: `# Generate Markdown document for current package
kcl-go doc generate
# Generate Html document for current package
kcl-go doc generate --format html
# Generate Markdown document for specific package
kcl-go doc generate --file-path <package path>
# Generate Markdown document for specific package to a <target directory>
kcl-go doc generate --file-path <package path> --target <target directory>`,
Flags: []cli.Flag{
// todo: look for packages recursive
// todo: package path list
&cli.StringFlag{
Name: "file-path",
Usage: `Relative or absolute path to the KCL package root when running kcl-doc command from
outside of the KCL package root directory.
If not specified, docs of all the KCL models under the work directory will be generated.`,
},
&cli.BoolFlag{
Name: "ignore-deprecated",
Usage: "do not generate documentation for deprecated schemas",
Value: false,
},
&cli.StringFlag{
Name: "format",
Usage: "The document format to generate. Supported values: markdown, html, openapi",
Value: string(doc.Markdown),
},
&cli.StringFlag{
Name: "target",
Usage: "If not specified, the current work directory will be used. A docs/ folder will be created under the target directory",
},
},
Action: func(context *cli.Context) error {
opts := doc.GenOpts{
Path: context.String("file-path"),
IgnoreDeprecated: context.Bool("ignore-deprecated"),
Format: context.String("format"),
Target: context.String("target"),
}

genContext, err := opts.ValidateComplete()
if err != nil {
fmt.Println(fmt.Errorf("generate failed: %s", err))
}

err = genContext.GenDoc()
if err != nil {
fmt.Println(fmt.Errorf("generate failed: %s", err))
return err
} else {
fmt.Println(fmt.Sprintf("Generate Complete! Check generated docs in %s", genContext.Target))
return nil
}
},
},
{
Name: "start",
Usage: "starts a document website locally",
Action: func(context *cli.Context) error {
fmt.Println("not implemented")
return nil
},
},
},
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "version",
},
},
Action: func(c *cli.Context) error {
args := append([]string{"-m", "kclvm.tools.docs"}, c.Args().Slice()...)
cmd := exec.Command(kclvm_runtime.MustGetKclvmPath(), args...)
stdoutStderr, err := cmd.CombinedOutput()
if err != nil {
fmt.Print(string(stdoutStderr))
fmt.Println("ERR:", err)
os.Exit(1)
if c.NArg() == 0 {
_ = cli.ShowCommandHelp(c, c.Command.Name)
return nil
}
arg := c.Args().First()
if arg == "version" {
fmt.Println(version)
}
fmt.Print(string(stdoutStderr))
return nil
},
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/powerman/rpc-codec v1.2.2
github.com/qri-io/jsonpointer v0.1.1
github.com/stretchr/testify v1.8.2
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.6.0
github.com/wk8/go-ordered-map/v2 v2.1.8
google.golang.org/grpc v1.53.0
Expand Down
11 changes: 2 additions & 9 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ github.com/chai2010/protorpc v1.1.4 h1:CTtFUhzXRoeuR7FtgQ2b2vdT/KgWVpCM+sIus8zJj
github.com/chai2010/protorpc v1.1.4/go.mod h1:/wO0kiyVdu7ug8dCMrA2yDr2vLfyhsLEuzLa9J2HJ+I=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
Expand Down Expand Up @@ -39,13 +38,8 @@ github.com/qri-io/jsonpointer v0.1.1 h1:prVZBZLL6TW5vsSB9fFHFAMBLI4b0ri5vribQlTJ
github.com/qri-io/jsonpointer v0.1.1/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/urfave/cli/v2 v2.6.0 h1:yj2Drkflh8X/zUrkWlWlUjZYHyWN7WMmpVxyxXIUyv8=
github.com/urfave/cli/v2 v2.6.0/go.mod h1:oDzoM7pVwz6wHn5ogWgFUU1s4VJayeQS+aEZDqXIEJs=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
Expand All @@ -67,7 +61,6 @@ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
kcl-lang.io/kcl-artifact-go v0.5.1 h1:1OIeb1xdq72XIvd9mftBvqFJbzbEkPjGtdeiQizUFj8=
Expand Down
64 changes: 64 additions & 0 deletions pkg/tools/doc/doc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package doc

import (
"github.com/stretchr/testify/assert"
kcl "kcl-lang.io/kcl-go"
"runtime"
"strings"
"testing"
)

func TestDocRender(t *testing.T) {
tcases := [...]struct {
source *kcl.KclType
expect string
}{
{
source: &kcl.KclType{
SchemaName: "Person",
SchemaDoc: "Description of Schema Person",
Properties: map[string]*kcl.KclType{"name": {
Type: "string",
}},
Required: []string{"name"},
},
expect: `## Schema Person
Description of Schema Person
### Attributes
**name** *required*
` + "`" + `string` + "`" + `
todo: The description of the property
### Examples
todo: The example section
## Source Files
- [Person](todo: filepath)
`,
},
}

context := GenContext{
Format: Markdown,
IgnoreDeprecated: true,
}

for _, tcase := range tcases {
content, err := context.renderContent(tcase.source)
if err != nil {
t.Errorf("render failed, err: %s", err)
}
expect := tcase.expect
if runtime.GOOS == "windows" {
expect = strings.ReplaceAll(tcase.expect, "\n", "\r\n")
}
assert.Equal(t, expect, string(content), "render content mismatch")
}
}
Loading

0 comments on commit be46045

Please sign in to comment.