Compare commits

...

7 Commits

13 changed files with 278 additions and 212 deletions

View File

@ -1,7 +1,6 @@
package lumecmd
import (
"errors"
"flag"
"fmt"
"strconv"
@ -14,12 +13,6 @@ const (
ExitFailure
)
type Config struct {
AccessToken string `toml:"access_token"`
OutputFormat string `toml:"output_format"`
Colors map[string][]float32 `toml:"colors"`
}
type CmdArgs struct {
Flags Flags
Args []string
@ -96,38 +89,3 @@ func GetCommand(name string) (Command, bool) {
cmd, ok := commandRegistry[name]
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
}

131
cmd/config.go Normal file
View File

@ -0,0 +1,131 @@
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
}
var (
DefaultConfig = Config{
userAgent: initUserAgent(),
}
)
// 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 LoadConfig(s string) (*Config, error) {
var err error
var c *Config = &Config{}
*c = DefaultConfig
if _, err := toml.Decode(s, &c); err != nil {
err = fmt.Errorf("fatal: failed to parse; %w", err)
}
envAccessToken := os.Getenv("LIFX_ACCESS_TOKEN")
if envAccessToken != "" {
c.AccessToken = envAccessToken
}
return c, err
}
func LoadConfigFile(configPath string) (*Config, error) {
var err error
var c *Config = &Config{}
*c = DefaultConfig
if _, err := toml.DecodeFile(configPath, &c); err != nil {
err = fmt.Errorf("fatal: failed to parse %s; %w", configPath, err)
}
envAccessToken := os.Getenv("LIFX_ACCESS_TOKEN")
if envAccessToken != "" {
c.AccessToken = envAccessToken
}
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

@ -24,6 +24,8 @@ func NewCmdLs() Command {
}
func LsCmd(args CmdArgs) (int, error) {
var p Printer
c := args.Client
selector := args.Flags.String("selector")
format := args.Flags.String("format")
@ -37,12 +39,8 @@ func LsCmd(args CmdArgs) (int, error) {
return ExitFailure, err
}
switch format {
case "table":
PrintLightsTable(lights)
default:
PrintLights(lights)
}
p = NewPrinter(format)
p.Lights(lights)
return ExitSuccess, nil
}

View File

@ -5,18 +5,11 @@ import (
"flag"
"fmt"
"os"
"path"
"strings"
"git.kill0.net/chill9/lifx-go"
"github.com/BurntSushi/toml"
)
var userAgent string
func init() {
userAgent = initUserAgent()
RegisterCommand(NewCmdHelp())
RegisterCommand(NewCmdLs())
RegisterCommand(NewCmdPoweroff())
@ -33,10 +26,8 @@ var Version string
var BuildDate string
var GitCommit string
const lumercFile string = ".lumerc"
func Main(args []string) (int, error) {
var config Config
var config *Config
var err error
if len(args) == 1 {
@ -49,8 +40,7 @@ func Main(args []string) (int, error) {
return ExitFailure, err
}
if _, err := toml.DecodeFile(configPath, &config); err != nil {
err = fmt.Errorf("fatal: failed to parse %s; %w", configPath, err)
if config, err = LoadConfigFile(configPath); err != nil {
return ExitFailure, err
}
@ -69,12 +59,12 @@ func Main(args []string) (int, error) {
c := lifx.NewClient(
config.AccessToken,
lifx.WithUserAgent(userAgent),
lifx.WithUserAgent(config.userAgent),
)
cmdArgs := CmdArgs{
Client: c,
Config: config,
Config: *config,
Args: args[2:],
}
@ -97,37 +87,4 @@ func Main(args []string) (int, error) {
}
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

@ -29,6 +29,8 @@ func NewCmdPoweroff() Command {
}
func PoweroffCmd(args CmdArgs) (int, error) {
var p Printer
c := args.Client
duration := args.Flags.Float64("duration")
selector := args.Flags.String("selector")
@ -44,12 +46,8 @@ func PoweroffCmd(args CmdArgs) (int, error) {
return ExitFailure, err
}
switch format {
case "table":
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
p = NewPrinter(format)
p.Results(r.Results)
return ExitSuccess, nil
}

View File

@ -29,6 +29,8 @@ func NewCmdPoweron() Command {
}
func PoweronCmd(args CmdArgs) (int, error) {
var p Printer
c := args.Client
duration := args.Flags.Float64("duration")
selector := args.Flags.String("selector")
@ -44,12 +46,8 @@ func PoweronCmd(args CmdArgs) (int, error) {
return ExitFailure, err
}
switch format {
case "table":
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
p = NewPrinter(format)
p.Results(r.Results)
return ExitSuccess, nil
}

View File

@ -10,6 +10,98 @@ import (
"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 {
c := color.New(color.FgRed)
if s == "on" {
@ -69,77 +161,3 @@ func makeResultsTable(results []lifx.Result) (hdr []string, rows [][]string) {
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

@ -51,6 +51,8 @@ func NewCmdSetColor() Command {
}
func SetColorCmd(args CmdArgs) (int, error) {
var p Printer
c := args.Client
state := lifx.State{}
selector := args.Flags.String("selector")
@ -126,12 +128,8 @@ func SetColorCmd(args CmdArgs) (int, error) {
}
if !fast {
switch format {
case "table":
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
p = NewPrinter(format)
p.Results(r.Results)
}
return ExitSuccess, nil

View File

@ -44,6 +44,8 @@ func NewCmdSetState() Command {
}
func SetStateCmd(args CmdArgs) (int, error) {
var p Printer
c := args.Client
state := lifx.State{}
selector := args.Flags.String("selector")
@ -92,12 +94,8 @@ func SetStateCmd(args CmdArgs) (int, error) {
}
if !fast {
switch format {
case "table":
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
p = NewPrinter(format)
p.Results(r.Results)
}
return ExitSuccess, nil

View File

@ -47,6 +47,8 @@ func NewCmdSetWhite() Command {
}
func SetWhiteCmd(args CmdArgs) (int, error) {
var p Printer
c := args.Client
state := lifx.State{}
selector := args.Flags.String("selector")
@ -110,12 +112,8 @@ func SetWhiteCmd(args CmdArgs) (int, error) {
}
if !fast {
switch format {
case "table":
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
p = NewPrinter(format)
p.Results(r.Results)
}
return ExitSuccess, nil

View File

@ -27,6 +27,8 @@ func NewCmdToggle() Command {
}
func ToggleCmd(args CmdArgs) (int, error) {
var p Printer
c := args.Client
duration := args.Flags.Float64("duration")
selector := args.Flags.String("selector")
@ -41,12 +43,8 @@ func ToggleCmd(args CmdArgs) (int, error) {
return ExitFailure, err
}
switch format {
case "table":
PrintResultsTable(r.Results)
default:
PrintResults(r.Results)
}
p = NewPrinter(format)
p.Results(r.Results)
return ExitSuccess, nil
}

View File

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

12
lume.code-workspace Normal file
View File

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