You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.7 KiB
Go

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)
}
}