r3bl-org/r3bl-open-core

[tuify][giti] ideas for making our Rust CLI / tuify git buddy called `giti`

Closed this issue · 7 comments

Bin target in r3bl_tuify/Cargo.toml

We have a bin target called giti here:

https://github.com/r3bl-org/r3bl-open-core/blob/main/tuify/src/bin/giti.rs#L65

image

Why

git is notoriously difficult to use. giti aims to simplify some of the git workflows by using r3bl_tuify. One example of this is the git branch -D workflow, when you have many local branches to choose from. You have to run the git branch -D on each one of the branches, which is tedious.

Better UX

Instead we can use r3bl_tuify to allow the user to select multiple branches and then perform an operation on them (like delete, or whatever else). The UX of this command still needs to be flushed out.

"Shell out" to git executable and run git branch commands

Here's more information on the git branch command and how we can pass arguments to it, so that we can output data from the command in a way that we can use in giti. We will "shell out" from the binary target to run git executable, since this is more of a demo of what tuify can do.

Here's the Rust API for that: https://doc.rust-lang.org/std/process/struct.Command.html
For now, we are ok shelling out, despite its limitations. For a more serious implementation, we can look at https://github.com/Byron/gitoxide so we don't have to shell out to git binary on the user's computer.

Here are some commands to get the output from git branch command in a way that is easy for our Rust program to use:

  • git branch --format '%(refname:short)' --show-current
  • git branch --format '%(refname:short)'

image

git branch --format is not a valid command. The git branch command is used to list, create, or delete branches in a Git repository. However, you can use git for-each-ref command to format the output of git branch command.

Here's an example of how to use git for-each-ref to output the branch name, author, and date for all branches:
git for-each-ref --format='%(refname:short) %(authorname) %(authordate)' refs/heads/

In this example, %(refname:short) is the placeholder for the branch name, %(authorname) is the placeholder for the author name, and %(authordate) is the placeholder for the author date.

References and guides

You can find a list of all available placeholders in the git for-each-ref documentation.

Tutorial on how to use clap & tuify:

Video w/ ideas on "type driven" API design:

Other projects that were started a long time ago in this vein

@NadiaIdris Just added this idea here as an issue; didn't know if it is better as an issue or github discussion.

@Harshil-Jani FYI - more info on giti

image

Potentially have 3 options to choose from when user chooses a branch to delete:

  1. Yes, delete branch
  2. No, exit program
  3. Go back and choose another branch to delete

Edit the code to delete multiple branches (Multi-Selection).

select_from_list() method returns Vec<String> for Both SelectionMode's, Single and Multiple. But In case of Single it looks much cleaner to have String datatype returned from the API

image

@Harshil-Jani @NadiaIdris That's a great idea. Simple but useful developer experience / usability / ergonomic improvement for the API.

@NadiaIdris @Harshil-Jani I don't think using lib-git2 is a path we want to go down (since it is a wrapper around a C lib, which has to be installed on the user's computer already; and there's a higher chance a user of this app already has git installed, but not libgit2-dev on linux for eg).

It might just be better to use process exec and "shell out" to execute git commands directly and use stdin and stdout to communicate w/ these git subcommands.

Alternatively we can use something called gitoxide. It is git but rewritten in Rust 100%. Here's an example of using gitoxide as a library (not binaries)
Byron/gitoxide#1020

Here's an example of how the git clone subcommand is implemented in Rust code, w/out using process exec to shell out:

https://github.com/Byron/gitoxide/blob/072ee32f693a31161cd6a843da6582d13efbb20b/gitoxide-core/src/repository/clone.rs#L75-L84

Note that gitoxide comes w/ 2 binaries. The aim of this project is to be totally git compatible, but it is implemented in Rust and not C.

https://asciinema.org/a/14V8v3OKKYvDkUDkRFiMDsCNg

Command to run this:

cd tuify ; ./run.nu install-giti ; giti branch -c delete