Improve design of CLI commands structure
Reason/Context
We need to improve the design of the CLI to follow the existing common CLI's (Docker, Git, GitHubβ¦) to minimise developer's friction and helping to increase the CLI adoption.
For that reason, it would be a good idea to push this improvement in the "must-have" list of things we need for CLI v1.0
Relates to #37
Description
We would like to follow the Git CLI convention:
1. Verb-noun format: Commands follow a verb-noun format, where the verb describes the action to be performed and the noun is the object of the action. For example, 'git commit' commits changes to the local repository.
2. Single-word commands: Some commands are single words that describe the action to be performed, such as 'git status' to show the status of the current repository.
3. Options: Options follow a single-hyphen or double-hyphen format, with a full word or an abbreviation of the option name. For example, -m or --message is used to specify the commit message.
4. Arguments: Arguments are usually positional, with the first argument being the most important one. For example, 'git clone' requires the repository URL as the first argument.
5. Flags: Flags are single-letter options that modify the behaviour of a command. For example, 'git log -p' shows the patch diff for each commit.
6. Subcommands: Git has several high-level commands, each with its own set of subcommands. For example, 'git remote' is a high-level command that has subcommands like add, remove, and rename.
Proposal
Pattern
asyncapi + namespace + command
Namespace concept
Command will have namespace. A namespace provides a way to organize concepts into distinct, named scopes, which can help avoid naming conflicts and make it easier to manage our CLI at scale.
Examples of namespaces:
studiogleeconfig
Examples of commands:
asyncapi studio start
asyncapi studio deploy
asyncapi generate
Namespaces can be also nested. But we recommend to stick to a minimal level of nested namespaces.
Example of nested namespace:
config>context
Examples of commands:
asyncapi config context
Default namespace
If the namespace is omitted then the commands are executed in the default namespace.
The default namespace in that case is the current asyncapi namespace directly including its files.
Examples of commands:
asyncapi new
The command above will create a new asyncapi file.
Can we come up with a list of all the existing commands and make a list of how they would look like?
Hmmm...good point! Let me collect them so we can visualize better the potential transformations β¨
Looks interesting , I would like to work on it . where can i get a list of all the previous commands @peter-rr @fmvilas Thank You.
@SumantxD Here you can find the list with all existing CLI commands so far:
EXISTING COMMANDS
config access configs
context access context configs
add
current
list
remove
use
diff find differences between two AsyncAPI files
optimize optimize your AsyncAPI specification file
new
file create a new AsyncAPI file
glee create a new Glee project
project create a new generic project
start start a new local instance of Studio
validate validate an AsyncAPI file
convert convert Asyncapi documents older to newer versions
bundle bundle one or multiple Asyncapi documents and their references together
generate generate all kinds of stuff
fromTemplate generate whatever you want using templates compatible with AsyncAPI Generator
models generate all the typed models for the message payloads defined in the AsyncAPI file
typescript generate the models for TypeScript
csharp generate the models for C#
golang generate the models for Go
java generate the models for Java
javascript generate the models for JavaScript
dart generate the models for Dart
rust generate the models for Rust
kotlin generate the models for Kotlin
And down below you can see how these commands would look like by following the pattern proposed:
PATTERN
$ asyncapi [NAMESPACE] [COMMAND]
CANDIDATES COMMANDS
config
context
add
current
list
remove
use
file
new
validate
optimize
convert
diff
bundle
studio
start
glee
new
project
new
generator
fromTemplate
models
typescript
csharp
golang
java
javascript
dart
rust
kotlin
Hey,I would like to know more about this issue and how can I approach it
@sambhavgupta0705 @SumantxD
First we should agree on the new pattern to be implemented and then decide which commands need to be changed. So feel free to share your ideas, doubts or concerns about it π For instance, after a recent conversation with @Souvikns and @KhudaDad414 we agreed that for some commands like validate, optimize, convert, diff or bundle it makes more sense to execute them in the default namespace asyncapi, not under the namespace file as I proposed above, since those commands actually work with already existing spec files.
Fresh new ideas or different pattern proposals are pretty welcomed β€οΈ
@peter-rr
Instead of
generate:models
we can have something like
generate --models php
At the beginning we had this discussion about verb noun vs noun verb and we finally decided to follow verb + noun and namespace + noun + [verb] and https://clig.dev/.
I still think we should follow https://clig.dev/ and not Git, or any other CLI. Picking Git, or Docker or Kubectl carries a risk that decision is done purely basing on what we are used to use, what we use more often and remember.
Anyway, as stated in readme, we follow verb + noun and you also suggest verb + noun which is confusing. So what is really changing? But then in your proposal you recommend to switch from generate (verb) to generator (noun). It is not specified anywhere that namespace is verb or noun and in your proposal you recommend to change namespace generate to generator, noun followed by nouns only.
I'm not convinced for studio, glee and other new namespaces as there is just one command under.
I don't believe that with asyncapi generate fromTemplate or asyncapi new glee we are doing bad things to CLI design. Sometimes you have cases like this, like with kubectl you do kubectl get nodes or kubectl get nodes which is much better than kubectl nodes get or kubectl pods get. In their case get is a great namespace, and also is natural to write. "You want to get pods" or "You want to pod gets"?
Anyway, comparing us with Kubectl is as confusing as comparing us with Git. Thus we need our way following https://clig.dev/ and just inspire form others like we did with asyncapi config as git config and kubectl config was there and seemed common.
Is there some specific command or something you feel is not intuitive and that triggered you to do a proposal?
We need to improve the design of the CLI to follow the existing common CLI's (Docker, Git, GitHubβ¦) to minimise developer's friction and helping to increase the CLI adoption.
cause in my opinion we actually follow common CLIs π
I found this nodejs-cli-apps-best-practices hope this helps @derberg @peter-rr @Shurtu-gal @fmvilas
I still think we should follow https://clig.dev/ and not Git, or any other CLI. Picking Git, or Docker or Kubectl carries a risk that decision is done purely basing on what we are used to use, what we use more often and remember.
Yeah, I agree with this π It really makes sense in terms of "not reinventing the wheel" and trying to adapt to our needs, not just following what others did.
Is there some specific command or something you feel is not intuitive and that triggered you to do a proposal?
At this moment, I think the only command that may create confusion regarding user experience is asyncapi start since is not clear explicitly what this command is actually going to start. I feel that something like asyncapi studio would be much more intuitive for the purpose of starting a new instance of Studio, then using "studio" namespace as an exception as we are doing already with "config". WDYT? π€
the thing is that config is also an action, short for configure
Yeah, that's right π Then we could proceed to close the discussion if nobody has any suggestion or a different proposal to share.
I still think we should follow https://clig.dev/ and not Git, or any other CLI. Picking Git, or Docker or Kubectl carries a risk that decision is done purely basing on what we are used to use, what we use more often and remember.
Yeah, I agree with this π It really makes sense in terms of "not reinventing the wheel" and trying to adapt to our needs, not just following what others did.
Is there some specific command or something you feel is not intuitive and that triggered you to do a proposal?
At this moment, I think the only command that may create confusion regarding user experience is
asyncapi startsince is not clear explicitly what this command is actually going to start. I feel that something likeasyncapi studiowould be much more intuitive for the purpose of starting a new instance of Studio, then using "studio" namespace as an exception as we are doing already with "config". WDYT? π€
yes we can change the name to the studio.i would like to work on this.
This issue has been automatically marked as stale because it has not had recent activity :sleeping:
It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.
There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.
Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.
Thank you for your patience :heart:
Still relevant
This issue has been automatically marked as stale because it has not had recent activity :sleeping:
It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.
There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.
Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.
Thank you for your patience :heart:
Still relevant
Hello there π @peter-rr @Amzani
If it's fine with you, I would be glad to work on this issue under the Bounty Program, 2024-Q3 as this is a potential issue for the Program.
-
I have worked on multiple issues in CLI https://github.com/asyncapi/cli/pulls?q=is%3Apr+is%3Aclosed+author%3AAayushSaini101 and created a new command from scratch https://github.com/asyncapi/cli/pull/1413.
-
Past Completed Bounty Issues:
- https://github.com/asyncapi/generator/pull/1061
- https://github.com/asyncapi/community/pull/1120
-
Bounty Issue submission link for ease of access. Thanks! π
@peter-rr @Shurtu-gal I'm not sure what kind of improvements you suggest here ?
@Amzani with the recent haul and the improvement in cli now. I suppose this can be closed.
Ref: https://github.com/asyncapi/cli/issues/551#issuecomment-1613823423
Agree π I think the only change we could introduce in the future regarding commands structure depends on the evolution of features from studio and integration of API in CLI as @Amzani mentioned in https://github.com/asyncapi/cli/issues/1090#issuecomment-2145056759