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

Tab completion for buf curl #2044

Open
torkelrogstad opened this issue May 4, 2023 · 0 comments
Open

Tab completion for buf curl #2044

torkelrogstad opened this issue May 4, 2023 · 0 comments
Labels
Feature New feature or request

Comments

@torkelrogstad
Copy link

torkelrogstad commented May 4, 2023

Thanks for creating buf curl! I think it's a very promising tool that will make it a lot easier to work with gRPC and Connect APIs.

An "obvious" and killer feature that's missing from buf curl is tab completion of services and methods. It would make for a fantastic developer experience if buf curl https://my-api.com/<TAB> could list out the available endpoints and methods.

A few ideas for how this could be done:

  1. Check and see if we're in a folder (or sub-folder) that contains a Buf module or workspace. In that case the module could be built, and the endpoints and methods enumerated.
  2. Attempt to do reflection on the written URL (and with any header flags, if passed into the command).
  3. If the --schema flag is passed, inspect that to find the data.

I don't know how buf curl is typically used. But for my personal usage, I'm mostly using it against local services I'm actively working on, for manual testing and debugging. Prior to buf curl being developed, I've used a Fish script called bufcurl that wraps grpcurl and uses the approach I described in point 1. I've implemented tab completion for that (it only lists services, I haven't gotten around to implementing the methods). Pasting this below, for inspiration/context on what I'm thinking.

A final note: I'm configuring my bufcurl script through environment variables. In the folder containing services I'm working on I typically set these environment variables using an environment file. I think this is crucial to providing the best possible DX, as it simplifies the command needed to be invoked.

The script itself
function bufcurl
    if test -n "$BUFCURL_PLAINTEXT" 
        set plaintext_arg '-plaintext'
    end

    # Check if we get passed a data arg, with
    # a trailing `=`
    if string match -q -- "*-d=*" "$argv"
        set idx (contains --index -- -d= $argv)
        set data_args $argv[$idx] 

        # only do it once, because it's the same arg 
        set --erase argv[$idx]

    # Check if we get a data arg, without 
    # trailing `=`
    else if contains -- -d $argv
        set idx (contains --index -- -d $argv)
        set data_args $argv[$idx] $argv[(math "$idx + 1")]

        # do it twice, both flag and value
        set --erase argv[$idx]
        set --erase argv[$idx]

    end

    if test -n "$BUFCURL_HEADER" 
        set header_arg -H="$BUFCURL_HEADER"
    end

    if test -n "$BUFCURL_VERBOSE"
        set verbose_arg "-v"
    end

    # If we get passed a target, this overwrites 
    # env var target. 
    if string match -q -- "*localhost*" "$argv" 
        set --erase BUFCURL_TARGET
    end

    set working_dir (pwd)
    while not test -e buf.yaml -o -e buf.yml -o -e buf.work.yaml -o -e buf.work.yml 
        if test (pwd) = "/"
            echo could not find Buf config! >&2
            cd $working_dir
            return 1
        end

        __bufcurl_log pwd=(pwd), going backwards
        
        cd ..
    end

    __bufcurl_log found buf_dir=(pwd)
    set buf_dir (pwd)
    cd $working_dir

    __bufcurl_log plaintext: $plaintext_arg
    __bufcurl_log target: $BUFCURL_TARGET
    grpcurl $verbose_arg $plaintext_arg $header_arg $data_args -protoset (buf build $buf_dir -o - | psub) $BUFCURL_TARGET $argv
end
The tab completions
$ cat $HOME/.config/fish/completions/bufcurl.fish
function __bufcurl_list_services
    buf build --exclude-source-info --output -#format=json | \
        jq --raw-output --compact-output \
        '.file | map ({service: .service, package: .package} | select(.service) | {service: .service[0].name, package: .package} | .package +"."+ .service  ) | .[]'
end

# Not implemented...
function __bufcurl_list_methods --argument-names service

end

function __bufcurl_complete
    # no buf setup!
    if not test -e buf.yaml && not test -e buf.work.yaml
        return 
    end

    set -l cmd (commandline -poc)
    set -e cmd[1]

    if not __fish_seen_subcommand_from (__bufcurl_list_services)
        __bufcurl_list_services
        return 
    end

    __bufcurl_list_methods



 
end

complete -c bufcurl --no-files -a "(__bufcurl_complete)"
@doriable doriable added the Feature New feature or request label Jun 10, 2024
@bufdev bufdev changed the title feature request: tab completions for buf curl Tab completion for buf curl Jun 27, 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
Projects
None yet
Development

No branches or pull requests

2 participants