complete
complete copied to clipboard
Why can't I run exec.Command("app do something") call inside custom predictor?
I would like to predict not hardcoded options but pull them from daemon every time.
For example I input command app user remove
, click TAB, and cli would offer me list of users which pulled by calling exec.Command("cli-get-users')
type ppred struct{}
func (y ppred) Predict(prefix string) []string {
dateCmd := exec.Command("app", "user", "list")
dateOut, err := dateCmd.Output()
if err != nil {
// handle error
}
s := strings.Split(strings.TrimSpace(string(dateOut)), "\n")
return predict.Set(s).Predict(prefix)
}
Output is always empty, but when I run this code inside unit test, output is present and we're all good. If this is expected behaviour please someone explain or point me to explanation why it's not working.
It seems that you forgot datacmd.Run()? Can you see that you first get the desired output in a main() program?
Hi, thank you for reply. cmd.Output() method under the hood runs Run() and Wait(). Anyway, I got logic I wanted other way, by making call to server without creating subprocess.
But this issue I mentioned is not solved. I suppose it's somehow can't run subprocess on my Mac or whatever because it's not even making request (although no error output either). You can try this by running even exec.Command("ls") and check out output. You'll get none..
Hi, thank you for reply. cmd.Output() method under the hood runs Run() and Wait().
Oh, right, sorry I missed it.
Anyway, I got logic I wanted other way, by making call to server without creating subprocess.
This is usually the better approach in any case :+1:
I see that you don't check the error returned from the cmd.Output()
call, maybe the returned error would be informative and revile the issue?
In any case, I tried to reproduce it on my linux machine and didn't found an issue:
The program:
// A program that complete itself
package main
import (
"flag"
"fmt"
"log"
"os"
"os/exec"
"strings"
"github.com/posener/complete"
)
func main() {
var name string
flag.StringVar(&name, "name", "", "Give your name")
cmp := complete.New(
"exec1",
complete.Command{Flags: complete.Flags{"-name": ppred{}}},
)
cmp.CLI.InstallName = "complete"
cmp.CLI.UninstallName = "uncomplete"
cmp.AddFlags(nil)
flag.Parse()
if cmp.Complete() {
return
}
// if the completion did not do anything, we can run our program logic here.
if name == "" {
fmt.Println("Your name is missing")
os.Exit(1)
}
fmt.Println("Hi,", name)
}
type ppred struct{}
func (y ppred) Predict(prefix complete.Args) []string {
dateOut, err := exec.Command("ls").Output()
if err != nil {
log.Fatalf("Unable to run command ls: %v", err)
}
return strings.Split(strings.TrimSpace(string(dateOut)), "\n")
}
In the terminal:
$ cd example/exec1
$ go install ./
$ exec1 -h
Usage of exec1:
-complete
Install completion for exec1 command
-name string
Give your name
-uncomplete
Uninstall completion for exec1 command
-y Don't prompt user for typing 'yes' when installing completion
$ exec1 -complete
Install completion for exec1? y
Installing...
Done!
$ source ~/.bashrc
Then I exec1 -name <tab>
and I get completion for main.go
, which is the file in the directory I am at. So this is the expected behavior...
Can you please check on your machine if you get the same behavior?