Contributing to Meshery CLI

mesheryctl is written in Golang or the Go Programming Language. For development use Go version 1.23+. mesheryctl uses the Cobra framework. A good first-step towards contributing to mesheryctl would be to familiarise yourself with the Cobra concepts. For manipulating config files, mesheryctl uses Viper.

Meshery CLI Reference Documents

Designing Commands

The Meshery CLI Style Guide outlines the process by which new commands are designed and contains a collection of principles and conventions that need to be followed while designing mesheryctl commands. mesheryctl might be the interface that the users first have with Meshery. As such, mesheryctl needs to provide a great UX.

Building CLI

The /mesheryctl folder contains the complete code for mesheryctl. Fork and clone the Meshery repo. cd mesheryctl to change directory mesheryctl’s source. After making changes, run make in the mesheryctl folder to build the binary. You can then use the binary by, say, ./mesheryctl system start.

Understand Model and Configuration Data

A central struct is maintained in the mesheryctl/internal/cli/root/config/config.go file. These are updated and should be used for getting the Meshery configuration.

Updates to this central struct is made through updates in Context with setter functions. The changes made in this central struct are reflected back in the Meshery configuration file (.meshery/config.yaml).

Logging

For logs, mesheryctl uses Logrus. Going through the docs and understanding the different log-levels will help a lot.

Documenting

The documentation pages for mesheryctl reference are made with the help of the Cobra Golang framework and use of GitHub Actions. The Meshery CLI Reference is autogenerated based on docs sections in each of mesheryctl’s Golang files. Meshery CLI Reference pages are updated each time a change to its respective mesheryctl Golang file is merged into the project’s master branch. This approach to documentation facilitates a single source of truth for CLI syntax and command behavior, which results in higher quality reference and a reduction in the toil involved in keeping documentation up-to-date. To contribute to the Meshery CLI Reference, follow these steps:

  • Go to the required command file in which the documentation has to be created/updated (mainly under /mesheryctl/internal/cli/root/…)
  • Then, edit the Cobra macro variables present in the each file. An example is given below for reference.
var startCmd = &cobra.Command{ Use: "start", Short: "Start Meshery", Long: 'Start Meshery and each of its components.', Args: cobra.NoArgs, Example:``` // Start meshery 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```, Annotations: linkScreenshot, ...

The variables present in above sample will be used in creating the doc pages for the specific command

Also, if the screenshot is present in the command, an Annotation macro variable (of map[string]string type) containing the link and the caption has to be added at the bottom of the Examples field in the command file. The image file has to be included in the docs/assets folder in PNG format. The screenshot field is given for reference below

var linkDocPatternApply = map[string]string{ "link": "![pattern-apply-usage](/assets/img/mesheryctl/patternApply.png)", "caption": "Usage of mesheryctl design apply", } ... Example:``` // apply a pattern file mesheryctl design apply -f [file | URL] // deploy a saved design mesheryctl design apply [design-name]```, Annotations: linkDocPatternApply, ...

Avoid documentation being overwritten

It is advised not to modify the changes in `docs` folder, rather should be done in `mesheryctl` folder as the changes will get overwritten by the CI workflows.

Adding New/Removing Existing commands in the reference index

Though the command page is generated automatically by the Cobra CLI library, there are chances where the command does not appear in the reference index page. In such cases, the command details must be manually added to the reference index YAML file. This is generally done by editing the below two files:

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

Example:``` // apply a pattern file mesheryctl design apply -f [file | URL] // deploy a saved design mesheryctl design apply [design-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> {% include permalink-of-file %}

Quality

Linting

mesheryctl uses golangci-lint. See the .github/workflow/ci.yaml for syntax used during Meshery’s build process.

Testing

Key Test Writing Principles

The following key principles should be taken to mind when writing tests:

  1. Golang’s standard library will be used to write tests.
  2. The tests should cover all possible use cases and not just the happy paths.
  3. Integration tests should contain the keyword β€œIntegration” in the title and should be marked to be skipped under unit testing. (See below)
  4. Fixtures are mock/raw data to use(for e.g. API response to mock an HTTP call).
  5. Testdata is the expected response of mesheryctl commands or functions.
  6. The mock data and the expected responses are stored in the golden files.
  7. Table formatted tests are performed on functions and commands.
  8. mesheryctl/pkg/utils/fixtures/validate.version.github.golden file needs to be updated regularly.
  9. The version in utils.NewTestHelper() should be updated regularly.
  10. Golden files should be updated synchronously as API responses, mesheryctl outputs are updated.

References

Unit Tests

Unit tests and integration tests are essential to make each mesheryctl release robust and of high quality. Below you will find guidelines to write unit tests and integration tests and examples of how they are implemented in mesheryctl.

Unit test code coverage reports can be found in the CodeCov logs. Note: GitHub login may be required for access.

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.

Integration Tests

Marking ingtegration tests under unit tests

Since there is no straightforward way to mark unit tests and integration tests differently. Here we use the --short flag while running tests to differentiate between unit tests and integration tests.

func TestPreflightCmdIntegration(t *testing.T) { // skipping this integration test with --short flag if testing.Short() { t.Skip("skipping integration test") } }

In the above code sample, the test is marked with β€œIntegration” in the title and if a --short flag is passed with the command, this test is skipped.

End-to-end Tests

End-to-end testing of mesheryctl uses the Bash Automated Testing System (BATS) framework to define and execute CLI tests. See Contributing to Meshery CLI End-to-End Tests

Running tests in GitHub workflows

Unit tests

go test --short ./... -race -coverprofile=coverage.txt -covermode=atomic

Integration tests

go test -run Integration ./... -race -coverprofile=coverage.txt -covermode=atomic

To update golden files with the test output use the --update flag:

var update = flag.Bool("update", false, "update golden files")

End-to-end Tests

End-to-end testing of mesheryctl uses the Bash Automated Testing System (BATS) framework to define and execute CLI tests. See Contributing to Meshery CLI End-to-End Tests

Suggested Reading