@@ 1,23 1,26 @@
module git.sr.ht/~ghost08/wt
-go 1.16
+go 1.17
require (
github.com/360EntSecGroup-Skylar/excelize v1.4.1
- github.com/alecthomas/kong v0.2.17
- github.com/emersion/go-message v0.14.1
- github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21
+ github.com/alecthomas/kong v0.2.22
+ github.com/emersion/go-message v0.15.0
+ github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac
github.com/emersion/go-smtp v0.15.0
+ github.com/gookit/color v1.5.0
+ github.com/posener/complete/v2 v2.0.1-alpha.13
+ github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
+)
+
+require (
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 // indirect
- github.com/gookit/color v1.4.2
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/martinlindhe/base36 v1.1.0 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/pkg/errors v0.9.1 // indirect
- github.com/posener/complete/v2 v2.0.1-alpha.13
github.com/posener/script v1.1.5 // indirect
- github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
- golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
+ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
)
@@ 4,19 4,28 @@ github.com/alecthomas/kong v0.2.16 h1:F232CiYSn54Tnl1sJGTeHmx4vJDNLVP2b9yCVMOQwH
github.com/alecthomas/kong v0.2.16/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
github.com/alecthomas/kong v0.2.17 h1:URDISCI96MIgcIlQyoCAlhOmrSw6pZScBNkctg8r0W0=
github.com/alecthomas/kong v0.2.17/go.mod h1:ka3VZ8GZNPXv9Ov+j4YNLkI8mTuhXyr/0ktSlqIydQQ=
+github.com/alecthomas/kong v0.2.22 h1:lRcQYT2/yJ+coDNA5ws0mRL0pwSqjbP/6AcRkyKhomk=
+github.com/alecthomas/kong v0.2.22/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0=
+github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emersion/go-message v0.14.1 h1:j3rj9F+7VtXE9c8P5UHBq8FTHLW/AjnmvSRre6AHoYI=
github.com/emersion/go-message v0.14.1/go.mod h1:N1JWdZQ2WRUalmdHAX308CWBq747VJ8oUorFI3VCBwU=
+github.com/emersion/go-message v0.15.0 h1:urgKGqt2JAc9NFJcgncQcohHdiYb803YTH9OQwHBHIY=
+github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
+github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac h1:tn/OQ2PmwQ0XFVgAHfjlLyqMewry25Rz7jWnVoh4Ggs=
+github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-smtp v0.15.0 h1:3+hMGMGrqP/lqd7qoxZc1hTU8LY8gHV9RFGWlqSDmP8=
github.com/emersion/go-smtp v0.15.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 h1:IbFBtwoTQyw0fIM5xv1HF+Y+3ZijDR839WMulgxCcUY=
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
+github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw=
+github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ 55,7 64,10 @@ golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 h1:C+AwYEtBp/VQwoLntUmQ/yx3MS9vmZaKNdw5eOpoQe8=
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.5-0.20201125200606-c27b9fd57aec/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ 18,35 18,38 @@ import (
var CLI struct {
Start struct {
- Project string `arg required help:"project name"`
- Description string `arg required help:"task description"`
- } `cmd help:"start a new entry"`
- End struct{} `cmd help:"end a running entry"`
- Status struct{} `cmd help:"print the running entry" default:"1"`
+ Project string `arg:"" required:"" help:"project name"`
+ Description string `arg:"" required:"" help:"task description"`
+ } `cmd:"" help:"start a new entry"`
+ End struct{} `cmd:"" help:"end a running entry"`
+ Status struct{} `cmd:"" help:"print the running entry" default:"1"`
Report struct {
- Month string `arg optional help:"select the month to export in format: YYYYMM (default is the previous month)"`
- Output string `optional short:"o" default:"report.xlsx" help:"output file path"`
- } `cmd help:"export data to a spreadsheet"`
+ Month string `arg:"" optional:"" help:"select the month to export in format: YYYYMM (default is the previous month)"`
+ Output string `optional:"" short:"o" default:"report.xlsx" help:"output file path"`
+ } `cmd:"" help:"export data to a spreadsheet"`
SendReport struct {
- Month string `arg optional help:"select the month to export in format: YYYYMM (default is the previous month)"`
- Output string `optional short:"o" default:"report.xlsx" help:"attachment file name"`
+ Month string `arg:"" optional:"" help:"select the month to export in format: YYYYMM (default is the previous month)"`
+ Output string `optional:"" short:"o" default:"report.xlsx" help:"attachment file name"`
SmtpServer string `help:"specifies the outgoing SMTP server to use" env:"SMTP_SERVER"`
SmtpPort int `default:"25" help:"specifies a port different from the default port (SMTP servers typically listen to smtp port 25, but may also listen to submission port 587, or the common SSL smtp port 465)" env:"SMTP_PORT"`
SmtpAuth string `enum:",PLAIN,LOGIN" help:"SMTP authentication mechanism" env:"SMTP_AUTH"`
- SmtpUser string `optional help:"username for SMTP-AUTH. if a username is not specified, then authentication is not attempted." env:"SMTP_USER"`
- SmtpPass string `optional help:"password for SMTP-AUTH. If no argument is specified, then the empty string is used as the password" env:"SMTP_PASS"`
- SmtpPassCmd string `optional help:"command that prints the password for SMTP-AUTH" env:"SMTP_PASS_CMD"`
- To []string `required help:"specify the primary recipients of the emails generated"`
- From string `required help:"specify the sender of the emails" env:"SENDMAIL_FROM"`
- } `cmd help:"sends the report by email"`
+ SmtpUser string `optional:"" help:"username for SMTP-AUTH. if a username is not specified, then authentication is not attempted." env:"SMTP_USER"`
+ SmtpPass string `optional:"" help:"password for SMTP-AUTH. If no argument is specified, then the empty string is used as the password" env:"SMTP_PASS"`
+ SmtpPassCmd string `optional:"" help:"command that prints the password for SMTP-AUTH" env:"SMTP_PASS_CMD"`
+ To []string `required:"" help:"specify the primary recipients of the emails generated"`
+ From string `required:"" help:"specify the sender of the emails" env:"SENDMAIL_FROM"`
+ } `cmd:"" help:"sends the report by email"`
Merge struct {
- Path string `arg required type:"path" help:"path to a data file to merge with the default wt data file"`
- } `cmd help:"merge an external wt data file"`
- Edit struct{} `cmd help:"opens up the default editor for the wt data fiel"`
- DataFile string `optional short:"d" help:"path to the wt data file (default:$HOME/.local/wt.data)" type:"path"`
+ Path string `arg:"" required:"" type:"path" help:"path to a data file to merge with the default wt data file"`
+ } `cmd:"" help:"merge an external wt data file"`
+ Edit struct{} `cmd:"" help:"opens up the default editor for the wt data fiel"`
+ Bars struct {
+ Month string `arg:"" optional:"" help:"select the month to export in format: YYYYMM (default is the current month)"`
+ } `cmd:"" help:"shows a bar chart of the month"`
+ DataFile string `optional:"" short:"d" help:"path to the wt data file (default:$HOME/.local/wt.data)" type:"path"`
InstallCompletions struct {
Uninstall bool
- } `cmd help:"install shell completions"`
+ } `cmd:"" help:"install shell completions"`
}
func main() {
@@ 83,6 86,9 @@ func main() {
Args: predict.Files("*"),
},
"edit": {},
+ "bars": {
+ Args: &monthsPredictor{},
+ },
},
Flags: map[string]complete.Predictor{
"data-file": predict.Files("*"),
@@ 115,6 121,8 @@ func main() {
err = merge()
case "edit":
err = edit()
+ case "bars", "bars <month>":
+ err = bars()
case "install-completions":
err = install.Install("wt")
default:
@@ 212,8 220,15 @@ func end() error {
if err := saveEntries(es); err != nil {
return err
}
- //TODO prettier print
- fmt.Printf("Ending entry %s", last)
+ fmt.Printf(
+ "\n %s\n %s\t\t%s\n %s: %s\t%s",
+ color.Style{color.FgLightWhite, color.OpBold}.Render("ending entry:"),
+ color.FgCyan.Render(last.Project),
+ color.FgLightWhite.Render(last.Description),
+ color.Style{color.FgLightWhite, color.OpBold}.Render("start"),
+ last.Start.Format("15:04:05"),
+ color.FgMagenta.Sprint(time.Now().Sub(last.Start)),
+ )
return nil
}