package cmd import ( "errors" "fmt" "io" "os" "github.com/spf13/cobra" ) var rootCmd = &cobra.Command{ Use: "gosay", Short: "gosay is a cli tool for performing basic tts", Long: `gosay is a cli tool for performing basic tts. It uses Piper TTS and Aplay to perform speech to text from the cmdline. Usage: gosay "Your message" # Say a message directly from an argument echo "Another message | gosay # Pipe a message to gosay gosay < input.txt # Redirect from file `, Args: cobra.MaximumNArgs(1), Run: rootRun, } // checkStdInSource checks if the source of stdin is a pipe, redirect or file. If true the source can be read. func checkStdInSource() (bool, error) { fileInfo, statErr := os.Stdin.Stat() if statErr != nil { return false, fmt.Errorf("could not determine stdin source. %s", statErr) } // perform a bitwise check on to check. True if os.Stdin is not a character device(ie. tty) isPiped := (fileInfo.Mode() & os.ModeCharDevice) == 0 return isPiped, nil } // rootRun provides the default command of using gosay "your args" func rootRun(cmd *cobra.Command, args []string) { var err error if !(len(args) > 0) { isPiped, err := checkStdInSource() if !isPiped || err != nil { err = errors.New("Must use pipe, redirect from stdin, or provide direct argument") cobra.CheckErr(err) } buf, err := io.ReadAll(os.Stdin) cobra.CheckErr(err) err = Say(buf) cobra.CheckErr(err) } else { // assume its input is comming from stdin err = Say([]byte(args[0])) } cobra.CheckErr(err) } func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Fprintf(os.Stderr, "An error occurred while executing gosay: %s", err) os.Exit(1) } }