Skip to content

Commit

Permalink
refactor!(cmd): reorganize the commands (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
nobe4 authored Jul 20, 2024
1 parent e978b48 commit 6ab605d
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 160 deletions.
17 changes: 17 additions & 0 deletions internal/cmd/deprecated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cmd

import (
"github.com/spf13/cobra"
)

func init() {
rootCmd.AddCommand(&cobra.Command{
Use: "repl",
Short: "deprecated: use `gh-not --repl` instead",
})

rootCmd.AddCommand(&cobra.Command{
Use: "list",
Short: "deprecated: use 'gh-not' instead",
})
}
66 changes: 0 additions & 66 deletions internal/cmd/list.go

This file was deleted.

50 changes: 0 additions & 50 deletions internal/cmd/repl.go

This file was deleted.

106 changes: 82 additions & 24 deletions internal/cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,44 @@
package cmd

import (
"fmt"
"log/slog"

"github.com/nobe4/gh-not/internal/api"
"github.com/nobe4/gh-not/internal/api/file"
tea "github.com/charmbracelet/bubbletea"
"github.com/nobe4/gh-not/internal/api/github"
configPkg "github.com/nobe4/gh-not/internal/config"
"github.com/nobe4/gh-not/internal/jq"
"github.com/nobe4/gh-not/internal/logger"
managerPkg "github.com/nobe4/gh-not/internal/manager"
"github.com/nobe4/gh-not/internal/notifications"
"github.com/nobe4/gh-not/internal/version"
"github.com/nobe4/gh-not/internal/views/normal"
"github.com/spf13/cobra"
)

var (
verbosityFlag int
configPathFlag string
notificationDumpPath string
refreshFlag bool
noRefreshFlag bool
verbosityFlag int
configPathFlag string
filterFlag string
jqFlag string
repl bool

config *configPkg.Config
manager *managerPkg.Manager

rootCmd = &cobra.Command{
Use: "gh-not",
Short: "Manage your GitHub notifications",
Short: "Lists your GitHub notifications",
Version: version.String(),
Example: `
gh-not --config list
gh-not --no-refresh list
gh-not --from-file notifications.json list
gh-not sync --refresh --verbosity 4
gh-not --verbosity 2
gh-not --config /path/to/config.yaml
gh-not --filter '.repository.full_name | contains("nobe4")'
gh-not --repl
`,
PersistentPreRunE: setupGlobals,
SilenceErrors: true,
RunE: runRoot,
}
)

Expand All @@ -48,11 +52,11 @@ func init() {
rootCmd.PersistentFlags().IntVarP(&verbosityFlag, "verbosity", "v", 1, "Change logger verbosity")
rootCmd.PersistentFlags().StringVarP(&configPathFlag, "config", "c", "", "Path to the YAML config file")

rootCmd.PersistentFlags().StringVarP(&notificationDumpPath, "from-file", "", "", "Path to notification dump in JSON (generate with 'gh api /notifications')")
rootCmd.Flags().StringVarP(&filterFlag, "filter", "f", "", "Filter with a jq expression passed into a select(...) call")
rootCmd.Flags().StringVarP(&jqFlag, "jq", "q", "", "jq expression to run on the notification list")
rootCmd.MarkFlagsMutuallyExclusive("filter", "jq")

rootCmd.PersistentFlags().BoolVarP(&refreshFlag, "refresh", "r", false, "Force a refresh")
rootCmd.PersistentFlags().BoolVarP(&noRefreshFlag, "no-refresh", "R", false, "Prevent a refresh")
rootCmd.MarkFlagsMutuallyExclusive("refresh", "no-refresh")
rootCmd.Flags().BoolVarP(&repl, "repl", "", false, "Start a REPL with the notifications list")
}

func setupGlobals(cmd *cobra.Command, args []string) error {
Expand All @@ -62,25 +66,79 @@ func setupGlobals(cmd *cobra.Command, args []string) error {
}

var err error

config, err = configPkg.New(configPathFlag)
if err != nil {
slog.Error("Failed to load the config", "path", configPathFlag, "err", err)
return err
}

var caller api.Caller
if notificationDumpPath != "" {
caller = file.New(notificationDumpPath)
} else {
caller, err = github.New()
manager = managerPkg.New(config.Data)

return nil
}

func runRoot(cmd *cobra.Command, args []string) error {
if err := manager.Load(); err != nil {
slog.Error("Failed to load the notifications", "err", err)
return err
}

notifications := manager.Notifications.Visible()

if filterFlag != "" {
notificationsList, err := jq.Filter(filterFlag, notifications)
if err != nil {
slog.Error("Failed to create an API REST client", "err", err)
return err
}
notifications = notificationsList
}

manager = managerPkg.New(config.Data, caller, refreshFlag, noRefreshFlag)
if jqFlag != "" {
return fmt.Errorf("`gh-not list --jq` implementation needed")
}

table, err := notifications.Table()
if err != nil {
slog.Warn("Failed to generate a table, using toString", "err", err)
table = notifications.String()
}

if repl {
return displayRepl(table, notifications)
}

displayTable(table, notifications)

return nil
}

func displayTable(table string, notifications notifications.Notifications) {
out := table
out += fmt.Sprintf("\nFound %d notifications", len(notifications))
// TODO: add a notice if the notifications could be refreshed

fmt.Println(out)
}

func displayRepl(renderCache string, n notifications.Notifications) error {
caller, err := github.New()
if err != nil {
slog.Error("Failed to create an API REST client", "err", err)
return err
}
manager.WithCaller(caller)

model := normal.New(manager.Actors, n, renderCache, config.Data.Keymap, config.Data.View)

p := tea.NewProgram(model)
if _, err := p.Run(); err != nil {
return err
}

if err := manager.Save(); err != nil {
slog.Error("Failed to save the notifications", "err", err)
return err
}

return nil
}
25 changes: 24 additions & 1 deletion internal/cmd/sync.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package cmd

import (
"fmt"
"log/slog"

"github.com/nobe4/gh-not/internal/api"
"github.com/nobe4/gh-not/internal/api/file"
"github.com/nobe4/gh-not/internal/api/github"
managerPkg "github.com/nobe4/gh-not/internal/manager"
"github.com/spf13/cobra"
)

var (
noop bool
noop bool
notificationDumpPath string
refreshStrategy managerPkg.RefreshStrategy

syncCmd = &cobra.Command{
Use: "sync",
Expand All @@ -26,9 +33,25 @@ func init() {
rootCmd.AddCommand(syncCmd)

syncCmd.Flags().BoolVarP(&noop, "noop", "n", false, "Doesn't execute any action")
syncCmd.Flags().VarP(&refreshStrategy, "refresh-strategy", "r", fmt.Sprintf("Refresh strategy: %s", refreshStrategy.Allowed()))
syncCmd.Flags().StringVarP(&notificationDumpPath, "from-file", "", "", "Path to notification dump in JSON (generate with 'gh api /notifications')")
}

func runSync(cmd *cobra.Command, args []string) error {
var caller api.Caller
var err error

if notificationDumpPath != "" {
caller = file.New(notificationDumpPath)
} else {
caller, err = github.New()
if err != nil {
slog.Error("Failed to create an API REST client", "err", err)
return err
}
}
manager.WithRefresh(refreshStrategy).WithCaller(caller)

if err := manager.Load(); err != nil {
slog.Error("Failed to load the notifications", "err", err)
return err
Expand Down
Loading

0 comments on commit 6ab605d

Please sign in to comment.