From 83888e75cabf2db0c3118231df4a382291f207d8 Mon Sep 17 00:00:00 2001 From: Dhruv Thakur Date: Sat, 24 Aug 2024 11:03:54 +0200 Subject: [PATCH] chore: add more linters +dependency upgrades --- .golangci.yml | 21 +++ cmd/root.go | 79 ++++---- go.mod | 41 ++--- go.sum | 106 +++++------ internal/utils/markdown.go | 8 +- internal/utils/markdown_test.go | 4 +- main.go | 13 +- ui/colors.go | 310 ++++++++++++++++---------------- ui/gh.go | 2 +- ui/initial.go | 9 +- ui/model.go | 4 +- ui/navigation.go | 29 +-- ui/types.go | 27 +-- ui/ui.go | 1 - ui/update.go | 27 +-- ui/view.go | 9 +- 16 files changed, 349 insertions(+), 341 deletions(-) create mode 100644 .golangci.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..c52fd12 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,21 @@ +linters: + enable: + - errcheck + - errname + - errorlint + - goconst + - gofumpt + - gosimple + - govet + - ineffassign + - nilerr + - prealloc + - predeclared + - revive + - rowserrcheck + - sqlclosecheck + - staticcheck + - unconvert + - unused + - usestdlibvars + - wastedassign diff --git a/cmd/root.go b/cmd/root.go index 4f60e38..ade97e5 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -21,7 +21,7 @@ const ( envPrefix = "PRS" author = "@dhth" projectHomePage = "https://github.com/dhth/prs" - issuesUrl = "https://github.com/dhth/prs/issues" + issuesURL = "https://github.com/dhth/prs/issues" configFileName = "prs/prs.yml" defaultSearchQuery = "type:pr author:@me sort:updated-desc state:open" defaultPRNum = 20 @@ -29,24 +29,45 @@ const ( ) var ( - errModeIncorrect = errors.New("incorrect mode provided") - errConfigFileDoesntExist = errors.New("config file does not exist") - errNoReposProvided = errors.New("no repos were provided") + errCouldntGetHomeDir = errors.New("couldn't get home directory") + errCouldntGetConfigDir = errors.New("couldn't get config directory") + errModeIncorrect = errors.New("incorrect mode provided") + errConfigFileDoesntExist = errors.New("config file does not exist") + errNoReposProvided = errors.New("no repos were provided") + errIncorrectRepoProvided = errors.New("incorrect repo provided") + errCouldntSetupGithubClient = errors.New("couldn't set up a Github Client") ) -func Execute(version string) { - rootCmd, err := NewRootCommand(version) +var reportIssueMsg = fmt.Sprintf("Let %s know about this error via %s.", author, issuesURL) +func Execute(version string) error { + rootCmd, err := NewRootCommand(version) if err != nil { - fmt.Fprintf(os.Stderr, "Error: %s\n", err) - os.Exit(1) + fmt.Printf("Error: %s\n", err.Error()) + switch { + case errors.Is(err, errCouldntGetHomeDir), errors.Is(err, errCouldntGetConfigDir): + fmt.Printf(` +This is a fatal error; use --config-path to specify config file path manually. +%s +`, reportIssueMsg) + } + return err } - _ = rootCmd.Execute() + err = rootCmd.Execute() + + switch { + case errors.Is(err, errCouldntSetupGithubClient): + fmt.Printf(` +If the error is due to misconfigured authentication, you can fix that by either of the following: +- Provide a valid Github token via $GH_TOKEN +- Have an authenticated instance of gh (https://github.com/cli/cli) available +`) + } + return err } func NewRootCommand(version string) (*cobra.Command, error) { - var ( configFilePath string configPathFull string @@ -84,7 +105,7 @@ Project home page: %s Args: cobra.MaximumNArgs(0), SilenceUsage: true, Version: version, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { configPathFull = expandTilde(configFilePath) if filepath.Ext(configPathFull) != ".yml" { @@ -122,7 +143,7 @@ Project home page: %s if mode == ui.RepoMode { var reposToUse []string // pretty ugly hack to get around the fact that - // v.GetStringSlice("repos") always seems to prioritise the config file + // v.GetStringSlice("repos") always seems to prioritize the config file if len(repoStrs) > 0 && len(repoStrs[0]) > 0 && !strings.HasPrefix(repoStrs[0], "[") { reposToUse = repoStrs } else { @@ -137,7 +158,7 @@ Project home page: %s repoEls := strings.Split(r, "/") // TODO: there can be more validations done here, maybe regex based if len(repoEls) != 2 { - return fmt.Errorf("Incorrect repo provided: %s", r) + return fmt.Errorf("%w: %s", errIncorrectRepoProvided, r) } repos = append(repos, ui.Repo{ @@ -155,18 +176,11 @@ Project home page: %s ghClient, err = ghapi.NewGraphQLClient(opts) if err != nil { - return fmt.Errorf(`Couldn't set up a Github client. - -If the error is due to misconfigured authentication, you can fix that by either of the following: -- Provide a valid Github token via $GH_TOKEN -- Have an authenticated instance of gh (https://github.com/cli/cli) available - -Underlying error: %s`, err.Error()) + return fmt.Errorf("%w: %s", errCouldntSetupGithubClient, err.Error()) } return nil }, - RunE: func(cmd *cobra.Command, args []string) error { - + RunE: func(_ *cobra.Command, _ []string) error { config := ui.Config{ PRCount: prNum, Repos: repos, @@ -181,11 +195,7 @@ Underlying error: %s`, err.Error()) ros := runtime.GOOS userCfgDir, err := os.UserConfigDir() if err != nil { - return nil, fmt.Errorf(`Couldn't get your default config directory. This is a fatal error; -use --config-path to specify config file path manually. -Let %s know about this via %s. - -Error: %s`, author, issuesUrl, err) + return nil, fmt.Errorf("%w: %s", errCouldntGetConfigDir, err.Error()) } var defaultConfigFilePath string @@ -196,11 +206,7 @@ Error: %s`, author, issuesUrl, err) // to use ~/.config instead of $HOME/Library/Application Support hd, err := os.UserHomeDir() if err != nil { - return nil, fmt.Errorf(`Couldn't get your home directory. This is a fatal error; -use --config-path to specify config file path manually -Let %s know about this via %s. - -Error: %s`, author, issuesUrl, err) + return nil, fmt.Errorf("%w: %s", errCouldntGetHomeDir, err.Error()) } defaultConfigFilePath = filepath.Join(hd, ".config", configFileName) } @@ -223,11 +229,9 @@ func initializeConfig(cmd *cobra.Command, configFile string) (*viper.Viper, erro v.SetConfigType("yaml") v.AddConfigPath(filepath.Dir(configFile)) - var err error - if err = v.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); !ok { - return v, err - } + err := v.ReadInConfig() + if err != nil && !errors.As(err, &viper.ConfigFileNotFoundError{}) { + return v, err } v.SetEnvPrefix(envPrefix) @@ -245,7 +249,6 @@ func initializeConfig(cmd *cobra.Command, configFile string) (*viper.Viper, erro func bindFlags(cmd *cobra.Command, v *viper.Viper) error { var err error cmd.Flags().VisitAll(func(f *pflag.Flag) { - if !f.Changed && v.IsSet(f.Name) { val := v.Get(f.Name) fErr := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)) diff --git a/go.mod b/go.mod index 12865d2..8c1b338 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,14 @@ module github.com/dhth/prs go 1.22.5 require ( - github.com/charmbracelet/bubbles v0.18.0 - github.com/charmbracelet/bubbletea v0.26.6 - github.com/charmbracelet/glamour v0.7.0 - github.com/charmbracelet/lipgloss v0.12.1 + github.com/charmbracelet/bubbles v0.19.0 + github.com/charmbracelet/bubbletea v0.27.1 + github.com/charmbracelet/glamour v0.8.0 + github.com/charmbracelet/lipgloss v0.13.0 github.com/cli/go-gh/v2 v2.9.0 github.com/cli/shurcooL-graphql v0.0.4 github.com/dustin/go-humanize v1.0.1 - github.com/muesli/termenv v0.15.2 + github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 @@ -22,13 +22,11 @@ require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.1.4 // indirect - github.com/charmbracelet/x/input v0.1.3 // indirect - github.com/charmbracelet/x/term v0.1.1 // indirect - github.com/charmbracelet/x/windows v0.1.2 // indirect + github.com/charmbracelet/x/ansi v0.2.3 // indirect + github.com/charmbracelet/x/term v0.2.0 // indirect github.com/cli/safeexec v1.0.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dlclark/regexp2 v1.11.2 // indirect + github.com/dlclark/regexp2 v1.11.4 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gorilla/css v1.0.1 // indirect @@ -45,29 +43,26 @@ require ( github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sahilm/fuzzy v0.1.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cast v1.7.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/thlib/go-timezone-local v0.0.3 // indirect - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yuin/goldmark v1.7.4 // indirect github.com/yuin/goldmark-emoji v1.0.3 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4e74b33..10cbd20 100644 --- a/go.sum +++ b/go.sum @@ -8,24 +8,24 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= +github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= -github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= -github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s= -github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= -github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng= -github.com/charmbracelet/glamour v0.7.0/go.mod h1:jUMh5MeihljJPQbJ/wf4ldw2+yBP59+ctV36jASy7ps= -github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= -github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= -github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= -github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= -github.com/charmbracelet/x/input v0.1.3 h1:oy4TMhyGQsYs/WWJwu1ELUMFnjiUAXwtDf048fHbCkg= -github.com/charmbracelet/x/input v0.1.3/go.mod h1:1gaCOyw1KI9e2j00j/BBZ4ErzRZqa05w0Ghn83yIhKU= -github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= -github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw= -github.com/charmbracelet/x/windows v0.1.2 h1:Iumiwq2G+BRmgoayww/qfcvof7W/3uLoelhxojXlRWg= -github.com/charmbracelet/x/windows v0.1.2/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ= +github.com/charmbracelet/bubbles v0.19.0 h1:gKZkKXPP6GlDk6EcfujDK19PCQqRjaJZQ7QRERx1UF0= +github.com/charmbracelet/bubbles v0.19.0/go.mod h1:WILteEqZ+krG5c3ntGEMeG99nCupcuIk7V0/zOP0tOA= +github.com/charmbracelet/bubbletea v0.27.1 h1:/yhaJKX52pxG4jZVKCNWj/oq0QouPdXycriDRA6m6r8= +github.com/charmbracelet/bubbletea v0.27.1/go.mod h1:xc4gm5yv+7tbniEvQ0naiG9P3fzYhk16cTgDZQQW6YE= +github.com/charmbracelet/glamour v0.8.0 h1:tPrjL3aRcQbn++7t18wOpgLyl8wrOHUEDS7IZ68QtZs= +github.com/charmbracelet/glamour v0.8.0/go.mod h1:ViRgmKkf3u5S7uakt2czJ272WSg2ZenlYEZXT2x7Bjw= +github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= +github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= +github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY= +github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q= +github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= +github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= +github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= github.com/cli/go-gh/v2 v2.9.0 h1:D3lTjEneMYl54M+WjZ+kRPrR5CEJ5BHS05isBPOV3LI= github.com/cli/go-gh/v2 v2.9.0/go.mod h1:MeRoKzXff3ygHu7zP+NVTT+imcHW6p3tpuxHAzRM2xE= github.com/cli/safeexec v1.0.1 h1:e/C79PbXF4yYTN/wauC4tviMxEV13BwljGj0N9j+N00= @@ -33,12 +33,11 @@ github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5 github.com/cli/shurcooL-graphql v0.0.4 h1:6MogPnQJLjKkaXPyGqPRXOI2qCsQdqNfUY1QSJu2GuY= github.com/cli/shurcooL-graphql v0.0.4/go.mod h1:3waN4u02FiZivIV+p1y4d0Jo1jc6BViMA73C+sZo2fk= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlclark/regexp2 v1.11.2 h1:/u628IuisSTwri5/UKloiIsH8+qF2Pu7xEQX+yIKg68= -github.com/dlclark/regexp2 v1.11.2/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= +github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= @@ -47,8 +46,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= @@ -75,7 +74,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= @@ -89,13 +87,10 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= -github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= -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/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg= +github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -105,8 +100,8 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= @@ -115,56 +110,44 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/thlib/go-timezone-local v0.0.3 h1:ie5XtZWG5lQ4+1MtC5KZ/FeWlOKzW2nPoUnXYUbV/1s= github.com/thlib/go-timezone-local v0.0.3/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark-emoji v1.0.3 h1:aLRkLHOuBR2czCY4R8olwMjID+tENfhyFDMCRhbIQY4= github.com/yuin/goldmark-emoji v1.0.3/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -172,6 +155,5 @@ gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/utils/markdown.go b/internal/utils/markdown.go index 677b00c..251e001 100644 --- a/internal/utils/markdown.go +++ b/internal/utils/markdown.go @@ -7,14 +7,12 @@ import ( "github.com/muesli/termenv" ) -var ( - //go:embed assets/gruvbox.json - glamourJsonBytes []byte -) +//go:embed assets/gruvbox.json +var glamourJSONBytes []byte func GetMarkDownRenderer(wrap int) (*glamour.TermRenderer, error) { return glamour.NewTermRenderer( - glamour.WithStylesFromJSONBytes(glamourJsonBytes), + glamour.WithStylesFromJSONBytes(glamourJSONBytes), glamour.WithColorProfile(termenv.TrueColor), glamour.WithWordWrap(wrap), ) diff --git a/internal/utils/markdown_test.go b/internal/utils/markdown_test.go index 64d6d68..7093df0 100644 --- a/internal/utils/markdown_test.go +++ b/internal/utils/markdown_test.go @@ -9,7 +9,7 @@ import ( ) func TestGetGlamourStyleFromFile(t *testing.T) { - gotOption := glamour.WithStylesFromJSONBytes(glamourJsonBytes) + gotOption := glamour.WithStylesFromJSONBytes(glamourJSONBytes) renderer, err := glamour.NewTermRenderer(gotOption) assert.NoError(t, err) assert.NotNil(t, renderer) @@ -19,6 +19,6 @@ func TestGetGlamourStyleFromFile(t *testing.T) { } func TestGlamourStylesFileIsValid(t *testing.T) { - got := json.Valid(glamourJsonBytes) + got := json.Valid(glamourJSONBytes) assert.True(t, got) } diff --git a/main.go b/main.go index bef32e2..2355177 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,14 @@ package main import ( - "github.com/dhth/prs/cmd" + "os" "runtime/debug" -) -var ( - version = "dev" + "github.com/dhth/prs/cmd" ) +var version = "dev" + func main() { v := version if version == "dev" { @@ -17,5 +17,8 @@ func main() { v = info.Main.Version } } - cmd.Execute(v) + err := cmd.Execute(v) + if err != nil { + os.Exit(1) + } } diff --git a/ui/colors.go b/ui/colors.go index f50c3d7..7d0b336 100644 --- a/ui/colors.go +++ b/ui/colors.go @@ -1,158 +1,156 @@ package ui -var ( - colors = []string{ - "#fe77a4", - "#d3869a", - "#ff4c8b", - "#ffb0c2", - "#df748b", - "#ff6682", - "#f19597", - "#d89e9d", - "#fc5260", - "#e96462", - "#ffb5a2", - "#febcac", - "#f0947b", - "#ff6334", - "#af9084", - "#ff5405", - "#e98658", - "#be876e", - "#ff803b", - "#fd780b", - "#ff9743", - "#e2ac85", - "#d67717", - "#d4925c", - "#ffb472", - "#fe9103", - "#de9644", - "#dc8b00", - "#ffb13c", - "#c9b094", - "#faca7d", - "#c7921f", - "#c6a267", - "#d3cdc5", - "#fabd2f", - "#dcad50", - "#daa402", - "#ffc20c", - "#fbcf56", - "#b29807", - "#e7c727", - "#c7b648", - "#9c9360", - "#cec48b", - "#bbb206", - "#ddd601", - "#d1cc74", - "#b8bb26", - "#acaa5e", - "#b4c800", - "#a6b92b", - "#a8b64c", - "#aab08a", - "#849843", - "#a8d906", - "#a8a9a3", - "#88b500", - "#add562", - "#a0d845", - "#8de107", - "#829b60", - "#7db839", - "#94bc63", - "#71c200", - "#b5d092", - "#6e9f3a", - "#51a100", - "#b5e48c", - "#8ce852", - "#59d412", - "#89d967", - "#59c435", - "#4ba539", - "#00b700", - "#00db04", - "#9ae089", - "#6fbd63", - "#83b87a", - "#5ddb63", - "#04eb4d", - "#7a9879", - "#00ce48", - "#05b64c", - "#9cdea5", - "#64d97f", - "#8fbc96", - "#4daa67", - "#00d977", - "#12b667", - "#6ed999", - "#63bd8f", - "#00d990", - "#a7e0c2", - "#0abe88", - "#90b4a6", - "#83a598", - "#5cab95", - "#b9d9cf", - "#03d7b3", - "#00b499", - "#6fd0bd", - "#1edacd", - "#19b7b2", - "#89cbce", - "#4dcfdb", - "#62a6ae", - "#90e1ef", - "#01aac0", - "#48cae4", - "#00ddff", - "#6ac1db", - "#00c3f9", - "#99bbcd", - "#149ccd", - "#6da2c6", - "#7bcaff", - "#07b1fa", - "#b4d4fb", - "#629fdb", - "#5aaaff", - "#0798ff", - "#4896ef", - "#bbd1ff", - "#9fb9f0", - "#949aab", - "#7b8ad5", - "#8498fb", - "#aaaffc", - "#8187dc", - "#ada7ff", - "#aba3ca", - "#d2c8f2", - "#a681fb", - "#b798f0", - "#c3a4e1", - "#ce8cf7", - "#c97df9", - "#e6a5f4", - "#e47cfb", - "#ffc6ff", - "#f344ff", - "#a882a7", - "#c57fbf", - "#ff4ded", - "#f081de", - "#fc69e6", - "#dfa5ca", - "#f646c1", - "#ceb4c3", - "#f27abe", - "#ae8c99", - "#ee91b6", - } -) +var colors = []string{ + "#fe77a4", + "#d3869a", + "#ff4c8b", + "#ffb0c2", + "#df748b", + "#ff6682", + "#f19597", + "#d89e9d", + "#fc5260", + "#e96462", + "#ffb5a2", + "#febcac", + "#f0947b", + "#ff6334", + "#af9084", + "#ff5405", + "#e98658", + "#be876e", + "#ff803b", + "#fd780b", + "#ff9743", + "#e2ac85", + "#d67717", + "#d4925c", + "#ffb472", + "#fe9103", + "#de9644", + "#dc8b00", + "#ffb13c", + "#c9b094", + "#faca7d", + "#c7921f", + "#c6a267", + "#d3cdc5", + "#fabd2f", + "#dcad50", + "#daa402", + "#ffc20c", + "#fbcf56", + "#b29807", + "#e7c727", + "#c7b648", + "#9c9360", + "#cec48b", + "#bbb206", + "#ddd601", + "#d1cc74", + "#b8bb26", + "#acaa5e", + "#b4c800", + "#a6b92b", + "#a8b64c", + "#aab08a", + "#849843", + "#a8d906", + "#a8a9a3", + "#88b500", + "#add562", + "#a0d845", + "#8de107", + "#829b60", + "#7db839", + "#94bc63", + "#71c200", + "#b5d092", + "#6e9f3a", + "#51a100", + "#b5e48c", + "#8ce852", + "#59d412", + "#89d967", + "#59c435", + "#4ba539", + "#00b700", + "#00db04", + "#9ae089", + "#6fbd63", + "#83b87a", + "#5ddb63", + "#04eb4d", + "#7a9879", + "#00ce48", + "#05b64c", + "#9cdea5", + "#64d97f", + "#8fbc96", + "#4daa67", + "#00d977", + "#12b667", + "#6ed999", + "#63bd8f", + "#00d990", + "#a7e0c2", + "#0abe88", + "#90b4a6", + "#83a598", + "#5cab95", + "#b9d9cf", + "#03d7b3", + "#00b499", + "#6fd0bd", + "#1edacd", + "#19b7b2", + "#89cbce", + "#4dcfdb", + "#62a6ae", + "#90e1ef", + "#01aac0", + "#48cae4", + "#00ddff", + "#6ac1db", + "#00c3f9", + "#99bbcd", + "#149ccd", + "#6da2c6", + "#7bcaff", + "#07b1fa", + "#b4d4fb", + "#629fdb", + "#5aaaff", + "#0798ff", + "#4896ef", + "#bbd1ff", + "#9fb9f0", + "#949aab", + "#7b8ad5", + "#8498fb", + "#aaaffc", + "#8187dc", + "#ada7ff", + "#aba3ca", + "#d2c8f2", + "#a681fb", + "#b798f0", + "#c3a4e1", + "#ce8cf7", + "#c97df9", + "#e6a5f4", + "#e47cfb", + "#ffc6ff", + "#f344ff", + "#a882a7", + "#c57fbf", + "#ff4ded", + "#f081de", + "#fc69e6", + "#dfa5ca", + "#f646c1", + "#ceb4c3", + "#f27abe", + "#ae8c99", + "#ee91b6", +} diff --git a/ui/gh.go b/ui/gh.go index 8d3d452..cb9591f 100644 --- a/ui/gh.go +++ b/ui/gh.go @@ -18,7 +18,7 @@ func getPRDataFromQuery(ghClient *ghapi.GraphQLClient, queryStr string, prCount if err != nil { return nil, err } - var prs []pr + var prs []pr //nolint:prealloc for _, edge := range query.Search.Edges { if edge.Node.Type != "PullRequest" { continue diff --git a/ui/initial.go b/ui/initial.go index bb7b015..b27f1c2 100644 --- a/ui/initial.go +++ b/ui/initial.go @@ -6,8 +6,11 @@ import ( ghapi "github.com/cli/go-gh/v2/pkg/api" ) -func InitialModel(ghClient *ghapi.GraphQLClient, config Config, mode Mode) model { +const ( + fetchingPRsTitle = "fetching PRs..." +) +func InitialModel(ghClient *ghapi.GraphQLClient, config Config, mode Mode) Model { prListDel := newPRListItemDel() prTLListDel := newPRTLListItemDel() @@ -16,7 +19,7 @@ func InitialModel(ghClient *ghapi.GraphQLClient, config Config, mode Mode) model prDetailsCurSectionCache := make(map[string]uint) - m := model{ + m := Model{ mode: mode, config: config, ghClient: ghClient, @@ -53,7 +56,7 @@ func InitialModel(ghClient *ghapi.GraphQLClient, config Config, mode Mode) model m.activePane = prListView } - m.prsList.Title = "fetching PRs..." + m.prsList.Title = fetchingPRsTitle m.prsList.SetStatusBarItemName("PR", "PRs") m.prsList.DisableQuitKeybindings() m.prsList.SetShowHelp(false) diff --git a/ui/model.go b/ui/model.go index 3d8673d..5011529 100644 --- a/ui/model.go +++ b/ui/model.go @@ -29,7 +29,7 @@ const ( RepoMode ) -type model struct { +type Model struct { mode Mode config Config ghClient *ghapi.GraphQLClient @@ -62,7 +62,7 @@ type model struct { prRevCurCmtNum uint } -func (m model) Init() tea.Cmd { +func (m Model) Init() tea.Cmd { var cmds []tea.Cmd cmds = append(cmds, hideHelp(time.Minute*1)) diff --git a/ui/navigation.go b/ui/navigation.go index 8464016..14c46a8 100644 --- a/ui/navigation.go +++ b/ui/navigation.go @@ -7,9 +7,12 @@ import ( const ( maxCommentsForNavIndicator = 8 + disabledSectionMarker = "◌" + inactiveSectionMarker = "◯" + activeSectionMarker = "●" ) -func (m *model) setPRDetailsContent(prDetails prDetails, section PRDetailSection) { +func (m *Model) setPRDetailsContent(prDetails prDetails, section PRDetailSection) { content := fmt.Sprintf(`# %s (%s/%s/pull/%d) `, prDetails.PRTitle, prDetails.Repository.Owner.Login, prDetails.Repository.Name, prDetails.Number, ) @@ -45,39 +48,39 @@ func (m *model) setPRDetailsContent(prDetails prDetails, section PRDetailSection sections := make([]string, len(PRDetailsSectionList)) for i := 0; i < len(PRDetailsSectionList); i++ { - sections[i] = "◯" + sections[i] = inactiveSectionMarker } if prDetails.Body == "" { - sections[PRDescription] = "◌" + sections[PRDescription] = disabledSectionMarker } // not foolproof, but should work in most cases // func (pr prDetails) Checks() will return with an appropriate message in // that case if !(len(prDetails.LastCommit.Nodes) > 0 && prDetails.LastCommit.Nodes[0].Commit.StatusCheckRollup != nil) { - sections[PRChecks] = "◌" + sections[PRChecks] = disabledSectionMarker } if len(prDetails.IssueReferences.Nodes) == 0 { - sections[PRReferences] = "◌" + sections[PRReferences] = disabledSectionMarker } if len(prDetails.Files.Nodes) == 0 { - sections[PRFilesChanged] = "◌" + sections[PRFilesChanged] = disabledSectionMarker } if len(prDetails.Commits.Nodes) == 0 { - sections[PRCommits] = "◌" + sections[PRCommits] = disabledSectionMarker } if len(prDetails.Comments.Nodes) == 0 { - sections[PRComments] = "◌" + sections[PRComments] = disabledSectionMarker } - sections[section] = "●" + sections[section] = activeSectionMarker m.prDetailsTitle = fmt.Sprintf("PR Details%s", " "+strings.Join(sections, " ")) m.prDetailsVP.GotoTop() } -func (m *model) GoToPRDetailSection(section uint) { +func (m *Model) GoToPRDetailSection(section uint) { if m.prDetailsCurrentSection == section { return } @@ -121,7 +124,7 @@ func (m *model) GoToPRDetailSection(section uint) { m.prDetailsCurrentSection = section } -func (m *model) setPRReviewCmt(tlItem *prTLItem, commentNum uint) { +func (m *Model) setPRReviewCmt(tlItem *prTLItem, commentNum uint) { revCmts := tlItem.PullRequestReview.Comments.Nodes var sectionsStr string @@ -130,9 +133,9 @@ func (m *model) setPRReviewCmt(tlItem *prTLItem, commentNum uint) { } else if len(revCmts) > 1 { sections := make([]string, len(revCmts)) for i := 0; i < len(revCmts); i++ { - sections[i] = "◯" + sections[i] = inactiveSectionMarker } - sections[commentNum] = "●" + sections[commentNum] = activeSectionMarker sectionsStr = " " + strings.Join(sections, " ") } diff --git a/ui/types.go b/ui/types.go index 0ab9b81..89b0c6b 100644 --- a/ui/types.go +++ b/ui/types.go @@ -51,6 +51,7 @@ const ( statusCheckContextsCount = 50 timeFormat = "2006/01/02 15:04" mergeableConflicting = "CONFLICTING" + noChecksHeader = "## No Checks" ) type terminalDetails struct { @@ -114,7 +115,7 @@ type pr struct { Author struct { Login string } - Url string + URL string Additions int Deletions int Reviews struct { @@ -185,7 +186,7 @@ type prDetails struct { Nodes []struct { Number int Title string - Url string + URL string } } `graphql:"closingIssuesReferences (first: $issuesCount)"` Participants struct { @@ -276,7 +277,7 @@ type prReviewComment struct { Outdated bool DiffHunk string Path string - Url string + URL string } type prSearchQuery struct { @@ -301,7 +302,7 @@ type prDetailsQuery struct { type prTLItem struct { Type string `graphql:"type: __typename"` PullRequestCommit struct { - Url string + URL string Commit struct { CommittedDate time.Time MessageHeadline string @@ -323,7 +324,7 @@ type prTLItem struct { } AfterCommit struct { AbbreviatedOid string - Url string + URL string MessageHeadline string } } `graphql:"... on HeadRefForcePushedEvent"` @@ -345,7 +346,7 @@ type prTLItem struct { } } `graphql:"... on ReviewRequestedEvent"` PullRequestReview struct { - Url string + URL string CreatedAt time.Time State string Body string @@ -359,7 +360,7 @@ type prTLItem struct { } `graphql:"... on PullRequestReview"` MergedEvent struct { CreatedAt time.Time - Url string + URL string MergeCommit struct { MessageHeadline string } `graphql:"mergeCommit: commit"` @@ -552,13 +553,13 @@ func (pr prDetails) Description() string { func (pr prDetails) Checks() string { if len(pr.LastCommit.Nodes) == 0 { - return "## No Checks" + return noChecksHeader } if pr.LastCommit.Nodes[0].Commit.StatusCheckRollup == nil { - return "## No Checks" + return noChecksHeader } if len(pr.LastCommit.Nodes[0].Commit.StatusCheckRollup.Contexts.Nodes) == 0 { - return "## No Checks" + return noChecksHeader } var checks []string @@ -599,7 +600,7 @@ func (pr prDetails) Checks() string { } if len(checks) == 0 { - return "## No Checks" + return noChecksHeader } return fmt.Sprintf(` @@ -616,7 +617,7 @@ func (pr prDetails) Checks() string { func (pr prDetails) References() string { issues := make([]string, len(pr.IssueReferences.Nodes)) for i, iss := range pr.IssueReferences.Nodes { - issues[i] = fmt.Sprintf("- `#%d`: %s (%s)", iss.Number, iss.Title, iss.Url) + issues[i] = fmt.Sprintf("- `#%d`: %s (%s)", iss.Number, iss.Title, iss.URL) } return fmt.Sprintf(` ## Referenced by @@ -676,7 +677,6 @@ func (pr prDetails) CommitsList() string { } func (pr prDetails) CommentsList() string { - comments := make([]string, len(pr.Comments.Nodes)) for i, c := range pr.Comments.Nodes { comments[i] = fmt.Sprintf("`@%s` (%s):\n\n%s", c.Author.Login, humanize.Time(c.UpdatedAt), c.Body) @@ -721,6 +721,7 @@ func (prRes prResult) FilterValue() string { func (ir prTLItemResult) Title() string { return ir.title } + func (ir prTLItemResult) Description() string { return ir.description } diff --git a/ui/ui.go b/ui/ui.go index d076705..e51dfb5 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -9,7 +9,6 @@ import ( ) func RenderUI(ghClient *ghapi.GraphQLClient, config Config, mode Mode) error { - if len(os.Getenv("DEBUG")) > 0 { f, err := tea.LogToFile("debug.log", "debug") if err != nil { diff --git a/ui/update.go b/ui/update.go index bd91449..414ee93 100644 --- a/ui/update.go +++ b/ui/update.go @@ -16,6 +16,7 @@ import ( const ( useHighPerformanceRenderer = false viewPortMoveLineCount = 5 + couldntGetPRDetailsMsg = "Couldn't get repo/pr details. Inform @dhth on Github." ) var ( @@ -25,7 +26,7 @@ var ( ErrPRDetailsNotCached = errors.New("PR details were not saved") ) -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd var cmds []tea.Cmd m.message = "" @@ -79,7 +80,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case QueryMode: cmds = append(cmds, fetchPRSFromQuery(m.ghClient, *m.config.Query, m.config.PRCount)) } - m.prsList.Title = "fetching PRs..." + m.prsList.Title = fetchingPRsTitle m.prsList.Styles.Title = m.prsList.Styles.Title.Background(lipgloss.Color(fetchingColor)) case prTLListView: @@ -112,7 +113,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case prListView: setTlCmd, ok := m.setTL() if !ok { - m.message = "Could't get repo/pr details. Inform @dhth on github." + m.message = couldntGetPRDetailsMsg } else { if setTlCmd != nil { cmds = append(cmds, setTlCmd) @@ -290,7 +291,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { break } - cmds = append(cmds, openURLInBrowser(pr.pr.Url)) + cmds = append(cmds, openURLInBrowser(pr.pr.URL)) case prTLListView, prTLItemDetailView: item, ok := m.prTLList.SelectedItem().(*prTLItemResult) if !ok { @@ -299,18 +300,18 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch item.item.Type { case tlItemPRCommit: - cmds = append(cmds, openURLInBrowser(item.item.PullRequestCommit.Url)) + cmds = append(cmds, openURLInBrowser(item.item.PullRequestCommit.URL)) case tlItemHeadRefForcePushed: - cmds = append(cmds, openURLInBrowser(item.item.HeadRefForcePushed.AfterCommit.Url)) + cmds = append(cmds, openURLInBrowser(item.item.HeadRefForcePushed.AfterCommit.URL)) case tlItemPRReview: - cmds = append(cmds, openURLInBrowser(item.item.PullRequestReview.Url)) + cmds = append(cmds, openURLInBrowser(item.item.PullRequestReview.URL)) case tlItemMergedEvent: - cmds = append(cmds, openURLInBrowser(item.item.MergedEvent.Url)) + cmds = append(cmds, openURLInBrowser(item.item.MergedEvent.URL)) } } case "ctrl+d": - if m.activePane != prListView && m.activePane != prTLListView && m.activePane != prTLItemDetailView { + if m.activePane != prListView && m.activePane != prTLListView { break } @@ -509,7 +510,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { break } - nextSection += 1 + nextSection++ } if !nextSectionFound { @@ -607,7 +608,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { break } - prevSection -= 1 + prevSection-- } m.setPRDetailsContent(prDetails, PRDetailsSectionList[prevSection]) @@ -741,7 +742,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.message = "Something went horribly wrong. Let @dhth know about this failure." } else { m.repoChosen = true - m.prsList.Title = "fetching PRs..." + m.prsList.Title = fetchingPRsTitle m.prsList.Styles.Title = m.prsList.Styles.Title.Background(lipgloss.Color(fetchingColor)) m.repoOwner = repoDetails[0] m.repoName = repoDetails[1] @@ -948,7 +949,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, tea.Batch(cmds...) } -func (m *model) setTL() (tea.Cmd, bool) { +func (m *Model) setTL() (tea.Cmd, bool) { var cmd tea.Cmd var repoOwner, repoName string var prNumber int diff --git a/ui/view.go b/ui/view.go index 40c05b7..5320826 100644 --- a/ui/view.go +++ b/ui/view.go @@ -8,9 +8,10 @@ import ( const ( viewPortWrapUpperLimit = 160 + vpNotReadyMsg = "Initializing..." ) -func (m model) View() string { +func (m Model) View() string { var content string var footer string @@ -28,7 +29,7 @@ func (m model) View() string { content = listStyle.Render(m.repoList.View()) case prDetailsView: if !m.prTLItemDetailVPReady { - content = "\n Initializing..." + content = vpNotReadyMsg } else { content = viewPortStyle.Render(fmt.Sprintf(" %s\n\n%s\n", prDetailsTitleStyle.Render(m.prDetailsTitle), @@ -37,7 +38,7 @@ func (m model) View() string { case prTLItemDetailView: var prRevCmtsVP string if !m.prTLItemDetailVPReady { - prRevCmtsVP = "\n Initializing..." + prRevCmtsVP = vpNotReadyMsg } else { prRevCmtsVP = viewPortStyle.Render(fmt.Sprintf(" %s\n\n%s\n", helpVPTitleStyle.Render(m.prTLItemDetailTitle), @@ -47,7 +48,7 @@ func (m model) View() string { case helpView: var helpVP string if !m.helpVPReady { - helpVP = "\n Initializing..." + helpVP = vpNotReadyMsg } else { helpVP = viewPortStyle.Render(fmt.Sprintf(" %s\n\n%s\n", helpVPTitleStyle.Render("Help"),