CLI namespace revamp

Labels: area/cli lifecycle/rotten

Timeline

Michael Muré (MichaelMure) opened (edited)

I've been thinking about dropping out of the git porcelain CLI integration (meaning that git bug xxx would stop working, in favor of directly using foo xxx). This integration is fun but actually doesn't bring much positive to the table. It does though bring possible confusion and, more importantly, way longer commands to type.

Additionally, when future new entities get added (say, pull-requests or config), we'll need to move all bug related command to their own namespace. That will make the commands even longer and repetitive (git bug bug add).

I've been thinking about the following organization:

IDENTITY
    gb user [USER-ID] [flags]
    gb user adopt USER-ID
    gb user create
    gb user ls [flags]

BUG
    gb bug add [flags]
    gb bug comment [ID]
    gb bug comment add [ID] [flags]
    gb bug label [ID]
    gb bug label add [ID] LABEL...
    gb bug label ls
    gb bug label rm [ID] LABEL...
    gb bug ls [QUERY] [flags]
    gb bug ls-id [PREFIX]
    gb bug rm ID
    gb bug show [ID] [flags]
    gb bug status [ID]
    gb bug status close [ID]
    gb bug status open [ID]
    gb bug title [ID]
    gb bug title edit [ID] [flags]

    gb bug select ID
    gb bug deselect    

PR
    gb pr add
    gb pr show
    gb pr status
    ...

    gb pr select ID
    gb pr deselect    

BRIDGE
    gb bridge
    gb bridge auth
    gb bridge auth add-token [TOKEN] [flags]
    gb bridge auth rm ID
    gb bridge auth show
    gb bridge configure [flags]
    gb bridge pull [NAME] [flags]
    gb bridge push [NAME]
    gb bridge rm NAME

REMOTE
    gb pull [REMOTE]
    gb push [REMOTE]

UIs
    gb termui
    gb webui [flags]

UTILITY
    gb commands [flags]
    gb version [flags]

As for the name of the binary, I've been thinking about gb, but I'm open to suggestion. At the end of the day, it might not be that important as users can rename the binary as they want, or make an alias.

Michael Muré (MichaelMure) added label area/cli

Sascha (GlancingMind) commented (edited)

:+1: from me. I would also propose a slightly different version. Currently the call format is Binary - Entity - Operation E.g. gb bug add (specific args). Another option would be to use Binary - Operation - Entity. E.g. the UI could then look like this.

  • gb show [ID] or Path [user, bug, comment, bridge, pr] (specific filter)
  • gb list [ID] or Path [user, bug, comment, label, bridge, pr] (specific filter)
  • gb add [user, bug, comment, label, bridge, pr] (specific args)
  • gb edit [ID] or Path [user, bug, comment, label, bridge, pr] (specific args)
  • gb pull (bridgename)
  • gb push (bridgename)
  • gb launch [termui, webui]
  • gb version
  • gb commands
  • gb configure

This could also be reduced to:

  • gb show [ID] or Path [user, bug, comment, label, bridge, pr, terminalui, webui] (specific filters/args)
    • ID or Path could also be left out, then a listing will be performed of all (sub-)catergories.
  • gb add [user, bug, comment, label, bridge, pr] (specific args)
  • gb edit [ID] or Path [user, bug, comment, label, bridge, pr, config] (specific args)
  • gb sync --only=[pull/push]
  • gb version
  • gb list [ID] or Path [user, bug, comment, label, bridge, pr] (specific filter) see gb show
  • gb pull (bridgename) see gb sync
  • gb push (bridgename) see gb sync - gb launch [termui, webui] see gb show - gb commands just invoke gb without anything or -h, --help
  • gb configure see gb edit

Besides, with Path I mean something like git does. git config user.name. user.name would be the path.

Not sure, how extensible or complex shell completion might become with this. Just wanted to point it out. Considering gb bridge rm NAME seems to be nicer than gb edit bridge --remove

Michael Muré (MichaelMure) commented

@GlancingMind what's your proposal?

Sascha (GlancingMind) commented

Accidentally hit comment without everything written. :)

Sascha (GlancingMind) commented (edited)

@MichaelMure Shortly before falling asleep yesterday, I got another idea. It might be possible to keep the git porcelain CLI and support new entities like PR. Just treat the problem in the UNIX way. E.g. every entity/context will be solved in a separate binary. E.g.

  • git bug -> bug binary
  • git pr -> pr binary
  • git identity -> identity binary ...

This would require to extract the repository logic into a library, which will then be used by all the specific programs. So the repository will be only the persistence layer with "contexts". Kinda like a domain specific database library. Or the library defines an API by which the binaries can interact with each other. E.g. a merged PR, closes a specific issue. This would allow to implement every binary without depending them on a specific communication technology. E.g. the "bug binary" will only call the "BugAdd" command and the "repo library" would then communicate over RabbitMQ or by setting some values in the git repository with the other binaries.

Either way, the git porcelain CLI integration could be kept, as their are multiple binaries for each entity.

Just noticed, that I'm describing a SoA/Microservice/Event-driven architecture.

Sascha (GlancingMind) commented (edited)

Just my two cents on seeing the progress over at PR #870.

Maybe a Poll would yield more user feedback then this old issue. :shrug:

