I believe that all functionality is implemented
This commit is contained in:
parent
54c91f0d3c
commit
45d13e7052
14
Makefile
14
Makefile
@ -1,6 +1,18 @@
|
||||
# This how we want to name the binary output
|
||||
BINARY=gime
|
||||
|
||||
# These are the values we want to pass for VERSION and BUILD
|
||||
# git tag 1.0.1
|
||||
# git commit -am "One more change after the tags"
|
||||
VERSION=`git describe --tags`
|
||||
BUILD=`date +%FT%T%z`
|
||||
|
||||
# Setup the -ldflags option for go build here, interpolate the variable values
|
||||
LDFLAGS=-ldflags "-w -s -X cmd.Version=${VERSION} -X cmd.Build=${BUILD}"
|
||||
|
||||
# Builds the project
|
||||
gime:
|
||||
go build -o build/gime *.go
|
||||
go build ${LDFLAGS} -o build/${BINARY}
|
||||
|
||||
clean:
|
||||
rm build/*
|
||||
|
@ -7,6 +7,7 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
@ -15,8 +16,11 @@ import (
|
||||
// configCmd represents the config command
|
||||
var configCmd = &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "Print all configuration values",
|
||||
RunE: opConfig,
|
||||
Short: "Show or update configuration values",
|
||||
Long: `To set values just list them in key=value format.
|
||||
For example:
|
||||
gime config copytags=true roundto=30m`,
|
||||
RunE: opConfig,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -24,9 +28,36 @@ func init() {
|
||||
}
|
||||
|
||||
func opConfig(cmd *cobra.Command, args []string) error {
|
||||
updConfig := make(map[string]string)
|
||||
if len(args) > 0 {
|
||||
// We're setting arguments
|
||||
for _, a := range args {
|
||||
pts := strings.Split(a, "=")
|
||||
if len(pts) == 2 {
|
||||
updConfig[pts[0]] = pts[1]
|
||||
} else {
|
||||
return fmt.Errorf("Unable to parse config values.")
|
||||
}
|
||||
}
|
||||
}
|
||||
var settings []string
|
||||
for k, v := range viper.AllSettings() {
|
||||
settings = append(settings, fmt.Sprintf("%s: %s", k, v))
|
||||
switch v.(type) {
|
||||
case bool:
|
||||
if nv, ok := updConfig[k]; ok {
|
||||
v = nv == "true"
|
||||
viper.Set(k, v)
|
||||
viper.WriteConfig()
|
||||
}
|
||||
settings = append(settings, fmt.Sprintf("%s: %t", k, v))
|
||||
default:
|
||||
if nv, ok := updConfig[k]; ok {
|
||||
v = nv
|
||||
viper.Set(k, v)
|
||||
viper.WriteConfig()
|
||||
}
|
||||
settings = append(settings, fmt.Sprintf("%s: %s", k, v))
|
||||
}
|
||||
}
|
||||
sort.Strings(settings)
|
||||
fmt.Println("Configuration File:", viper.ConfigFileUsed())
|
||||
|
@ -17,14 +17,8 @@ import (
|
||||
// i3statusCmd represents the i3status command
|
||||
var i3statusCmd = &cobra.Command{
|
||||
Use: "i3status",
|
||||
Short: "",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
RunE: opI3Status,
|
||||
Short: "Output your timer.txt status in json for the i3 status bar",
|
||||
RunE: opI3Status,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
87
cmd/mod.go
87
cmd/mod.go
@ -6,21 +6,21 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.bullercodeworks.com/brian/gime/cli"
|
||||
"git.bullercodeworks.com/brian/gime/util"
|
||||
"git.bullercodeworks.com/brian/go-timertxt"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// modCmd represents the mod command
|
||||
var modCmd = &cobra.Command{
|
||||
Use: "mod",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
RunE: opMod,
|
||||
Short: "Modify a timer",
|
||||
RunE: opMod,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -28,6 +28,75 @@ func init() {
|
||||
}
|
||||
|
||||
func opMod(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("mod called")
|
||||
var err error
|
||||
p := cli.Program{}
|
||||
err = p.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = p.LoadTimerList(); err != nil {
|
||||
return err
|
||||
}
|
||||
var timer *timertxt.Timer
|
||||
var contexts, projects []string
|
||||
id, err := strconv.Atoi(args[0])
|
||||
if err != nil {
|
||||
// We didn't have a timer id, so try to modify the first active timer
|
||||
if len(*p.TimerList.GetActiveTimers()) > 0 {
|
||||
timer = (*p.TimerList.GetActiveTimers())[0]
|
||||
} else {
|
||||
// And we don't have any active timers
|
||||
return fmt.Errorf("No active timers, 'id' must be provided: %w", err)
|
||||
}
|
||||
} else {
|
||||
args = args[1:]
|
||||
if timer, err = p.TimerList.GetTimer(id); err != nil {
|
||||
return fmt.Errorf("Error getting timer %d: %w", id, err)
|
||||
}
|
||||
}
|
||||
var start, end time.Time
|
||||
|
||||
for _, v := range args {
|
||||
pts := strings.Split(v, "=")
|
||||
switch pts[0] {
|
||||
case "beginning", "start":
|
||||
if start, err = util.ParseFuzzyTime(pts[1]); err != nil {
|
||||
return fmt.Errorf("Error parsing start time: %w", err)
|
||||
}
|
||||
case "stop", "finish", "end":
|
||||
if end, err = util.ParseFuzzyTime(pts[1]); err != nil {
|
||||
return fmt.Errorf("Error parsing end time: %w", err)
|
||||
}
|
||||
case "project", "projects":
|
||||
projects = strings.Split(pts[1], ",")
|
||||
case "context", "contexts":
|
||||
contexts = strings.Split(pts[1], ",")
|
||||
}
|
||||
}
|
||||
if len(contexts) > 0 {
|
||||
for k := range contexts {
|
||||
contexts[k] = strings.TrimPrefix(contexts[k], "@")
|
||||
}
|
||||
timer.Contexts = contexts
|
||||
}
|
||||
if len(projects) > 0 {
|
||||
for k := range projects {
|
||||
projects[k] = strings.TrimPrefix(projects[k], "+")
|
||||
}
|
||||
timer.Projects = projects
|
||||
}
|
||||
if !start.IsZero() {
|
||||
timer.StartDate = start
|
||||
}
|
||||
if !end.IsZero() {
|
||||
timer.FinishDate = end
|
||||
timer.Finished = true
|
||||
}
|
||||
fmt.Println("Modified Timer:")
|
||||
fmt.Println(util.TimerToFriendlyString(timer))
|
||||
|
||||
if err := p.WriteTimerList(); err != nil {
|
||||
return fmt.Errorf("Error writing timer list: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
42
cmd/rm.go
42
cmd/rm.go
@ -6,21 +6,18 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"git.bullercodeworks.com/brian/gime/cli"
|
||||
"git.bullercodeworks.com/brian/gime/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// rmCmd represents the rm command
|
||||
var rmCmd = &cobra.Command{
|
||||
Use: "rm",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
RunE: opRemove,
|
||||
Short: "Remove a timer",
|
||||
RunE: opRemove,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -28,6 +25,33 @@ func init() {
|
||||
}
|
||||
|
||||
func opRemove(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("remove called")
|
||||
var err error
|
||||
p := cli.Program{}
|
||||
err = p.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = p.LoadTimerList(); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return fmt.Errorf("No timer id given")
|
||||
}
|
||||
id, err := strconv.Atoi(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid timer id given %s: %w", args[0], err)
|
||||
}
|
||||
t, err := p.TimerList.GetTimer(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting timer with id %s: %w", args[0], err)
|
||||
}
|
||||
if err = p.TimerList.RemoveTimerById(id); err != nil {
|
||||
return fmt.Errorf("Error Removing Timer: %w", err)
|
||||
}
|
||||
fmt.Println("Timer removed")
|
||||
fmt.Println(util.TimerToString(t))
|
||||
if err := p.WriteTimerList(); err != nil {
|
||||
return fmt.Errorf("Error writing timer list: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -15,14 +15,16 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
Version = "2.0"
|
||||
Version string
|
||||
Build string
|
||||
|
||||
configFile string
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "gime",
|
||||
Short: "Timer.txt Client",
|
||||
Long: "Gime is a timer.txt client to make all aspects of timekeeping simpler.",
|
||||
Long: fmt.Sprintf("Gime is a timer.txt client to make all aspects of timekeeping simpler.\nVersion: %s\nBuild Date: %s\n", Version, Build),
|
||||
RunE: opStatus,
|
||||
}
|
||||
)
|
||||
@ -46,6 +48,7 @@ func initConfig() {
|
||||
viper.SetDefault("timerfile", "timer.txt")
|
||||
viper.SetDefault("donefile", "done.txt")
|
||||
viper.SetDefault("reportfile", "report.txt")
|
||||
viper.SetDefault("copytags", false)
|
||||
var firstDir string // In case we need to make directories
|
||||
if configFile != "" {
|
||||
viper.SetConfigFile(configFile)
|
||||
|
51
cmd/start.go
51
cmd/start.go
@ -6,21 +6,19 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.bullercodeworks.com/brian/gime/cli"
|
||||
"git.bullercodeworks.com/brian/gime/util"
|
||||
"git.bullercodeworks.com/brian/go-timertxt"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// startCmd represents the start command
|
||||
var startCmd = &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
RunE: opStart,
|
||||
Short: "Start a timer",
|
||||
RunE: opStart,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -28,6 +26,41 @@ func init() {
|
||||
}
|
||||
|
||||
func opStart(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("start called")
|
||||
var err error
|
||||
p := cli.Program{}
|
||||
err = p.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = p.LoadTimerList(); err != nil {
|
||||
return err
|
||||
}
|
||||
var contexts, projects, strTags []string
|
||||
t := timertxt.NewTimer()
|
||||
if len(args) > 0 {
|
||||
if start, err := util.ParseFuzzyTime(args[0]); err == nil {
|
||||
t.StartDate = start
|
||||
args = args[1:]
|
||||
}
|
||||
}
|
||||
contexts, args = util.GetContextsFromSlice(args)
|
||||
projects, args = util.GetProjectsFromSlice(args)
|
||||
strTags, args = util.GetAdditionalTagsFromSlice(args)
|
||||
for _, v := range contexts {
|
||||
t.Contexts = append(t.Contexts, strings.TrimPrefix(v, "@"))
|
||||
}
|
||||
for _, v := range projects {
|
||||
t.Projects = append(t.Projects, strings.TrimPrefix(v, "+"))
|
||||
}
|
||||
for _, v := range strTags {
|
||||
tgPts := strings.Split(v, ":")
|
||||
t.AdditionalTags[tgPts[0]] = tgPts[1]
|
||||
}
|
||||
|
||||
p.TimerList.AddTimer(t)
|
||||
if err := p.WriteTimerList(); err != nil {
|
||||
return fmt.Errorf("Error writing timer list: %w", err)
|
||||
}
|
||||
fmt.Println("Started: ", util.TimerToString(t))
|
||||
return nil
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ func opStatus(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
if err := p.LoadTimerList(); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("Error loading timer list: %w", err)
|
||||
}
|
||||
if len(*p.TimerList.GetActiveTimers()) == 0 {
|
||||
fmt.Println("No timers running")
|
||||
|
58
cmd/stop.go
58
cmd/stop.go
@ -6,21 +6,20 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.bullercodeworks.com/brian/gime/cli"
|
||||
"git.bullercodeworks.com/brian/gime/util"
|
||||
"git.bullercodeworks.com/brian/go-timertxt"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// stopCmd represents the stop command
|
||||
var stopCmd = &cobra.Command{
|
||||
Use: "stop",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
RunE: opStop,
|
||||
Short: "Stop a timer",
|
||||
RunE: opStop,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -28,6 +27,47 @@ func init() {
|
||||
}
|
||||
|
||||
func opStop(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("stop called")
|
||||
var err error
|
||||
p := cli.Program{}
|
||||
err = p.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = p.LoadTimerList(); err != nil {
|
||||
return err
|
||||
}
|
||||
var wrk time.Time
|
||||
end := time.Now()
|
||||
id := -1
|
||||
|
||||
if len(args) > 0 {
|
||||
if wrk, err = util.ParseFuzzyTime(args[0]); err != nil {
|
||||
id, err = strconv.Atoi(args[0])
|
||||
} else {
|
||||
end = wrk
|
||||
args = args[1:]
|
||||
}
|
||||
}
|
||||
fmt.Println("Stopping at : " + end.Format(time.RFC3339))
|
||||
var timerIds []int
|
||||
if id == -1 {
|
||||
for _, v := range *p.TimerList.GetActiveTimers() {
|
||||
timerIds = append(timerIds, v.Id)
|
||||
}
|
||||
} else {
|
||||
timerIds = append(timerIds, id)
|
||||
}
|
||||
for _, v := range timerIds {
|
||||
var stopped *timertxt.Timer
|
||||
if stopped, err = p.TimerList.GetTimer(v); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
stopped.FinishDate = end
|
||||
stopped.Finished = true
|
||||
fmt.Println("Stopped Timer:", util.TimerToFriendlyString(stopped))
|
||||
}
|
||||
if err = p.WriteTimerList(); err != nil {
|
||||
return fmt.Errorf("Error writing timer list: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -6,21 +6,19 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.bullercodeworks.com/brian/gime/cli"
|
||||
"git.bullercodeworks.com/brian/gime/util"
|
||||
"git.bullercodeworks.com/brian/go-timertxt"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// switchCmd represents the switch command
|
||||
var switchCmd = &cobra.Command{
|
||||
Use: "switch",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
RunE: opSwitch,
|
||||
Short: "Stop the current timer and start a new one copying the last one's parameters",
|
||||
RunE: opSwitch,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -28,6 +26,31 @@ func init() {
|
||||
}
|
||||
|
||||
func opSwitch(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("switch called")
|
||||
return nil
|
||||
var err error
|
||||
p := cli.Program{}
|
||||
err = p.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = p.LoadTimerList(); err != nil {
|
||||
return err
|
||||
}
|
||||
var timerIds []int
|
||||
end := time.Now()
|
||||
// Stop all running timers and start a new one with the given args
|
||||
for _, v := range *p.TimerList.GetActiveTimers() {
|
||||
timerIds = append(timerIds, v.Id)
|
||||
}
|
||||
fmt.Print("Stopping ", timerIds, "\n")
|
||||
for _, v := range timerIds {
|
||||
var stopped *timertxt.Timer
|
||||
if stopped, err = p.TimerList.GetTimer(v); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
continue
|
||||
}
|
||||
stopped.FinishDate = end
|
||||
stopped.Finished = true
|
||||
fmt.Println("Stopped Timer:", util.TimerToFriendlyString(stopped))
|
||||
}
|
||||
return opStart(cmd, args)
|
||||
}
|
||||
|
@ -7,20 +7,16 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.bullercodeworks.com/brian/gime/cli"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// toggleCmd represents the toggle command
|
||||
var toggleCmd = &cobra.Command{
|
||||
Use: "toggle",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
RunE: opToggle,
|
||||
Short: "Toggle the most recent timer on and off",
|
||||
RunE: opToggle,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -28,6 +24,37 @@ func init() {
|
||||
}
|
||||
|
||||
func opToggle(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("toggle called")
|
||||
return nil
|
||||
var err error
|
||||
p := cli.Program{}
|
||||
err = p.Initialize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = p.LoadTimerList(); err != nil {
|
||||
return err
|
||||
}
|
||||
wrk, err := p.GetMostRecentTimer()
|
||||
if err != nil {
|
||||
fmt.Print("{\"icon\":\"time\",\"state\":\"Critical\", \"text\": \"Error loading timer entry\"}")
|
||||
return nil
|
||||
}
|
||||
var startArgs []string
|
||||
if wrk.Finished {
|
||||
// Start a new timer with the same data
|
||||
for _, v := range wrk.Contexts {
|
||||
startArgs = append(startArgs, "@"+v)
|
||||
}
|
||||
for _, v := range wrk.Projects {
|
||||
startArgs = append(startArgs, "+"+v)
|
||||
}
|
||||
if viper.GetBool("copytags") {
|
||||
for k, v := range wrk.AdditionalTags {
|
||||
startArgs = append(startArgs, k+":"+v)
|
||||
}
|
||||
}
|
||||
return opStart(cmd, startArgs)
|
||||
} else {
|
||||
// Stop the active timer
|
||||
return opStop(cmd, []string{})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user