Skip to content
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

Add JSON (machine readable) status output. #1210

Open
asford opened this issue Mar 26, 2024 · 3 comments
Open

Add JSON (machine readable) status output. #1210

asford opened this issue Mar 26, 2024 · 3 comments
Assignees
Labels
feature New feature or request status Relates to how status is rendered

Comments

@asford
Copy link
Contributor

asford commented Mar 26, 2024

Overview

git machete is a mega-useful workflow tool,
partially because is nicely separates the current branch state (the git repo state) from a declared target state (the machete config).

It'd be real useful to be able to overlay workflow helpers or lightweight views onto git machete;
which would be much easier if there was an easily-parsed output format.

Most interactions with machete can be represented as:

  1. Call git machete status to get the branch tree and branch status information.
  2. Inspect the branch tree and (maybe) current repo/remote state to know what to do.
  3. Invoke some git or git machete command to do the needful.

Therefor, we can implement most integrations by only adding output git machete status.
Semi-obviously, this should just be a json form of the status output.

In my experience, this best represented as an adjacency based structure akin to the output of the git machete show commands.
In dataclasses:

# single-character status, equivalent to ASCII output
class Status(str, enum.Enum):
    IN_SYNC = "o"
    MERGED = "m"
    OUT_OF_SYNC = "x"
    WEIRD_FORK = "?"

@attr.define
class MacheteConfig:
    # primary data from status - must have to reconstruct full status
    # all tracked branches
    tracked: list[str]
    
    # branch to parent mapping
    # a branch is only present if it's non-root and has a parent
    up: dict[str, str]

    # branch status
    status: dict[str, Status]
    
    # branch custom annotations
    anno: dict[str, str]

    # derived data from status - useful views but not strictly needed
    current: str | None
    roots: list[str] # all roots in the tree
    non_root: list[str] # all non-roots in the tree

    # show output, keyed by branch
    down: dict[str, list[str]]
    first: dict[str, str]
    last: dict[str, str]
    next: dict[str, str]
    prev: dict[str, str]
    root: dict[str, str]

This can be semi-trivially generated during machete's current status implementation.
The easiest implementation might be to just add a --json flag to git machete status?

Happy to open a PR for comments if you're open to it.

@PawelLipski
Copy link
Collaborator

Wowow that's a novel idea... could you elaborate on how what kind of integrations do you consider? so far I'd rather expected that the tool is only ever used by human users directly, and not by scripts (other than maybe some scripts like git hooks or shell completion for git-machete itself, hence git-machete defines some plumbing commands of its own).

@asford
Copy link
Contributor Author

asford commented Mar 26, 2024

Honestly, the simplest case is just github/gitlab integration.

We have an internal machete-to-github PR management tool that wraps machete.
It slightly pre-dates the in-built integration in machete and it's about ~%60 identical to what y'all have implemented.

However, as we all know, PR flows are ... highly opinionated ... matters;
there differences in behavior between our tool and your upstream.
E.g. the behavior wrt comment updates, how this are updated on push, etc.
Neither implementation is "correct", just different colors of the bike shed.
Right now our tool reaches into machete's internals to populate the datastructure above, but this is obviously undesirable.

Having a plumbing-level command for status output would let us easily integrate with machete;
defer to the builtins when we can, but add in our own weird commenting and workflow flavor on top.
Status is, as you know, one of the immensely tricky problems to solve because you're doing reflog introspection. 😨

In slightly-less-simple cases, we have actions workflows built on machete that do things like auto-merge of stack machete trees.
These workflows run on github and benefit immensely from have verbose status information about a tree.
For example, we would slide-out and push in a workflow if-and-only-if the (root, merged, child) branches are an up-to-date machete stack, and the root is main and the parent and child branch are tagged.

In the way-far-afield-future I could imagine a status-json interface supporting a VSCode extension for machete.
This would only require that the extension call machete status and then do the needful rendering of a status tree.
Various update commands could just be simple dispatches down to appropriate machete and/or git commands.

@PawelLipski
Copy link
Collaborator

PawelLipski commented Mar 27, 2024

I wasn't aware you've got such complicated machinery on top of git-machete 😯 sure, feel free to open the PR! I'm currently busy with GitLab integration btw (#1189), this is gonna take me while (even though the API is strikingly similar to GitHub's) :/

Also, as you probably know, we've got an IntelliJ plugin that covers most of the features of CLI (even traverse; but notably, GitHub integration is still missing). There's unfortunately no easy way to quickly port it to a VSCode extension :/

@PawelLipski PawelLipski added this to the v3.25.0 milestone Mar 27, 2024
@PawelLipski PawelLipski added feature New feature or request status Relates to how status is rendered labels Mar 27, 2024
@PawelLipski PawelLipski removed this from the v3.25.0 milestone Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request status Relates to how status is rendered
Projects
None yet
Development

No branches or pull requests

2 participants