Compare commits

..

17 Commits

19 changed files with 531 additions and 321 deletions

106
cmd/breathe.go Normal file
View File

@ -0,0 +1,106 @@
package lumecmd
import (
"flag"
"git.kill0.net/chill9/lifx-go"
)
func NewCmdBreathe() Command {
return Command{
Name: "breathe",
Func: BreatheCmd,
Flags: func() *flag.FlagSet {
fs := flag.NewFlagSet("breathe", flag.ExitOnError)
selector := fs.String("selector", defaultSelector, "Set the selector")
fs.StringVar(selector, "s", defaultSelector, "Set the selector")
fs.String("color", defaultColor, "The color to use for the breathe effect")
fs.String("from-color", defaultColor, "The color to start the effect from")
fs.Float64("period", lifx.DefaultBreathePeriod, "The time in seconds for one cycle of the effect")
fs.Float64("cycles", lifx.DefaultBreatheCycles, "The number of times to repeat the effect")
fs.Bool("persist", lifx.DefaultBreathePersist, "If false set the light back to its previous value when effect ends, if true leave the last effect color")
fs.Bool("power-on", lifx.DefaultBreathePowerOn, "If true, turn the bulb on if it is not already on")
fs.Float64("peak", lifx.DefaultBreathePeak, "Defines where in a period the target color is at its maximum (min: 0.0, max: 1.0)")
fs.String("format", defaultOutputFormat, "Set the output format")
return fs
}(),
Use: "[--selector <selector>] --color <color> [--from-color <color>] [--period <period>] [--cycles <cycles>] [--persist <persist>] [--power-on] [--peak <peak>]",
Short: "The breathe effect",
}
}
func BreatheCmd(ctx Context) (int, error) {
var p Printer
c := ctx.Client
breathe := lifx.NewBreathe()
selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
if format == "" && ctx.Config.OutputFormat != "" {
format = ctx.Config.OutputFormat
}
color := ctx.Flags.String("color")
if color != "" {
breathe.Color = lifx.NamedColor(color)
}
from_color := ctx.Flags.String("from-color")
if from_color != "" {
breathe.FromColor = lifx.NamedColor(from_color)
}
periodFlag := ctx.Flags.String("period")
if periodFlag != "" {
period := ctx.Flags.Float64("period")
breathe.Period = period
}
cyclesFlag := ctx.Flags.String("cycles")
if cyclesFlag != "" {
cycles := ctx.Flags.Float64("cycles")
breathe.Cycles = cycles
}
persist := ctx.Flags.Bool("persist")
breathe.Persist = persist
power_on := ctx.Flags.Bool("power-on")
breathe.PowerOn = power_on
peakFlag := ctx.Flags.String("peak")
if peakFlag != "" {
peak := ctx.Flags.Float64("peak")
breathe.Peak = peak
}
if color == "" {
printCmdHelp(ctx.Name)
return ExitFailure, nil
}
if err := breathe.Valid(); err != nil {
return ExitFailure, err
}
r, err := c.Breathe(selector, breathe)
if err != nil {
return ExitFailure, err
}
p = NewPrinter(format)
p.Results(r.Results)
return ExitSuccess, nil
}

View File

