diff options
author | Alexander Kiryukhin <a.kiryukhin@mail.ru> | 2021-12-05 17:46:53 +0300 |
---|---|---|
committer | Alexander Kiryukhin <a.kiryukhin@mail.ru> | 2021-12-05 17:46:53 +0300 |
commit | bcdbe68ecde049ef62343584bcc26840322c4864 (patch) | |
tree | 4a02b4da5db29ab3f3526ff475db859293a97646 /cmd |
Initial commit
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/add.go | 48 | ||||
-rw-r--r-- | cmd/ls.go | 66 | ||||
-rw-r--r-- | cmd/root.go | 68 | ||||
-rw-r--r-- | cmd/start.go | 37 | ||||
-rw-r--r-- | cmd/stop.go | 38 |
5 files changed, 257 insertions, 0 deletions
diff --git a/cmd/add.go b/cmd/add.go new file mode 100644 index 0000000..b8979b0 --- /dev/null +++ b/cmd/add.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "strings" + + "github.com/spf13/cobra" +) + +// addCmd represents the add command +var addCmd = &cobra.Command{ + Use: "add", + Short: "Add activity", + Long: `Add new activity that we can track`, + Run: func(cmd *cobra.Command, args []string) { + titles := []string{} + tags := []string{} + contexts := []string{} + for _, s := range args { + if len(s) == 0 { + continue + } + if s[0:1] == "#" { + if len(s[1:]) >= 1 { + tags = append(tags, s[1:]) + continue + } + } + if s[0:1] == "@" { + if len(s[1:]) >= 1 { + contexts = append(contexts, s[1:]) + continue + } + } + titles = append(titles, s) + } + title := strings.Join(titles, " ") + activityID, err := tr.Add(title, tags, contexts) + if err != nil { + cmd.PrintErr(err) + return + } + cmd.Printf("Activity #%d added! Now you can start it.\n", activityID) + }, +} + +func init() { + rootCmd.AddCommand(addCmd) +} diff --git a/cmd/ls.go b/cmd/ls.go new file mode 100644 index 0000000..3fe7244 --- /dev/null +++ b/cmd/ls.go @@ -0,0 +1,66 @@ +package cmd + +import ( + "strings" + + "github.com/spf13/cobra" +) + +// lsCmd represents the ls command +var lsCmd = &cobra.Command{ + Use: "ls", + Short: "List activities", + Long: `List started (or all by -a flag) activities`, + Run: func(cmd *cobra.Command, args []string) { + all, err := cmd.Flags().GetBool("all") + if err != nil { + cmd.PrintErr(err) + return + } + verbose, err := cmd.Flags().GetBool("verbose") + if err != nil { + cmd.PrintErr(err) + return + } + activities := tr.List(all) + if len(activities) == 0 { + cmd.Printf("There is no activities.\n") + return + } + if all { + cmd.Printf("Activities:\n") + } else { + cmd.Printf("Started activities:\n") + } + for _, activity := range activities { + cmd.Printf("%d. %s\n", activity.ID, activity.Title) + if len(activity.Tags) > 0 { + cmd.Printf("\tTags: %v\n", activity.Tags) + } + if len(activity.Context) > 0 { + cmd.Printf("\tContexts: %v\n", activity.Context) + } + cmd.Printf("\t%d timespans\n", len(activity.Spans)) + for i, span := range activity.Spans { + if !verbose && i < len(activity.Spans)-1 { + continue + } + stop := "now" + if span.Stop != nil { + stop = span.Stop.Format("15:04:05 2.1.2006") + } + if strings.Trim(span.Comment, " ") != "" { + cmd.Printf("\t%s — %s: \"%s\"\n", span.Start.Format("15:04:05 2.1.2006"), stop, span.Comment) + } else { + cmd.Printf("\t%s — %s\n", span.Start.Format("15:04:05 2.1.2006"), stop) + } + } + } + }, +} + +func init() { + rootCmd.AddCommand(lsCmd) + lsCmd.Flags().BoolP("all", "a", false, "List all activities. Only started by default") + lsCmd.Flags().BoolP("verbose", "v", false, "List all timespans. Only last by default") +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..ad372c1 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,68 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/afero" + "github.com/spf13/cobra" + + "github.com/spf13/viper" + + "github.com/neonxp/track/internal/tracker" +) + +var cfgFile string + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "track", + Short: "Track your work or personal activities", + Long: `Track time spent for any work or personal activities`, +} + +var tr *tracker.Tracker + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + fs := afero.NewOsFs() + var err error + tr, err = tracker.New(fs) + if err != nil { + panic(err) + return + } + cobra.CheckErr(rootCmd.Execute()) +} + +func init() { + cobra.OnInitialize(initConfig) + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.track.yaml)") + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := os.UserHomeDir() + cobra.CheckErr(err) + + // Search config in home directory with name ".track" (without extension). + viper.AddConfigPath(home) + viper.SetConfigType("yaml") + viper.SetConfigName(".track") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + } +} + diff --git a/cmd/start.go b/cmd/start.go new file mode 100644 index 0000000..a0ae4f1 --- /dev/null +++ b/cmd/start.go @@ -0,0 +1,37 @@ +package cmd + +import ( + "strconv" + "strings" + + "github.com/spf13/cobra" +) + +// startCmd represents the start command +var startCmd = &cobra.Command{ + Use: "start", + Short: "Start activity", + Long: `Start new timespan on activity`, + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + cmd.PrintErr("First argument must be activity id\n") + return + } + id, err := strconv.Atoi(args[0]) + if err != nil { + cmd.PrintErr("First argument must be activity id, got %s\n", args[0]) + return + } + comment := strings.Join(args[1:], " ") + if err := tr.Start(id, comment); err != nil { + cmd.PrintErr(err) + return + } + activity := tr.Activity(id) + cmd.Printf("Started new span for activity \"%s\".\n", activity.Title) + }, +} + +func init() { + rootCmd.AddCommand(startCmd) +} diff --git a/cmd/stop.go b/cmd/stop.go new file mode 100644 index 0000000..ac472cd --- /dev/null +++ b/cmd/stop.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "strconv" + + "github.com/spf13/cobra" + + "github.com/neonxp/track/internal/tracker" +) + +// stopCmd represents the stop command +var stopCmd = &cobra.Command{ + Use: "stop", + Short: "Stop activity", + Long: `Stop working on activity`, + Run: func(cmd *cobra.Command, args []string) { + activities := tr.List(false) + if len(args) != 0 { + id, err := strconv.Atoi(args[0]) + if err != nil { + cmd.PrintErr("First argument must be activity id, got %s.\n", args[0]) + return + } + activities = []*tracker.Activity{tr.Activity(id)} + } + for _, activity := range activities { + if err := tr.Stop(activity.ID); err != nil { + cmd.PrintErr(err) + return + } + cmd.Printf("Stopped activity \"%s\".\n", activity.Title) + } + }, +} + +func init() { + rootCmd.AddCommand(stopCmd) +} |