3

I'm working on a Cobra-based Go app and I want to have a bash completion for command line flags:

$ my-cool-app --some-id=

The list of valid values for --some-id flag is available by making some HTTP call. How to make such bash completion available using Cobra?

Petr Razumov
  • 1,952
  • 2
  • 17
  • 32
  • 1
    @Adrian: No, I believe this question is perfectly on-topic here, as the question is how to take advantage of cobra's bash completion feature, when the argument options are determined dynamically. – Jonathan Hall Aug 14 '18 at 14:27
  • Yes it's possible. Bash does not care how you get the valid `--some-id` flags. –  Aug 14 '18 at 14:40
  • 1
    @MichaWiedenmann: "man bash" knows nothing about cobra's bash completion support. The proper starting place is [here](https://github.com/spf13/cobra/blob/master/bash_completions.md), with your link as a possible additional resource for advanced customizations (probably irrelevant for this particular question, though). – Jonathan Hall Aug 14 '18 at 15:00
  • @MichaWiedenmann thanks for the hint, but my question is mostly about using Cobra Go package other than programmable bash completion: https://github.com/spf13/cobra/blob/master/bash_completions.md – Petr Razumov Aug 14 '18 at 15:04
  • So you have to make some http `GET` somewhere, then parse your output with some xml parser or depending on html result, maybe could you use `sed`... You have to post more information about: .1 sample of html result to parse, .2 sample of argument you want to extract, .3 some code you already tried. – F. Hauri - Give Up GitHub Jul 29 '21 at 08:58
  • Once your *list of available option* done, you have to use `complete` command, Have a look at [Completion based on Associative Array](https://stackoverflow.com/a/13112493/1765658) or at [how to build a `mrcon` (minecraft remote connexion) with **completion** bash *environment*](https://stackoverflow.com/a/58266594/1765658) – F. Hauri - Give Up GitHub Jul 29 '21 at 09:11

1 Answers1

0

From This answer:

Where I create a function with completion for interacting with a server.

.0 Preamble: A function

As for bounty:

Please provide a clear and scalable sample code

There is a nice function intented to create an URL for stackoverflow.com:

soUrl() { 
    local __so_url='https://stackoverflow.com/'
    if [ "$1" = "-v" ]; then
        printf -v "$2" '%s%s' "$__so_url" "$3"
    else
        printf '%s%s\n' "$__so_url" "$1"
    fi
}

Usage:

soUrl
https://stackoverflow.com/
soUrl fooBar
https://stackoverflow.com/fooBar

or create a variable:

soUrl -v testvar baz
echo $testvar
https://stackoverflow.com/baz

.1 Collect available options in an array

The list of valid values for --some-id flag is available by making some HTTP...

You have to write something like:

wget -O - https://somewhere.net/somepath?someoption... |
    sed -ne 's/^.*someRE\(Re2\).*/\1/p'

Of course, instead of wget, you could use curl, nc or even /dev/tcp or openssl (Login to a site (stackoverflow) by bash)

But as you could have to make many tries on command line, use a temporary file in order to avoid stressing web server! Upto you're able to show all your available options.

.1b Then create an array:

soUrlOpts=($(soUrl -v var;wget -qO - $var | sed -ne '/a href="\//{
     s/.*a href="\/\([^"\/?]*\)[?\/"].*/\1/;H;};${x;:a;
     s/\n\([^\n]\+\)\(\n\(.*\n\|\)\)\1\n/\n\1\2\n/;ta;s/^\n//;s/\n\+/ /g;p;}'))

or

soUrlOpts=($(
    soUrl -v var
    wget -qO - $var |
    sed -ne '
        /a href="\//{
          s/.*a href="\/\([^"\/?]*\)[?\/"].*/\1/;
          H;
        };
        ${
          x;
         :a;
          s/\n\([^\n]\+\)\(\n\(.*\n\|\)\)\1\n/\n\1\2\n/;
          ta;
          s/^\n//;
          s/\n\+/ /g;
          p;
        }'
))

Ensure your variable is correct:

declare -p soUrlOpts
declare -a soUrlOpts=([0]="company" [1]="teams" [2]="questions" [3]="jobs"
     [4]="collectives" [5]="users" [6]="advertising" [7]="talent" [8]="help")

.2 enable completion

complete -W "${soUrlOpts[*]}" soUrl

Then now, if you write: soUrl -v testvar q, then hit Tab, console must write uestion:

soUrl -v testvar questions
echo $testvar
https://stackoverflow.com/questions
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137