@ -1,7 +1,6 @@
package lumecmd package lumecmd
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
"strconv" "strconv"
@ -14,13 +13,7 @@ const (
ExitFailure ExitFailure
) )
type Config struct { type Context struct {
AccessToken string `toml:"access_token"`
OutputFormat string `toml:"output_format"`
Colors map[string][]float32 `toml:"colors"`
}
type CmdArgs struct {
Flags Flags Flags Flags
Args []string Args []string
Client *lifx.Client Client *lifx.Client
@ -34,7 +27,7 @@ type Flags struct {
type Command struct { type Command struct {
Name string Name string
Func func(CmdArgs) (int, error) Func func(Context) (int, error)
Flags *flag.FlagSet Flags *flag.FlagSet
Use string Use string
Short string Short string
@ -96,38 +89,3 @@ func GetCommand(name string) (Command, bool) {
cmd, ok := commandRegistry[name] cmd, ok := commandRegistry[name]
return cmd, ok return cmd, ok
} }
// Validate configuration struct
func (c *Config) Validate() error {
var err error
if c.AccessToken == "" {
err = errors.New("access_token is not set")
}
if err = c.validateColors(); err != nil {
return err
}
return err
}
func (c *Config) validateColors() (err error) {
if len(c.Colors) > 0 {
for name, hsb := range c.Colors {
if len(hsb) != 3 {
return fmt.Errorf("color '%s' needs three values", name)
}
h, s, b := hsb[0], hsb[1], hsb[2]
if h < 0 || h > 360 {
return fmt.Errorf("color '%s' hue value must be between 0.0-360.0", name)
}
if s < 0 || b > 1 {
return fmt.Errorf("color '%s' saturation value must be between 0.0-1.0", name)
}
if b < 0 || b > 1 {
return fmt.Errorf("color '%s' brightness value must be between 0.0-1.0", name)
}
}
}
return err
}

142
cmd/config.go Normal file
View File

@ -0,0 +1,142 @@
package lumecmd
import (
"errors"
"fmt"
"os"
"path"
"strings"
"github.com/BurntSushi/toml"
)
const lumercFile string = ".lumerc"
type Config struct {
AccessToken string `toml:"access_token"`
OutputFormat string `toml:"output_format"`
Colors map[string][]float32 `toml:"colors"`
userAgent string
Debug bool `toml:"debug"`
}
var (
DefaultConfig = Config{
userAgent: initUserAgent(),
}
globalConfig *Config = NewConfig()
)
func NewConfig() *Config {
c := new(Config)
c.userAgent = initUserAgent()
c.Debug = false
c.OutputFormat = "simple"
return c
}
func GetConfig() *Config {
return globalConfig
}
// Validate configuration struct
func (c *Config) Validate() error {
var err error
if c.AccessToken == "" {
err = errors.New("access_token is not set")
}
if err = c.validateColors(); err != nil {
return err
}
return err
}
func (c *Config) validateColors() (err error) {
if len(c.Colors) > 0 {
for name, hsb := range c.Colors {
if len(hsb) != 3 {
return fmt.Errorf("color '%s' needs three values", name)
}
h, s, b := hsb[0], hsb[1], hsb[2]
if h < 0 || h > 360 {
return fmt.Errorf("color '%s' hue value must be between 0.0-360.0", name)
}
if s < 0 || b > 1 {
return fmt.Errorf("color '%s' saturation value must be between 0.0-1.0", name)
}
if b < 0 || b > 1 {
return fmt.Errorf("color '%s' brightness value must be between 0.0-1.0", name)
}
}
}
return err
}
func (c *Config) MergeWithEnv() {
envAccessToken := os.Getenv("LIFX_ACCESS_TOKEN")
if envAccessToken != "" {
c.AccessToken = envAccessToken
}
}
func LoadConfig(s string) (*Config, error) {
var err error
var c *Config = GetConfig()
*c = DefaultConfig
if _, err := toml.Decode(s, &c); err != nil {
err = fmt.Errorf("fatal: failed to parse; %w", err)
}
return c, err
}
func LoadConfigFile(configPath string) (*Config, error) {
var err error
var c *Config = GetConfig()
*c = DefaultConfig
if _, err := toml.DecodeFile(configPath, &c); err != nil {
err = fmt.Errorf("fatal: failed to parse %s; %w", configPath, err)
}
return c, err
}
func getConfigPath() string {
var tryPath, configPath string
// ~/.lumerc
homeDir, err := os.UserHomeDir()
if err == nil {
tryPath = path.Join(homeDir, lumercFile)
if _, err := os.Stat(tryPath); !os.IsNotExist(err) {
configPath = tryPath
}
}
// ./.lumerc
cwd, err := os.Getwd()
if err == nil {
tryPath = path.Join(cwd, lumercFile)
if _, err := os.Stat(tryPath); !os.IsNotExist(err) {
configPath = tryPath
}
}
return configPath
}
func initUserAgent() string {
var b strings.Builder
b.WriteString("lume")
b.WriteRune('/')
b.WriteString(Version)
return b.String()
}

View File

@ -14,11 +14,11 @@ func NewCmdHelp() Command {
} }
} }
func HelpCmd(args CmdArgs) (int, error) { func HelpCmd(ctx Context) (int, error) {
if len(args.Args) == 0 { if len(ctx.Args) == 0 {
printHelp(commandRegistry) printHelp(commandRegistry)
} else if len(args.Args) >= 1 { } else if len(ctx.Args) >= 1 {
printCmdHelp(args.Args[0]) printCmdHelp(ctx.Args[0])
} }
return ExitSuccess, nil return ExitSuccess, nil

View File

@ -23,26 +23,27 @@ func NewCmdLs() Command {
} }
} }
func LsCmd(args CmdArgs) (int, error) { func LsCmd(ctx Context) (int, error) {
c := args.Client var p Printer
selector := args.Flags.String("selector")
format := args.Flags.String("format")
if format == "" && args.Config.OutputFormat != "" { c := ctx.Client
format = args.Config.OutputFormat selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
if format == "" && ctx.Config.OutputFormat != "" {
format = ctx.Config.OutputFormat
} }
lights, err := c.ListLights(selector) lights, err := c.ListLights(selector)
Debugf("%+v\n", lights)
if err != nil { if err != nil {
return ExitFailure, err return ExitFailure, err
} }
switch format { p = NewPrinter(format)
case "table": p.Lights(lights)
PrintLightsTable(lights)
default:
PrintLights(lights)
}
return ExitSuccess, nil return ExitSuccess, nil
} }

