| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- package main
- import (
- "fmt"
- "io"
- "os"
- "github.com/spf13/cobra"
- "netdome.biz/paul/qmk-rgb/internal/device"
- )
- // version is set at build time via -ldflags.
- var version = "dev"
- // Group IDs for the root help. They name a group in the help output and say
- // nothing else: no behaviour hangs off them.
- const (
- groupLighting = "lighting"
- groupProfile = "profile"
- groupKeyboard = "keyboard"
- )
- var (
- targetDevice string
- targetZone string
- )
- func newRootCommand() *cobra.Command {
- cmd := &cobra.Command{
- Use: "qmk-rgb-tool",
- Short: "QMK RGB CLI — control QMK keyboard lighting",
- SilenceErrors: true,
- SilenceUsage: true,
- }
- // The commands are grouped because fifteen of them in one flat list is where
- // a user starts reading the help to find a command and gives up. A group says
- // what a command is for, and a command in none of them lands under
- // "Additional Commands" where the grouping says nothing.
- cmd.AddGroup(
- &cobra.Group{ID: groupLighting, Title: "Lighting Commands:"},
- &cobra.Group{ID: groupProfile, Title: "Profile Commands:"},
- &cobra.Group{ID: groupKeyboard, Title: "Keyboard Commands:"},
- )
- cmd.PersistentFlags().StringVar(&targetDevice, "device", "", "Keyboard number as printed by 'keyboard info', starting at 1")
- cmd.PersistentFlags().StringVar(&targetZone, "zone", "", "RGB lighting channel: backlight, rgblight, rgb_matrix, audio or led_matrix, or the name this keyboard's definition gives it")
- cmd.PersistentFlags().StringVar(&definitionFlag, "definition", "", "VIA definition file to read effect names from, instead of the one in the data directory")
- cmd.PersistentFlags().BoolVar(&jsonOutput, "json", false, "Print JSON instead of text")
- return cmd
- }
- var rootCmd = newRootCommand()
- func Execute() {
- if err := rootCmd.Execute(); err != nil {
- fmt.Fprintf(os.Stderr, "Error: %v\n", err)
- os.Exit(1)
- }
- }
- func main() {
- Execute()
- }
- var keyboardCmd = &cobra.Command{
- Use: "keyboard",
- Short: "Keyboard management commands",
- GroupID: groupKeyboard,
- }
- // inGroup places a command in one of the root help's groups.
- func inGroup(cmd *cobra.Command, group string) *cobra.Command {
- cmd.GroupID = group
- return cmd
- }
- // discoverAll is a seam for tests.
- var discoverAll = device.DiscoverAll
- // runKeyboardInfo writes the connected QMK keyboards, as text unless --json
- // asks otherwise. The 1-based index that --device accepts is in the "index"
- // field, so the machine shape emits no banner alongside it. Whether a keyboard
- // has effect names is reported per keyboard, because it differs: one board may
- // have a definition and the next may not.
- func runKeyboardInfo(out io.Writer) error {
- devices, err := discoverAll()
- if err != nil {
- return err
- }
- if devices == nil {
- devices = []device.Device{}
- }
- lines := describeDevices(devices)
- if !jsonOutput {
- return printKeyboardInfoText(out, lines)
- }
- type info struct {
- Devices []keyboardLine `json:"devices"`
- Total int `json:"total"`
- }
- return encodeJSON(out, info{Devices: lines, Total: len(lines)})
- }
- var keyboardInfoCmd = &cobra.Command{
- Use: "info",
- Short: "Discover connected QMK keyboards",
- Long: "Scan for connected QMK keyboards and print device info as JSON.\n" +
- "Each device carries the 1-based index that --device accepts.",
- Args: cobra.NoArgs,
- RunE: func(cmd *cobra.Command, args []string) error {
- return runKeyboardInfo(cmd.OutOrStdout())
- },
- }
- func init() {
- registerCommands(rootCmd)
- registerFlagCompletions(rootCmd)
- rootCmd.Version = version
- rootCmd.SetVersionTemplate(" qmk-rgb-tool {{.Version}}\n")
- }
- // registerCommands adds every command to the root, each in the group the help
- // output lists it under. It is a function of its own so that a test can build the
- // same tree the binary runs and check the grouping is real, rather than repeating
- // a list that could fall behind the one that ships.
- func registerCommands(root *cobra.Command) {
- keyboardCmd.AddCommand(keyboardInfoCmd)
- root.AddCommand(
- inGroup(NewEnableCmd(), groupLighting),
- inGroup(NewDisableCmd(), groupLighting),
- inGroup(NewInfoCmd(), groupLighting),
- inGroup(NewEffectCmd(), groupLighting),
- inGroup(NewBrightnessCmd(), groupLighting),
- inGroup(NewSpeedCmd(), groupLighting),
- inGroup(NewColorCmd(), groupLighting),
- inGroup(NewProfileSaveCmd(), groupProfile),
- inGroup(NewProfileLoadCmd(), groupProfile),
- inGroup(NewProfileListCmd(), groupProfile),
- inGroup(NewProfileDeleteCmd(), groupProfile),
- inGroup(NewDefinitionCmd(), groupKeyboard),
- inGroup(keyboardCmd, groupKeyboard),
- )
- }
|