github.com/wawandco/ox@v0.13.6-0.20230809142027-913b3d837f2a/plugins/base/generate/generate.go (about)

     1  // generate package provides the base of the generate command
     2  // which allows to run generators for tools.
     3  package generate
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"os"
     9  	"text/tabwriter"
    10  
    11  	"github.com/wawandco/ox/internal/log"
    12  	"github.com/wawandco/ox/internal/source"
    13  	"github.com/wawandco/ox/plugins/core"
    14  )
    15  
    16  //HelpText returns the help Text of build function
    17  
    18  var _ core.Command = (*Command)(nil)
    19  var _ core.PluginReceiver = (*Command)(nil)
    20  
    21  type Command struct {
    22  	generators      []Generator
    23  	aftergenerators []AfterGenerator
    24  }
    25  
    26  func (c Command) Name() string {
    27  	return "generate"
    28  }
    29  
    30  func (c Command) Alias() string {
    31  	return "g"
    32  }
    33  
    34  func (c Command) ParentName() string {
    35  	return ""
    36  }
    37  
    38  func (c Command) HelpText() string {
    39  	return "Allows to invoke registered generator plugins"
    40  }
    41  
    42  func (c *Command) Run(ctx context.Context, root string, args []string) error {
    43  	if len(args) < 2 {
    44  		c.list()
    45  
    46  		return fmt.Errorf("no generator name specified")
    47  	}
    48  
    49  	name := args[1]
    50  	var generator Generator
    51  	//Run each of the fixers registered.
    52  	for _, gen := range c.generators {
    53  		if gen.InvocationName() != name {
    54  			continue
    55  		}
    56  
    57  		generator = gen
    58  		break
    59  	}
    60  
    61  	if generator == nil {
    62  		c.list()
    63  		return fmt.Errorf("generator `%v` not found", name)
    64  	}
    65  
    66  	err := generator.Generate(ctx, root, args)
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	for _, ag := range c.aftergenerators {
    72  		err := ag.AfterGenerate(ctx, root, args)
    73  		if err != nil {
    74  			log.Errorf("Error running after generator %v: %v", ag.Name(), err)
    75  		}
    76  	}
    77  
    78  	err = source.RunImports(root)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	err = source.RunModTidy(root)
    84  	if err != nil {
    85  		return err
    86  	}
    87  
    88  	return err
    89  }
    90  
    91  func (c Command) list() {
    92  	w := new(tabwriter.Writer)
    93  	defer w.Flush()
    94  
    95  	// minwidth, tabwidth, padding, padchar, flags
    96  	w.Init(os.Stdout, 8, 8, 3, '\t', 0)
    97  	fmt.Printf("Available Generators:\n\n")
    98  	fmt.Fprintf(w, "  Name\tPlugin\n")
    99  	fmt.Fprintf(w, "  ----\t------\n")
   100  	for _, plugin := range c.generators {
   101  		helpText := ""
   102  		if ht, ok := plugin.(core.HelpTexter); ok {
   103  			helpText = ht.HelpText()
   104  		}
   105  
   106  		fmt.Fprintf(w, "  %v\t%v\t%v\n", plugin.InvocationName(), plugin.Name(), helpText)
   107  	}
   108  
   109  	fmt.Fprintf(w, "\n")
   110  }
   111  
   112  func (c *Command) Receive(plugins []core.Plugin) {
   113  	for _, plugin := range plugins {
   114  		ptool, ok := plugin.(Generator)
   115  		if !ok {
   116  			continue
   117  		}
   118  
   119  		c.generators = append(c.generators, ptool)
   120  	}
   121  
   122  	for _, plugin := range plugins {
   123  		ptool, ok := plugin.(AfterGenerator)
   124  		if !ok {
   125  			continue
   126  		}
   127  
   128  		c.aftergenerators = append(c.aftergenerators, ptool)
   129  	}
   130  }