View File

@ -4,19 +4,11 @@ import (
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
"os"
"path"
"strings"
"git.kill0.net/chill9/lifx-go" "git.kill0.net/chill9/lifx-go"
"github.com/BurntSushi/toml"
) )
var userAgent string
func init() { func init() {
userAgent = initUserAgent()
RegisterCommand(NewCmdHelp()) RegisterCommand(NewCmdHelp())
RegisterCommand(NewCmdLs()) RegisterCommand(NewCmdLs())
RegisterCommand(NewCmdPoweroff()) RegisterCommand(NewCmdPoweroff())
@ -27,17 +19,24 @@ func init() {
RegisterCommand(NewCmdShow()) RegisterCommand(NewCmdShow())
RegisterCommand(NewCmdToggle()) RegisterCommand(NewCmdToggle())
RegisterCommand(NewCmdVersion()) RegisterCommand(NewCmdVersion())
RegisterCommand(NewCmdBreathe())
flag.BoolVar(&debugFlag, "debug", false, "debug mode")
flag.BoolVar(&debugFlag, "d", false, "debug mode")
} }
var Version string var Version string
var BuildDate string var BuildDate string
var GitCommit string var GitCommit string
var debugFlag bool
const lumercFile string = ".lumerc"
func Main(args []string) (int, error) { func Main(args []string) (int, error) {
var config Config var config *Config = GetConfig()
var err error var err error
var i int
flag.Parse()
i = flag.NFlag() + 1
if len(args) == 1 { if len(args) == 1 {
args = append(args, "help") args = append(args, "help")
@ -49,33 +48,30 @@ func Main(args []string) (int, error) {
return ExitFailure, err return ExitFailure, err
} }
if _, err := toml.DecodeFile(configPath, &config); err != nil { if config, err = LoadConfigFile(configPath); err != nil {
err = fmt.Errorf("fatal: failed to parse %s; %w", configPath, err)
return ExitFailure, err return ExitFailure, err
} }
config.MergeWithEnv()
envAccessToken := os.Getenv("LIFX_ACCESS_TOKEN")
if envAccessToken != "" {
config.AccessToken = envAccessToken
}
if err = config.Validate(); err != nil { if err = config.Validate(); err != nil {
return ExitFailure, fmt.Errorf("fatal: %s", err) return ExitFailure, fmt.Errorf("fatal: %s", err)
} }
flag.Parse() config.Debug = debugFlag
command := args[1] command := args[i]
i++
c := lifx.NewClient( c := lifx.NewClient(
config.AccessToken, config.AccessToken,
lifx.WithUserAgent(userAgent), lifx.WithUserAgent(config.userAgent),
lifx.WithDebug(debugFlag),
) )
cmdArgs := CmdArgs{ Context := Context{
Client: c, Client: c,
Config: config, Config: *config,
Args: args[2:], Args: args[i:],
} }
cmd, ok := GetCommand(command) cmd, ok := GetCommand(command)
@ -86,48 +82,15 @@ func Main(args []string) (int, error) {
fs := cmd.Flags fs := cmd.Flags
if fs != nil { if fs != nil {
fs.Parse(args[2:]) fs.Parse(args[i:])
cmdArgs.Flags = Flags{FlagSet: fs} Context.Flags = Flags{FlagSet: fs}
} }
cmdArgs.Name = command Context.Name = command
exitCode, err := cmd.Func(cmdArgs) exitCode, err := cmd.Func(Context)
if err != nil { if err != nil {
err = fmt.Errorf("fatal: %s", err) err = fmt.Errorf("fatal: %s", err)
} }
return exitCode, err return exitCode, err
} }
func getConfigPath() string {
var tryPath, configPath string
// ~/.lumerc
homeDir, err := os.UserHomeDir()
if err == nil {
tryPath = path.Join(homeDir, lumercFile)
if _, err := os.Stat(tryPath); !os.IsNotExist(err) {
configPath = tryPath
}
}
// ./.lumerc
cwd, err := os.Getwd()
if err == nil {
tryPath = path.Join(cwd, lumercFile)
if _, err := os.Stat(tryPath); !os.IsNotExist(err) {
configPath = tryPath
}
}
return configPath
}
func initUserAgent() string {
var b strings.Builder
b.WriteString("lume")
b.WriteRune('/')
b.WriteString(Version)
return b.String()
}

View File

@ -28,15 +28,17 @@ func NewCmdPoweroff() Command {
} }
} }
func PoweroffCmd(args CmdArgs) (int, error) { func PoweroffCmd(ctx Context) (int, error) {
c := args.Client var p Printer
duration := args.Flags.Float64("duration")
selector := args.Flags.String("selector") c := ctx.Client
format := args.Flags.String("format") duration := ctx.Flags.Float64("duration")
selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
state := lifx.State{Power: "off", Duration: duration} state := lifx.State{Power: "off", Duration: duration}
if format == "" && args.Config.OutputFormat != "" { if format == "" && ctx.Config.OutputFormat != "" {
format = args.Config.OutputFormat format = ctx.Config.OutputFormat
} }
r, err := c.SetState(selector, state) r, err := c.SetState(selector, state)
@ -44,12 +46,8 @@ func PoweroffCmd(args CmdArgs) (int, error) {
return ExitFailure, err return ExitFailure, err
} }
switch format { p = NewPrinter(format)
case "table": p.Results(r.Results)
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
return ExitSuccess, nil return ExitSuccess, nil
} }

