Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Prevent Manually Added Content in CLI Docs to be Overwritten #9125

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 33 additions & 4 deletions docs/pages/project/contributing/contributing-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,7 @@ Example:```
mesheryctl system start

// To create a new context for in-cluster Kubernetes deployments and set the new context as your current-context
mesheryctl system context create k8s -p kubernetes -s
```,
mesheryctl system context create k8s -p kubernetes -s```,
Annotations: linkScreenshot,
...{% endcapture %}

Expand All @@ -186,8 +185,7 @@ Example:```
mesheryctl pattern apply -f [file | URL]

// deploy a saved pattern
mesheryctl pattern apply [pattern-name]
```,
mesheryctl pattern apply [pattern-name]```,
Annotations: linkDocPatternApply,
...
{% endcapture %}
Expand All @@ -202,6 +200,37 @@ Though the command page is generated automatically by the Cobra CLI library, the
- [cmds.yml](https://github.com/meshery/meshery/blob/master/docs/_data/mesheryctlcommands/cmds.yml) - The YAML file containing the data about the commands
- [mesheryctl-commands.md](https://github.com/meshery/meshery/blob/master/docs/pages/reference/mesheryctl-commands.md) - The markdown page of the command reference documentation

## Preserving Manually Added Documentation

`mesheryctl` uses Cobra CLI library and GitHub Actions to automate the generation of command documentation pages. On occasion, additional documentation beyond that included in the `mesheryctl` Golang files is ideal to capture and include in the CLI reference pages. Contributors are encouraged to add more usage examples, screenshots to any of the CLI reference pages. To protect any manually added content and ensure it remains intact after regeneration, create a separate Jekyll `include` file. Follow file naming scheme outlined below:

If your mesheryctl docs end like this, add the include tag at the end of the file. An example is given below

{% capture code_content %}
Example:```
// apply a pattern file
mesheryctl pattern apply -f [file | URL]

// deploy a saved pattern
mesheryctl pattern apply [pattern-name]```,
Annotations: linkDocPatternApply,
...
<pre class='codeblock-pre'>
<div class='codeblock'>
--config string path to config file (default "/home/runner/.meshery/config.yaml")
-t, --token string Path to token file default from current context
-v, --verbose verbose output

</div>
</pre>
{% raw %}{% include permalink-of-file %}{% endraw %}
{% endcapture %}
{% include code.html code=code_content %}


This format should reference an external file where your manual changes are stored. These files should be present at the folder path (`_includes/mesheryctl/`). Any content added using this method will not be altered during the documentation generation process, but instead will be included post-auto doc generation. When making new changes or additions, understand that these additional details are positioned at the end their given CLI reference page, so bear this in mind as you organize and present your additional command details.


### References

- [jarcoal/httpmock](https://github.com/jarcoal/httpmock)
Expand Down
43 changes: 40 additions & 3 deletions mesheryctl/doc/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -133,7 +134,7 @@ func printOptions(buf *bytes.Buffer, cmd *cobra.Command) error {
}

// GenMarkdownCustom creates custom markdown output.
func GenMarkdownCustom(cmd *cobra.Command, w io.Writer) error {
func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, manuallyAddedContent map[int]string) error {
// InitDefaultHelpCmd add the help command to the command tree.
cmd.InitDefaultHelpCmd()
// InitDefaultHelpFlag add the help flag to the command tree.
Expand Down Expand Up @@ -176,6 +177,7 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer) error {
buf.WriteString(strings.Replace(examples[i], "// ", "", -1) + "\n")
} else {
// Code Block Line

buf.WriteString(fmt.Sprintf("<pre class='codeblock-pre'>\n<div class='codeblock'>\n%s\n\n</div>\n</pre> \n\n", examples[i]))
}
}
Expand All @@ -197,6 +199,13 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer) error {
buf.WriteString("\n\n")
}

if len(manuallyAddedContent) > 0 {
for _, content := range manuallyAddedContent {
buf.WriteString("\n")
buf.WriteString("{% include " + content + " %}" + "\n")
}
}

if hasSeeAlso(cmd) {
buf.WriteString("## See Also\n\n")
if cmd.HasParent() {
Expand All @@ -206,9 +215,10 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer) error {
}
})
}
buf.WriteString("Go back to [command reference index](/reference/mesheryctl/) ")
buf.WriteString("Go back to [command reference index](/reference/mesheryctl/), if you want to add content manually to the CLI documentation, please refer to the [instruction](/project/contributing/contributing-cli#preserving-manually-added-documentation) for guidance.")
buf.WriteString("\n")
}

if !cmd.DisableAutoGenTag {
buf.WriteString("###### Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "\n")
}
Expand Down Expand Up @@ -243,6 +253,9 @@ func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHa

basename := strings.Replace(cmd.CommandPath(), " ", "-", -1) + ".md"
filename := filepath.Join(dir, basename)

manuallyAddedContent, _ := getManuallyAddedContentMap(filename)

f, err := os.Create(filename)
if err != nil {
return err
Expand All @@ -254,13 +267,37 @@ func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHa
return err
}

err = GenMarkdownCustom(cmd, f)
err = GenMarkdownCustom(cmd, f, manuallyAddedContent)
if err != nil {
return err
}
return nil
}

func getManuallyAddedContentMap(filename string) (map[int]string, error) {
manuallyAddedContentMap := make(map[int]string)

_, err := os.Stat(filename)
if err != nil {
return manuallyAddedContentMap, err
}

existingContent, err := os.ReadFile(filename)
if err != nil {
return manuallyAddedContentMap, err
}

content := string(existingContent)

includePattern := regexp.MustCompile(`\{\%\s*include\s+([^%]+)\s+\%\}`)
includeMatches := includePattern.FindAllStringSubmatch(content, -1)
for i, match := range includeMatches {
// Store the include content in the map with order as the key
manuallyAddedContentMap[i] = strings.TrimSpace(match[1])
}
return manuallyAddedContentMap, nil
}

// GenYamlTreeCustom creates custom yaml output.
func GenYamlTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
for _, c := range cmd.Commands() {
Expand Down
15 changes: 14 additions & 1 deletion mesheryctl/doc/doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ var _ = Describe("Tests for Doc", func() {

// add Example for cmd for test
cmd.Example = "test_example"
manuallyAddedContent, _ := getManuallyAddedContentMap("test.md")

// io.Writer
buf := &bytes.Buffer{}
// call GenMarkdownCustom
err := GenMarkdownCustom(cmd, buf)
err := GenMarkdownCustom(cmd, buf, manuallyAddedContent)
// check if err is nil
Expect(err).To(BeNil())
// check if buf is not empty
Expand Down Expand Up @@ -121,6 +122,18 @@ var _ = Describe("Tests for Doc", func() {
})
})

//Test getManuallyAddedContentMap
Context("Test getManuallyAddedContentMap function", func() {
It("should return nil", func() {

// call getManuallyAddedContentMap
_, err := getManuallyAddedContentMap("test.md")

// check if err is nil
Expect(err).To(BeNil())
})
})

//TestGenYamlCustom is the test for GenYamlCustom function
Context("Test GenYamlCustom function", func() {
It("should return specific sub-strings", func() {
Expand Down