Skip to content

Generate documentation for command line interfaces #3816

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

Open
renancaraujo opened this issue Jul 8, 2024 · 4 comments
Open

Generate documentation for command line interfaces #3816

renancaraujo opened this issue Jul 8, 2024 · 4 comments
Labels
P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug

Comments

@renancaraujo
Copy link

Some people (like me) love publishing some command line apps on pub. Happens that often, such packages do not include a public API as code. Rather, the API is through commands and options to be executed in the terminal. Almost always using package:args.

To document such CLIs, maintainers must resource to the old ways and keep files such as the README up to date (manual work 😱).

It would be awesome if https://pub.dev/documentation/<package_name>/latest/ would also present pages with the commands available and their respective help message (often obtained via --help).

@srawlins srawlins added the type-enhancement A request for a change that isn't a bug label Jul 8, 2024
@srawlins
Copy link
Member

Cool idea. I think there could be some configuration that we could provide. Tricky to read the --help text of a script inside a package-being-documented... because you have to run the code to produce that text.

@srawlins srawlins added the P3 A lower priority bug or feature request label Jul 15, 2024
@renancaraujo
Copy link
Author

@srawlins you can obtain it programmatically if the CLI was built using package:args's CommandRunner, which keeps a tree of commands, subcommands, and options.
I did have to map that programatically to build cli_completion, so maybe dartdoc can use the same approach?

@srawlins
Copy link
Member

That's what I mean, I think. You cannot statically determine what command documentation is. You have to programmatically determine it (run the code), executing calls to addCommand etc.

@jonasfj
Copy link
Member

jonasfj commented May 2, 2025

I think this is and should be outside the scope of dartdoc, but that we could facilitate packages to provide things like this.

Some options that could alleviate these problems could be:

Option (A): Leverage {@tool ...} annotations

Today, dartdoc supports {@tool ...} annotations, where the "tool" is configured in dartdoc_options.yaml -- and the tool is essentially a command that runs as subprocess and is passed values from the {@tool ...}...{@end-tool} annotation.

I haven't tested if these {@tool ...} annotations works inside README.md, but it's not impossible.

The community could write a package similar to cli_completion that produces markdown documentation for a CLI command, and this is then invoked by the {@tool ...} annotation.

In practice, this might just be a matter of adding a hidden --markdown-help option to your CLI tool (which will print --help in a pretty markdown format), and define a dartdoc_options.yaml as follows:

dartdoc:
  tools:
    my_tool_cli_docs:
      command: ['dart', 'bin/mytool.dart', '--markdown-help']

Then where you want the documentation inserted you'd write: {@tool my_tool_cli_docs}{@end-tool}.

Downside: for security reasons {@tool} annotations don't work on pub.dev

Option (B): Write a script to update a markdown file

Another low-tech option that could work is to make a script that generates markdown documentation for the CLI options and injects/updates a markdown file.

You could have a README.md as follows:

Mypackage... bla.. bla.. bla..

<!-- BEGIN CLI DOC -->
...
<!-- END CLI DOC -->

And then have a tool in tool/update-readme.dart which:

  • Generate documentation for your CLI command
  • Injects documentation for your CLI command into README.md between <!-- BEGIN CLI DOC --> / <!-- END CLI DOC -->

This is how I generate a table of packages in my mono-repository:
https://github.com/google/dart-neats/blob/9b80400e850241a7c3bc9cba4d672393a2bab014/README.md#L16-L34

If you wanted to make it convenient for others to do this too, you could ofcourse put the update-readme.dart tool in a separate package and publish it as a package people can use (could be called something like cli_documentation). Such package could even have utilities for writing tests that ensures the documentation is kept up-to-date.


I think that (A) and (B) are decent options for now. If one day we can figure out how to do some sort of sandboxing when running {@tool ...} annotations, we could potentially support running them on pub.dev

If {@tool ...} annotations were running in a sandbox, maybe we could even build a system where tools from dependencies are automatically enabled. And things like that.

I think direct support for package:args in dartdoc would be a mistake. Some form of support for documentation pages that are automatically generated by a tool / script seems more reasonable. But to make it work on pub.dev, we'd need to run it in a security sandbox, like gVisor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

3 participants