Personally, I think it would be fine to break the ties with the git integration. Considering that related tools seem to ignore such an integration - except for git-appraise? Therefore it might be possible, that most users don't have a strong preference about it. And then there is the possibility of future name collisions... (hopefully I'm not mistaken something here :sweat_smile:).

Also, if the git-integration is still wanted, an optional dedicated "git <-> git-bug"-wrapper could be introduced. Moving the complexity out of git-bug.

Michael Muré (MichaelMure) commented

I happen to have worked on this recently: https://github.com/MichaelMure/git-bug/tree/cli-reorg

The main goal was to make space for new entities (in that case board), which means moving all bug related commands to a new bug root command, but I also ended up reorganizing the CLI to be uniform, following these conventions:

CLI commands should consistently follow this pattern:

xxx                 --> list xxx things if list, otherwise show one
xxx new             --> create thing
xxx rm              --> delete thing
xxx show ID         --> show one
xxx show            --> show one with "select" implied ID
xxx yyy             --> action commands for that thing, or subcommand
xxx select|deselect --> select/deselect implied ID

This is the result:

git-bug
git-bug bridge
git-bug bridge auth
git-bug bridge auth add-token [TOKEN] [flags]
git-bug bridge auth rm BRIDGE_ID
git-bug bridge auth show
git-bug bridge new [flags]
git-bug bridge pull [NAME] [flags]
git-bug bridge push [NAME]
git-bug bridge rm NAME
git-bug bug [QUERY] [flags]
git-bug bug comment [BUG_ID]
git-bug bug comment edit [COMMENT_ID] [flags]
git-bug bug comment new [BUG_ID] [flags]
git-bug bug deselect
git-bug bug label [BUG_ID]
git-bug bug label new [BUG_ID] LABEL...
git-bug bug label rm [BUG_ID] LABEL...
git-bug bug new [flags]
git-bug bug rm BUG_ID
git-bug bug select BUG_ID
git-bug bug show [BUG_ID] [flags]
git-bug bug status [BUG_ID]
git-bug bug status close [BUG_ID]
git-bug bug status open [BUG_ID]
git-bug bug title [BUG_ID]
git-bug bug title edit [BUG_ID] [flags]
git-bug commands [flags]
git-bug label
git-bug pull [REMOTE]
git-bug push [REMOTE]
git-bug termui
git-bug user [flags]
git-bug user adopt USER_ID
git-bug user new [flags]
git-bug user user show [USER_ID] [flags]
git-bug version [flags]
git-bug webui [flags]
./git-bug --help
git-bug is a bug tracker embedded in git.

git-bug use git objects to store the bug tracking separated from the files
history. As bugs are regular git objects, they can be pushed and pulled from/to
the same git remote you are already using to collaborate with other people.

Usage:
  git-bug [flags]
  git-bug [command]

Entities
  bug         List bugs
  label       List valid labels
  user        List identities

User interfaces
  termui      Launch the terminal UI
  webui       Launch the web UI

Interaction with the outside world
  bridge      List bridges to other bug trackers
  pull        Pull updates from a git remote
  push        Push updates to a git remote

Additional Commands:
  commands    Display available commands.
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  version     Show git-bug version information

Flags:
  -h, --help   help for git-bug

Use "git-bug [command] --help" for more information about a command.

Now ... the remaining conundrum is whether or not to integrate as git subcommands. As you can see in the previous listing, integrating those commands within git range from useful/non-colliding (bug, user, label) to confusing (commands, completion, termui, webui, bridge), to downright colliding (help, version, push, pull).

At this point I'm kinda leaning to ship those commands in a separate binary (gb bug the name is debatable, can't be git-bug though), and have an optional subset of shell wrapper (git-bug --> gb bug $@, git-user --> gb user $@) to integrate only the most useful and non-confusing commands.

It's not a prefect plan though and does feel a bit half-assed. Additionally, it does not solve the colliding problem of push/pull, which are pretty important commands for git-bug.

Sascha (GlancingMind) commented

Additionally, it does not solve the colliding problem of push/pull, which are pretty important commands for git-bug.

What if we rename push/pull to publish/load? Grouping them into one command. Something like sync or update?

E.g.

gb update # Pushes to and pulls from default remote
gb update --all  [adr] # Pushes to and pulls from given remote
gb update --from [adr] # Pulls from remote
gb update --remote [adr] # Pushes to remote

github-actions (github-actions) added label lifecycle/stale

github-actions (github-actions) added label lifecycle/rotten

github-actions (github-actions) removed label lifecycle/stale

sudoforge removed label lifecycle/dormant

Waldir Pimenta (waldyrious) commented (edited)

I'm puzzled as to why git-bug user user show [USER_ID] [flags] was chosen instead of simply git-bug user show [USER_ID] [flags]. In other words, why is there a user sub-subcommand of the user subcommand, especially if it only has one single child command (show)? The double user user seems quite awkward, and also seems to break the pattern from cli-convention.md.

Was it an overlook, or was that decision deliberate and I'm missing something?

Waldir Pimenta (waldyrious) commented (edited)

Actually, I stand corrected: the command is indeed git-bug user show [USER_ID], and in fact trying to do git bug user user show [USER_ID] results in an error:

Error: only one identity can be displayed at a time

So this seems to be just a documentation error :) I'll see if I can submit a fix.