Skip to content

Commit

Permalink
refactor: restructure option handling code
Browse files Browse the repository at this point in the history
  • Loading branch information
ahamidullah committed Dec 6, 2018
1 parent f82f4c8 commit 99e8105
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 123 deletions.
53 changes: 31 additions & 22 deletions cmd/depviz/cmd_airtable.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,48 +28,57 @@ type airtableOptions struct {
Targets []repo.Target `mapstructure:"targets"`
}

var globalAirtableOptions airtableOptions

func (opts airtableOptions) String() string {
out, _ := json.Marshal(opts)
return string(out)
}

func airtableSetupFlags(flags *pflag.FlagSet, opts *airtableOptions) {
flags.StringVarP(&opts.IssuesTableName, "airtable-issues-table-name", "", "Issues and PRs", "Airtable issues table name")
flags.StringVarP(&opts.RepositoriesTableName, "airtable-repositories-table-name", "", "Repositories", "Airtable repositories table name")
flags.StringVarP(&opts.AccountsTableName, "airtable-accounts-table-name", "", "Accounts", "Airtable accounts table name")
flags.StringVarP(&opts.LabelsTableName, "airtable-labels-table-name", "", "Labels", "Airtable labels table name")
flags.StringVarP(&opts.MilestonesTableName, "airtable-milestones-table-name", "", "Milestones", "Airtable milestones table nfame")
flags.StringVarP(&opts.ProvidersTableName, "airtable-providers-table-name", "", "Providers", "Airtable providers table name")
flags.StringVarP(&opts.BaseID, "airtable-base-id", "", "", "Airtable base ID")
flags.StringVarP(&opts.Token, "airtable-token", "", "", "Airtable token")
flags.BoolVarP(&opts.DestroyInvalidRecords, "airtable-destroy-invalid-records", "", false, "Destroy invalid records")
type airtableCommand struct {
opts airtableOptions
}

func (cmd *airtableCommand) LoadDefaultOptions() error {
if err := viper.Unmarshal(&cmd.opts); err != nil {
return err
}
return nil
}

func (cmd *airtableCommand) ParseFlags(flags *pflag.FlagSet) {
flags.StringVarP(&cmd.opts.IssuesTableName, "airtable-issues-table-name", "", "Issues and PRs", "Airtable issues table name")
flags.StringVarP(&cmd.opts.RepositoriesTableName, "airtable-repositories-table-name", "", "Repositories", "Airtable repositories table name")
flags.StringVarP(&cmd.opts.AccountsTableName, "airtable-accounts-table-name", "", "Accounts", "Airtable accounts table name")
flags.StringVarP(&cmd.opts.LabelsTableName, "airtable-labels-table-name", "", "Labels", "Airtable labels table name")
flags.StringVarP(&cmd.opts.MilestonesTableName, "airtable-milestones-table-name", "", "Milestones", "Airtable milestones table nfame")
flags.StringVarP(&cmd.opts.ProvidersTableName, "airtable-providers-table-name", "", "Providers", "Airtable providers table name")
flags.StringVarP(&cmd.opts.BaseID, "airtable-base-id", "", "", "Airtable base ID")
flags.StringVarP(&cmd.opts.Token, "airtable-token", "", "", "Airtable token")
flags.BoolVarP(&cmd.opts.DestroyInvalidRecords, "airtable-destroy-invalid-records", "", false, "Destroy invalid records")
viper.BindPFlags(flags)
}

func newAirtableCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *airtableCommand) NewCobraCommand(dc map[string]DepvizCommand) *cobra.Command {
cc := &cobra.Command{
Use: "airtable",
}
cmd.AddCommand(newAirtableSyncCommand())
return cmd
cc.AddCommand(cmd.airtableSyncCommand())
return cc
}

func newAirtableSyncCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *airtableCommand) airtableSyncCommand() *cobra.Command {
cc := &cobra.Command{
Use: "sync",
RunE: func(cmd *cobra.Command, args []string) error {
opts := globalAirtableOptions
RunE: func(_ *cobra.Command, args []string) error {
opts := cmd.opts
var err error
if opts.Targets, err = repo.ParseTargets(args); err != nil {
return errors.Wrap(err, "invalid targets")
}
return airtableSync(&opts)
},
}
airtableSetupFlags(cmd.Flags(), &globalAirtableOptions)
return cmd
cmd.ParseFlags(cc.Flags())
return cc
}

// TODO: Make this function a lot shorter by pulling out some of the boilerplate?
Expand Down
37 changes: 23 additions & 14 deletions cmd/depviz/cmd_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,44 @@ import (

type dbOptions struct{}

var globalDBOptions dbOptions

func (opts dbOptions) String() string {
out, _ := json.Marshal(opts)
return string(out)
}

func dbSetupFlags(flags *pflag.FlagSet, opts *dbOptions) {
viper.BindPFlags(flags)
type dbCommand struct {
opts dbOptions
}

func (cmd *dbCommand) LoadDefaultOptions() error {
if err := viper.Unmarshal(&cmd.opts); err != nil {
return err
}
return nil
}

func newDBCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *dbCommand) NewCobraCommand(dc map[string]DepvizCommand) *cobra.Command {
cc := &cobra.Command{
Use: "db",
}
cmd.AddCommand(newDBDumpCommand())
return cmd
cc.AddCommand(cmd.dbDumpCommand())
return cc
}

func (cmd *dbCommand) ParseFlags(flags *pflag.FlagSet) {
viper.BindPFlags(flags)
}

func newDBDumpCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *dbCommand) dbDumpCommand() *cobra.Command {
cc := &cobra.Command{
Use: "dump",
RunE: func(cmd *cobra.Command, args []string) error {
opts := globalDBOptions
RunE: func(_ *cobra.Command, args []string) error {
opts := cmd.opts
return dbDump(&opts)
},
}
dbSetupFlags(cmd.Flags(), &globalDBOptions)
return cmd
cmd.ParseFlags(cc.Flags())
return cc
}

func dbDump(opts *dbOptions) error {
Expand Down
43 changes: 26 additions & 17 deletions cmd/depviz/cmd_graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,49 @@ type graphOptions struct {
// NoExternal
}

var globalGraphOptions graphOptions

func (opts graphOptions) String() string {
out, _ := json.Marshal(opts)
return string(out)
}

func graphSetupFlags(flags *pflag.FlagSet, opts *graphOptions) {
flags.BoolVarP(&opts.ShowClosed, "show-closed", "", false, "show closed issues")
flags.BoolVarP(&opts.DebugGraph, "debug-graph", "", false, "debug graph")
flags.BoolVarP(&opts.ShowOrphans, "show-orphans", "", false, "show issues not linked to an epic")
flags.BoolVarP(&opts.NoCompress, "no-compress", "", false, "do not compress graph (no overlap)")
flags.BoolVarP(&opts.DarkTheme, "dark-theme", "", false, "dark theme")
flags.BoolVarP(&opts.ShowPRs, "show-prs", "", false, "show PRs")
flags.StringVarP(&opts.Output, "output", "o", "-", "output file ('-' for stdout, dot)")
flags.StringVarP(&opts.Format, "format", "f", "", "output file format (if empty, will determine thanks to output extension)")
type graphCommand struct {
opts graphOptions
}

func (cmd *graphCommand) LoadDefaultOptions() error {
if err := viper.Unmarshal(&cmd.opts); err != nil {
return err
}
return nil
}

func (cmd *graphCommand) ParseFlags(flags *pflag.FlagSet) {
flags.BoolVarP(&cmd.opts.ShowClosed, "show-closed", "", false, "show closed issues")
flags.BoolVarP(&cmd.opts.DebugGraph, "debug-graph", "", false, "debug graph")
flags.BoolVarP(&cmd.opts.ShowOrphans, "show-orphans", "", false, "show issues not linked to an epic")
flags.BoolVarP(&cmd.opts.NoCompress, "no-compress", "", false, "do not compress graph (no overlap)")
flags.BoolVarP(&cmd.opts.DarkTheme, "dark-theme", "", false, "dark theme")
flags.BoolVarP(&cmd.opts.ShowPRs, "show-prs", "", false, "show PRs")
flags.StringVarP(&cmd.opts.Output, "output", "o", "-", "output file ('-' for stdout, dot)")
flags.StringVarP(&cmd.opts.Format, "format", "f", "", "output file format (if empty, will determine thanks to output extension)")
//flags.BoolVarP(&opts.Preview, "preview", "p", false, "preview result")
viper.BindPFlags(flags)
}

func newGraphCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *graphCommand) NewCobraCommand(dc map[string]DepvizCommand) *cobra.Command {
cc := &cobra.Command{
Use: "graph",
RunE: func(cmd *cobra.Command, args []string) error {
opts := globalGraphOptions
RunE: func(_ *cobra.Command, args []string) error {
opts := cmd.opts
var err error
if opts.Targets, err = repo.ParseTargets(args); err != nil {
return errors.Wrap(err, "invalid targets")
}
return graph(&opts)
},
}
graphSetupFlags(cmd.Flags(), &globalGraphOptions)
return cmd
cmd.ParseFlags(cc.Flags())
return cc
}

func graph(opts *graphOptions) error {
Expand Down
31 changes: 20 additions & 11 deletions cmd/depviz/cmd_pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,42 @@ type pullOptions struct {
Targets repo.Targets `mapstructure:"targets"`
}

var globalPullOptions pullOptions

func (opts pullOptions) String() string {
out, _ := json.Marshal(opts)
return string(out)
}

func pullSetupFlags(flags *pflag.FlagSet, opts *pullOptions) {
flags.StringVarP(&opts.GithubToken, "github-token", "", "", "GitHub Token with 'issues' access")
flags.StringVarP(&opts.GitlabToken, "gitlab-token", "", "", "GitLab Token with 'issues' access")
type pullCommand struct {
opts pullOptions
}

func (cmd *pullCommand) LoadDefaultOptions() error {
if err := viper.Unmarshal(&cmd.opts); err != nil {
return err
}
return nil
}

func (cmd *pullCommand) ParseFlags(flags *pflag.FlagSet) {
flags.StringVarP(&cmd.opts.GithubToken, "github-token", "", "", "GitHub Token with 'issues' access")
flags.StringVarP(&cmd.opts.GitlabToken, "gitlab-token", "", "", "GitLab Token with 'issues' access")
viper.BindPFlags(flags)
}

func newPullCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *pullCommand) NewCobraCommand(dc map[string]DepvizCommand) *cobra.Command {
cc := &cobra.Command{
Use: "pull",
RunE: func(cmd *cobra.Command, args []string) error {
opts := globalPullOptions
RunE: func(_ *cobra.Command, args []string) error {
opts := cmd.opts
var err error
if opts.Targets, err = repo.ParseTargets(args); err != nil {
return errors.Wrap(err, "invalid targets")
}
return pullAndCompute(&opts)
},
}
pullSetupFlags(cmd.Flags(), &globalPullOptions)
return cmd
cmd.ParseFlags(cc.Flags())
return cc
}

func pullAndCompute(opts *pullOptions) error {
Expand Down
39 changes: 24 additions & 15 deletions cmd/depviz/cmd_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,35 @@ type runOptions struct {
NoPull bool `mapstructure:"no-pull"`
}

var globalRunOptions runOptions

func (opts runOptions) String() string {
out, _ := json.Marshal(opts)
return string(out)
}

func runSetupFlags(flags *pflag.FlagSet, opts *runOptions) {
flags.BoolVarP(&opts.NoPull, "no-pull", "", false, "do not pull new issues before running")
flags.StringSliceVarP(&opts.AdditionalPulls, "additional-pulls", "", []string{}, "additional pull that won't necessarily be displayed on the graph")
type runCommand struct {
opts runOptions
}

func (cmd *runCommand) LoadDefaultOptions() error {
if err := viper.Unmarshal(&cmd.opts); err != nil {
return err
}
return nil
}

func (cmd *runCommand) ParseFlags(flags *pflag.FlagSet) {
flags.BoolVarP(&cmd.opts.NoPull, "no-pull", "", false, "do not pull new issues before running")
flags.StringSliceVarP(&cmd.opts.AdditionalPulls, "additional-pulls", "", []string{}, "additional pull that won't necessarily be displayed on the graph")
viper.BindPFlags(flags)
}

func newRunCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *runCommand) NewCobraCommand(dc map[string]DepvizCommand) *cobra.Command {
cc := &cobra.Command{
Use: "run",
RunE: func(cmd *cobra.Command, args []string) error {
opts := globalRunOptions
opts.GraphOptions = globalGraphOptions
opts.PullOptions = globalPullOptions
RunE: func(_ *cobra.Command, args []string) error {
opts := cmd.opts
opts.GraphOptions = dc["graph"].(*graphCommand).opts
opts.PullOptions = dc["pull"].(*pullCommand).opts

targets, err := repo.ParseTargets(args)
if err != nil {
Expand All @@ -51,10 +60,10 @@ func newRunCommand() *cobra.Command {
return run(&opts)
},
}
runSetupFlags(cmd.Flags(), &globalRunOptions)
graphSetupFlags(cmd.Flags(), &globalGraphOptions)
pullSetupFlags(cmd.Flags(), &globalPullOptions)
return cmd
cmd.ParseFlags(cc.Flags())
dc["graph"].ParseFlags(cc.Flags())
dc["pull"].ParseFlags(cc.Flags())
return cc
}

func run(opts *runOptions) error {
Expand Down
31 changes: 20 additions & 11 deletions cmd/depviz/cmd_web.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,38 @@ type webOptions struct {
ShowRoutes bool
}

var globalWebOptions webOptions

func (opts webOptions) String() string {
out, _ := json.Marshal(opts)
return string(out)
}

func webSetupFlags(flags *pflag.FlagSet, opts *webOptions) {
flags.StringVarP(&opts.Bind, "bind", "b", ":2020", "web server bind address")
flags.BoolVarP(&opts.ShowRoutes, "show-routes", "", false, "display available routes and quit")
type webCommand struct {
opts webOptions
}

func (cmd *webCommand) LoadDefaultOptions() error {
if err := viper.Unmarshal(&cmd.opts); err != nil {
return err
}
return nil
}

func (cmd *webCommand) ParseFlags(flags *pflag.FlagSet) {
flags.StringVarP(&cmd.opts.Bind, "bind", "b", ":2020", "web server bind address")
flags.BoolVarP(&cmd.opts.ShowRoutes, "show-routes", "", false, "display available routes and quit")
viper.BindPFlags(flags)
}

func newWebCommand() *cobra.Command {
cmd := &cobra.Command{
func (cmd *webCommand) NewCobraCommand(dc map[string]DepvizCommand) *cobra.Command {
cc := &cobra.Command{
Use: "web",
RunE: func(cmd *cobra.Command, args []string) error {
opts := globalWebOptions
RunE: func(_ *cobra.Command, args []string) error {
opts := cmd.opts
return web(&opts)
},
}
webSetupFlags(cmd.Flags(), &globalWebOptions)
return cmd
cmd.ParseFlags(cc.Flags())
return cc
}

func webListIssues(w http.ResponseWriter, r *http.Request) {
Expand Down
Loading

0 comments on commit 99e8105

Please sign in to comment.