babarot / afx

📦 Package manager for CLI
https://babarot.me/afx/
MIT License
150 stars 6 forks source link

Refactor meta command #25

Closed babarot closed 2 years ago

babarot commented 2 years ago

WHAT

Refactor meta command. `meta is used in various command in afx. It's basically for embedding to each subcommand to access meta information (e.g. env, packages, state etc...). In this PR, it has been moved to outside of each command. Concretely, will be moved to rootCmd.

By this, each commands doesn't have to run meta.init() with inside of its own. Each command can access meta via its receiver. Also, each command can continuously embed meta into its own subcommand to pass meta to each command methods.

Before:

func newRootCmd() *cobra.Command {
         rootCmd.AddCommand(newInitCmd())

// ------------------------------------

type initCmd struct {
    meta
}
func newInitCmd() *cobra.Command {
    c := &initCmd{}
    initCmd := &cobra.Command{
                 // ...
        RunE: func(cmd *cobra.Command, args []string) error {
            if err := c.meta.init(args); err != nil {
                return err
            }

After:

func Execute() error {
         // ...
    meta := metaCmd{}
    if err := meta.init(); err != nil {
        return errors.Wrap(err, "failed to initialize afx")
    }
    return newRootCmd(meta).Execute()
}

func newRootCmd(m metaCmd) *cobra.Command {
         // ...
    rootCmd.AddCommand(
        m.newInitCmd(),
        )

// ------------------------------------

type initCmd struct {
    metaCmd
}
func (m metaCmd) newInitCmd() *cobra.Command {
        c := &initCmd{metaCmd: m}
    return &cobra.Command{
        Run: func(cmd *cobra.Command, args []string) {
                     // ...
        },
    }

WHY

By taking the meta.init() method out of each commands, afx can become to get meta information at root command level. meta has a lot of information to run afx command, so these data can be used before running each command. For example, state data. It can be passed to each command as its valid args.

Thanks to this, each command completion feature will be more powerful. Other benefits also will be appeared soon.