View File

@ -28,15 +28,17 @@ func NewCmdPoweron() Command {
} }
} }
func PoweronCmd(args CmdArgs) (int, error) { func PoweronCmd(ctx Context) (int, error) {
c := args.Client var p Printer
duration := args.Flags.Float64("duration")
selector := args.Flags.String("selector") c := ctx.Client
format := args.Flags.String("format") duration := ctx.Flags.Float64("duration")
selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
state := lifx.State{Power: "on", Duration: duration} state := lifx.State{Power: "on", Duration: duration}
if format == "" && args.Config.OutputFormat != "" { if format == "" && ctx.Config.OutputFormat != "" {
format = args.Config.OutputFormat format = ctx.Config.OutputFormat
} }
r, err := c.SetState(selector, state) r, err := c.SetState(selector, state)
@ -44,12 +46,8 @@ func PoweronCmd(args CmdArgs) (int, error) {
return ExitFailure, err return ExitFailure, err
} }
switch format { p = NewPrinter(format)
case "table": p.Results(r.Results)
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
return ExitSuccess, nil return ExitSuccess, nil
} }

View File

@ -10,6 +10,98 @@ import (
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
) )
type Printer interface {
Results(results []lifx.Result)
Lights(lights []lifx.Light)
}
type defaultPrinter struct{}
type tablePrinter struct{}
func NewPrinter(format string) Printer {
switch format {
case "table":
return &tablePrinter{}
default:
return &defaultPrinter{}
}
}
func (dp *defaultPrinter) Results(results []lifx.Result) {
sortResults(results)
table := tablewriter.NewWriter(os.Stdout)
_, rows := makeResultsTable(results)
for _, v := range rows {
table.Append(v)
}
fmt.Printf("total %d\n", len(results))
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetAutoWrapText(false)
table.SetBorder(false)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetHeaderLine(false)
table.SetNoWhiteSpace(true)
table.SetRowSeparator("")
table.SetTablePadding(" ")
table.Render()
}
func (tp *tablePrinter) Results(results []lifx.Result) {
sortResults(results)
table := tablewriter.NewWriter(os.Stdout)
hdr, rows := makeResultsTable(results)
for _, v := range rows {
table.Append(v)
}
table.SetHeader(hdr)
table.Render()
}
func (dp *defaultPrinter) Lights(lights []lifx.Light) {
sortLights(lights)
table := tablewriter.NewWriter(os.Stdout)
_, rows := makeLightsTable(lights)
for _, v := range rows {
table.Append(v)
}
fmt.Printf("total %d\n", len(lights))
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetAutoWrapText(false)
table.SetBorder(false)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetHeaderLine(false)
table.SetNoWhiteSpace(true)
table.SetRowSeparator("")
table.SetTablePadding(" ")
table.Render()
}
func (tp *tablePrinter) Lights(lights []lifx.Light) {
sortLights(lights)
table := tablewriter.NewWriter(os.Stdout)
hdr, rows := makeLightsTable(lights)
for _, v := range rows {
table.Append(v)
}
table.SetHeader(hdr)
table.Render()
}
func ColorizePower(s string) string { func ColorizePower(s string) string {
c := color.New(color.FgRed) c := color.New(color.FgRed)
if s == "on" { if s == "on" {
@ -69,77 +161,3 @@ func makeResultsTable(results []lifx.Result) (hdr []string, rows [][]string) {
return return
} }
func PrintLights(lights []lifx.Light) {
sortLights(lights)
table := tablewriter.NewWriter(os.Stdout)
_, rows := makeLightsTable(lights)
for _, v := range rows {
table.Append(v)
}
fmt.Printf("total %d\n", len(lights))
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetAutoWrapText(false)
table.SetBorder(false)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetHeaderLine(false)
table.SetNoWhiteSpace(true)
table.SetRowSeparator("")
table.SetTablePadding(" ")
table.Render()
}
func PrintLightsTable(lights []lifx.Light) {
sortLights(lights)
table := tablewriter.NewWriter(os.Stdout)
hdr, rows := makeLightsTable(lights)
for _, v := range rows {
table.Append(v)
}
table.SetHeader(hdr)
table.Render()
}
func PrintResults(results []lifx.Result) {
sortResults(results)
table := tablewriter.NewWriter(os.Stdout)
_, rows := makeResultsTable(results)
for _, v := range rows {
table.Append(v)
}
fmt.Printf("total %d\n", len(results))
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetAutoWrapText(false)
table.SetBorder(false)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetHeaderLine(false)
table.SetNoWhiteSpace(true)
table.SetRowSeparator("")
table.SetTablePadding(" ")
table.Render()
}
func PrintResultsTable(results []lifx.Result) {
sortResults(results)
table := tablewriter.NewWriter(os.Stdout)
hdr, rows := makeResultsTable(results)
for _, v := range rows {
table.Append(v)
}
table.SetHeader(hdr)
table.Render()
}

View File

@ -50,28 +50,30 @@ func NewCmdSetColor() Command {
} }
} }
func SetColorCmd(args CmdArgs) (int, error) { func SetColorCmd(ctx Context) (int, error) {
c := args.Client var p Printer
state := lifx.State{}
selector := args.Flags.String("selector")
format := args.Flags.String("format")
if format == "" && args.Config.OutputFormat != "" { c := ctx.Client
format = args.Config.OutputFormat state := lifx.State{}
selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
if format == "" && ctx.Config.OutputFormat != "" {
format = ctx.Config.OutputFormat
} }
power := args.Flags.String("power") power := ctx.Flags.String("power")
if power != "" { if power != "" {
state.Power = power state.Power = power
} }
hueFlag := args.Flags.String("hue") hueFlag := ctx.Flags.String("hue")
saturationFlag := args.Flags.String("saturation") saturationFlag := ctx.Flags.String("saturation")
rgbFlag := args.Flags.String("rgb") rgbFlag := ctx.Flags.String("rgb")
name := args.Flags.String("name") name := ctx.Flags.String("name")
if (hueFlag == "" || saturationFlag == "") && rgbFlag == "" && name == "" { if (hueFlag == "" || saturationFlag == "") && rgbFlag == "" && name == "" {
printCmdHelp(args.Name) printCmdHelp(ctx.Name)
return ExitFailure, nil return ExitFailure, nil
} }
@ -79,12 +81,12 @@ func SetColorCmd(args CmdArgs) (int, error) {
color := lifx.HSBKColor{} color := lifx.HSBKColor{}
if hueFlag != "" { if hueFlag != "" {
hue := args.Flags.Float32("hue") hue := ctx.Flags.Float32("hue")
color.H = lifx.Float32Ptr(hue) color.H = lifx.Float32Ptr(hue)
} }
if saturationFlag != "" { if saturationFlag != "" {
saturation := args.Flags.Float32("saturation") saturation := ctx.Flags.Float32("saturation")
color.S = lifx.Float32Ptr(saturation) color.S = lifx.Float32Ptr(saturation)
} }
state.Color = color state.Color = color
@ -96,7 +98,7 @@ func SetColorCmd(args CmdArgs) (int, error) {
} }
state.Color = color state.Color = color
} else if name != "" { } else if name != "" {
hsb, ok := args.Config.Colors[name] hsb, ok := ctx.Config.Colors[name]
if !ok { if !ok {
return ExitFailure, fmt.Errorf("%s is not a defined color", name) return ExitFailure, fmt.Errorf("%s is not a defined color", name)
} }
@ -107,16 +109,16 @@ func SetColorCmd(args CmdArgs) (int, error) {
state.Color = color state.Color = color
} }
brightnessFlag := args.Flags.String("brightness") brightnessFlag := ctx.Flags.String("brightness")
if brightnessFlag != "" { if brightnessFlag != "" {
brightness := args.Flags.Float64("brightness") brightness := ctx.Flags.Float64("brightness")
state.Brightness = brightness state.Brightness = brightness
} }
duration := args.Flags.Float64("duration") duration := ctx.Flags.Float64("duration")
state.Duration = duration state.Duration = duration
fast := args.Flags.Bool("fast") fast := ctx.Flags.Bool("fast")
state.Fast = fast state.Fast = fast
r, err := c.SetState(selector, state) r, err := c.SetState(selector, state)
@ -126,12 +128,8 @@ func SetColorCmd(args CmdArgs) (int, error) {
} }
if !fast { if !fast {
switch format { p = NewPrinter(format)
case "table": p.Results(r.Results)
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
} }
return ExitSuccess, nil return ExitSuccess, nil

View File

@ -43,46 +43,48 @@ func NewCmdSetState() Command {
} }
} }
func SetStateCmd(args CmdArgs) (int, error) { func SetStateCmd(ctx Context) (int, error) {
c := args.Client var p Printer
state := lifx.State{}
selector := args.Flags.String("selector")
format := args.Flags.String("format")
if format == "" && args.Config.OutputFormat != "" { c := ctx.Client
format = args.Config.OutputFormat state := lifx.State{}
selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
if format == "" && ctx.Config.OutputFormat != "" {
format = ctx.Config.OutputFormat
} }
power := args.Flags.String("power") power := ctx.Flags.String("power")
if power != "" { if power != "" {
state.Power = power state.Power = power
} }
color := args.Flags.String("color") color := ctx.Flags.String("color")
if color != "" { if color != "" {
state.Color = lifx.NamedColor(color) state.Color = lifx.NamedColor(color)
} }
brightnessFlag := args.Flags.String("brightness") brightnessFlag := ctx.Flags.String("brightness")
if brightnessFlag != "" { if brightnessFlag != "" {
brightness := args.Flags.Float64("brightness") brightness := ctx.Flags.Float64("brightness")
state.Brightness = brightness state.Brightness = brightness
} }
duration := args.Flags.Float64("duration") duration := ctx.Flags.Float64("duration")
state.Duration = duration state.Duration = duration
infraredFlag := args.Flags.String("infrared") infraredFlag := ctx.Flags.String("infrared")
if infraredFlag != "" { if infraredFlag != "" {
infrared := args.Flags.Float64("infrared") infrared := ctx.Flags.Float64("infrared")
state.Infrared = infrared state.Infrared = infrared
} }
fast := args.Flags.Bool("fast") fast := ctx.Flags.Bool("fast")
state.Fast = fast state.Fast = fast
if power == "" && color == "" && brightnessFlag == "" && infraredFlag == "" { if power == "" && color == "" && brightnessFlag == "" && infraredFlag == "" {
printCmdHelp(args.Name) printCmdHelp(ctx.Name)
return ExitFailure, nil return ExitFailure, nil
} }
@ -92,12 +94,8 @@ func SetStateCmd(args CmdArgs) (int, error) {
} }
if !fast { if !fast {
switch format { p = NewPrinter(format)
case "table": p.Results(r.Results)
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
} }
return ExitSuccess, nil return ExitSuccess, nil

View File

@ -46,24 +46,26 @@ func NewCmdSetWhite() Command {
} }
} }
func SetWhiteCmd(args CmdArgs) (int, error) { func SetWhiteCmd(ctx Context) (int, error) {
c := args.Client var p Printer
state := lifx.State{}
selector := args.Flags.String("selector")
format := args.Flags.String("format")
if format == "" && args.Config.OutputFormat != "" { c := ctx.Client
format = args.Config.OutputFormat state := lifx.State{}
selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
if format == "" && ctx.Config.OutputFormat != "" {
format = ctx.Config.OutputFormat
} }
power := args.Flags.String("power") power := ctx.Flags.String("power")
if power != "" { if power != "" {
state.Power = power state.Power = power
} }
kelvinFlag := args.Flags.String("kelvin") kelvinFlag := ctx.Flags.String("kelvin")
if kelvinFlag != "" { if kelvinFlag != "" {
kelvin := args.Flags.Int16("kelvin") kelvin := ctx.Flags.Int16("kelvin")
color, err := lifx.NewWhite(kelvin) color, err := lifx.NewWhite(kelvin)
if err != nil { if err != nil {
return ExitFailure, err return ExitFailure, err
@ -71,9 +73,9 @@ func SetWhiteCmd(args CmdArgs) (int, error) {
state.Color = color state.Color = color
} }
name := args.Flags.String("name") name := ctx.Flags.String("name")
if name != "" { if name != "" {
name := args.Flags.String("name") name := ctx.Flags.String("name")
color, err := lifx.NewWhiteString(name) color, err := lifx.NewWhiteString(name)
if err != nil { if err != nil {
return ExitFailure, err return ExitFailure, err
@ -81,26 +83,26 @@ func SetWhiteCmd(args CmdArgs) (int, error) {
state.Color = color state.Color = color
} }
brightnessFlag := args.Flags.String("brightness") brightnessFlag := ctx.Flags.String("brightness")
if brightnessFlag != "" { if brightnessFlag != "" {
brightness := args.Flags.Float64("brightness") brightness := ctx.Flags.Float64("brightness")
state.Brightness = brightness state.Brightness = brightness
} }
duration := args.Flags.Float64("duration") duration := ctx.Flags.Float64("duration")
state.Duration = duration state.Duration = duration
infraredFlag := args.Flags.String("infrared") infraredFlag := ctx.Flags.String("infrared")
if infraredFlag != "" { if infraredFlag != "" {
infrared := args.Flags.Float64("infrared") infrared := ctx.Flags.Float64("infrared")
state.Infrared = infrared state.Infrared = infrared
} }
fast := args.Flags.Bool("fast") fast := ctx.Flags.Bool("fast")
state.Fast = fast state.Fast = fast
if power == "" && kelvinFlag == "" && name == "" && brightnessFlag == "" && infraredFlag == "" { if power == "" && kelvinFlag == "" && name == "" && brightnessFlag == "" && infraredFlag == "" {
printCmdHelp(args.Name) printCmdHelp(ctx.Name)
return ExitFailure, nil return ExitFailure, nil
} }
@ -110,12 +112,8 @@ func SetWhiteCmd(args CmdArgs) (int, error) {
} }
if !fast { if !fast {
switch format { p = NewPrinter(format)
case "table": p.Results(r.Results)
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
} }
return ExitSuccess, nil return ExitSuccess, nil

View File

@ -24,10 +24,10 @@ func NewCmdShow() Command {
} }
} }
func ShowCmd(args CmdArgs) (int, error) { func ShowCmd(ctx Context) (int, error) {
var indent int var indent int
c := args.Client c := ctx.Client
selector := args.Flags.String("selector") selector := ctx.Flags.String("selector")
lights, err := c.ListLights(selector) lights, err := c.ListLights(selector)
if err != nil { if err != nil {

View File

@ -26,14 +26,16 @@ func NewCmdToggle() Command {
} }
} }
func ToggleCmd(args CmdArgs) (int, error) { func ToggleCmd(ctx Context) (int, error) {
c := args.Client var p Printer
duration := args.Flags.Float64("duration")
selector := args.Flags.String("selector")
format := args.Flags.String("format")
if format == "" && args.Config.OutputFormat != "" { c := ctx.Client
format = args.Config.OutputFormat duration := ctx.Flags.Float64("duration")
selector := ctx.Flags.String("selector")
format := ctx.Flags.String("format")
if format == "" && ctx.Config.OutputFormat != "" {
format = ctx.Config.OutputFormat
} }
r, err := c.Toggle(selector, duration) r, err := c.Toggle(selector, duration)
@ -41,12 +43,8 @@ func ToggleCmd(args CmdArgs) (int, error) {
return ExitFailure, err return ExitFailure, err
} }
switch format { p = NewPrinter(format)
case "table": p.Results(r.Results)
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
return ExitSuccess, nil return ExitSuccess, nil
} }

View File

@ -60,3 +60,9 @@ func YesNo(v bool) string {
} }
return "no" return "no"
} }
func Debugf(format string, a ...interface{}) {
if GetConfig().Debug {
fmt.Printf(format, a...)
}
}

View File

@ -2,6 +2,7 @@ package lumecmd
import ( import (
"fmt" "fmt"
"runtime"
"strings" "strings"
) )
@ -15,19 +16,23 @@ func NewCmdVersion() Command {
} }
} }
func VersionCmd(args CmdArgs) (int, error) { func VersionCmd(ctx Context) (int, error) {
var b strings.Builder var b strings.Builder
fmt.Fprintf(&b, "lume %s", Version) fmt.Fprintf(&b, "lume, version %s\n", Version)
b.WriteString(" ")
if GitCommit != "" { if GitCommit != "" {
fmt.Fprintf(&b, "(git: %s)", GitCommit) fmt.Fprintf(&b, " revision: %s\n", GitCommit)
b.WriteString(" ")
}
if BuildDate != "" {
fmt.Fprintf(&b, "build_date: %s", BuildDate)
} }
fmt.Println(b.String()) if BuildDate != "" {
fmt.Fprintf(&b, " build date: %s\n", BuildDate)
}
fmt.Fprintf(&b, " go version: %s\n", runtime.Version())
fmt.Fprintf(&b, " platform: %s/%s\n", runtime.GOOS, runtime.GOARCH)
fmt.Print(b.String())
return ExitSuccess, nil return ExitSuccess, nil
} }

6
go.mod
View File

@ -3,9 +3,11 @@ module git.kill0.net/chill9/lume
go 1.15 go 1.15
require ( require (
git.kill0.net/chill9/lifx-go v0.0.0-20210215004437-f86c28b0a5ef git.kill0.net/chill9/lifx-go v0.0.0-20210323044657-dbe1c40e1621
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/fatih/color v1.10.0 github.com/fatih/color v1.10.0
github.com/mattn/go-runewidth v0.0.10 // indirect
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061 github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4
) )

9
go.sum
View File

@ -1,5 +1,7 @@
git.kill0.net/chill9/lifx-go v0.0.0-20210215004437-f86c28b0a5ef h1:8yyXAk+qiRvrowTeHHAOBZqGXXCr8SxWFydez61ZGp8= git.kill0.net/chill9/lifx-go v0.0.0-20210215004437-f86c28b0a5ef h1:8yyXAk+qiRvrowTeHHAOBZqGXXCr8SxWFydez61ZGp8=
git.kill0.net/chill9/lifx-go v0.0.0-20210215004437-f86c28b0a5ef/go.mod h1:ZFKIcwdJ4Nqlrkn/eUHbeLt0NVhFsfxBREkVoA+jzUc= git.kill0.net/chill9/lifx-go v0.0.0-20210215004437-f86c28b0a5ef/go.mod h1:ZFKIcwdJ4Nqlrkn/eUHbeLt0NVhFsfxBREkVoA+jzUc=
git.kill0.net/chill9/lifx-go v0.0.0-20210323044657-dbe1c40e1621 h1:koWq2W08HjmvsNm4D8kD0OjMZKCJ/3681P9XFMTj77I=
git.kill0.net/chill9/lifx-go v0.0.0-20210323044657-dbe1c40e1621/go.mod h1:jInpjEqTBhrFpQKk7zPIWISvgjjfS2djXeKB3yB/8dY=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
@ -10,9 +12,16 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061 h1:DQmQoKxQWtyybCtX/3dIuDBcAhFszqq8YiNeS6sNu1c= golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061 h1:DQmQoKxQWtyybCtX/3dIuDBcAhFszqq8YiNeS6sNu1c=
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZN/QzUQp4ptM4rnjHvc=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

12
lume.code-workspace Normal file
View File

@ -0,0 +1,12 @@
{
"folders": [
{
"path": "."
},
{
"name": "lifx-go",
"path": "..\\lifx-go"
}
],
"settings": {}
}