github.com/bingoohuang/pkger@v0.0.0-20210127185155-a71b9df4c4c7/cmd/pkger/cmds/pack.go (about)

     1  package cmds
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"sort"
     9  	"strings"
    10  
    11  	"github.com/bingoohuang/pkger"
    12  	"github.com/bingoohuang/pkger/here"
    13  	"github.com/bingoohuang/pkger/parser"
    14  	"github.com/bingoohuang/pkger/pkging/pkgutil"
    15  )
    16  
    17  type slice []string
    18  
    19  func (i slice) String() string {
    20  	return fmt.Sprintf("%s", []string(i))
    21  }
    22  
    23  func (i *slice) Set(value string) error {
    24  	*i = append(*i, value)
    25  	return nil
    26  }
    27  
    28  const outName = "pkged.go"
    29  
    30  type packCmd struct {
    31  	*flag.FlagSet
    32  	out     string
    33  	help    bool
    34  	include slice
    35  	subs    []command
    36  }
    37  
    38  func (e *packCmd) Name() string {
    39  	return e.Flags().Name()
    40  }
    41  
    42  func (e *packCmd) Exec(args []string) error {
    43  	info, err := pkger.Current()
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	fp := filepath.Join(info.Dir, e.out, outName)
    49  	os.RemoveAll(fp)
    50  
    51  	decls, err := parser.Parse(info, e.include...)
    52  	if err != nil {
    53  		return err
    54  	}
    55  
    56  	if err := Package(info, fp, decls); err != nil {
    57  		return err
    58  	}
    59  
    60  	return nil
    61  }
    62  
    63  func (e *packCmd) Route(args []string) error {
    64  	e.Parse(args)
    65  
    66  	if e.help {
    67  		e.Usage()
    68  		return nil
    69  	}
    70  
    71  	args = e.Args()
    72  
    73  	if len(args) == 0 {
    74  		return e.Exec(args)
    75  	}
    76  
    77  	k := args[0]
    78  	for _, c := range e.subs {
    79  		if k == c.Name() {
    80  			args = args[1:]
    81  			for _, a := range args {
    82  				if a == "-h" {
    83  					Usage(os.Stderr, c.Flags())()
    84  					return nil
    85  				}
    86  			}
    87  			return c.Exec(args)
    88  		}
    89  	}
    90  
    91  	return fmt.Errorf("unknown arguments: %s", strings.Join(args, " "))
    92  }
    93  
    94  func New() (*packCmd, error) {
    95  	c := &packCmd{}
    96  
    97  	c.subs = []command{
    98  		&serveCmd{}, &statCmd{}, &infoCmd{}, &pathCmd{}, &parseCmd{}, &listCmd{},
    99  	}
   100  	sort.Slice(c.subs, func(a, b int) bool {
   101  		return c.subs[a].Name() <= c.subs[b].Name()
   102  	})
   103  
   104  	c.FlagSet = flag.NewFlagSet("pkger", flag.ExitOnError)
   105  	c.BoolVar(&c.help, "h", false, "prints help information")
   106  	c.StringVar(&c.out, "o", "", "output directory for pkged.go")
   107  	c.Var(&c.include, "include", "packages the specified file or directory")
   108  	c.Usage = func() {
   109  		fmt.Fprintf(os.Stderr, "Usage:\n\n")
   110  		Usage(os.Stderr, c.FlagSet)()
   111  		for _, s := range c.subs {
   112  			Usage(os.Stderr, s.Flags())()
   113  		}
   114  	}
   115  	return c, nil
   116  }
   117  
   118  func (e *packCmd) Flags() *flag.FlagSet {
   119  	if e.FlagSet == nil {
   120  		e.FlagSet = flag.NewFlagSet("", flag.ExitOnError)
   121  	}
   122  	e.Usage = Usage(os.Stderr, e.FlagSet)
   123  	return e.FlagSet
   124  }
   125  
   126  func Package(info here.Info, out string, decls parser.Decls) error {
   127  	c, err := here.Dir(filepath.Dir(out))
   128  	if err != nil {
   129  		return err
   130  	}
   131  
   132  	os.RemoveAll(out)
   133  	defer func() {
   134  		if err := recover(); err != nil {
   135  			os.RemoveAll(out)
   136  		}
   137  	}()
   138  
   139  	f, err := os.Create(out)
   140  	if err != nil {
   141  		return err
   142  	}
   143  	defer f.Close()
   144  
   145  	fmt.Fprintf(f, "// Code generated by pkger; DO NOT EDIT.\n\n")
   146  	fmt.Fprintf(f, "// +build !skippkger\n\n")
   147  	fmt.Fprintf(f, "package %s\n\n", c.Name)
   148  	fmt.Fprintf(f, "import (\n\t\"github.com/bingoohuang/pkger\"\n\t")
   149  	fmt.Fprintf(f, "\"github.com/bingoohuang/pkger/pkging/mem\"\n)\n\n")
   150  	fmt.Fprintf(f, "var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`")
   151  
   152  	if err := pkgutil.Stuff(f, info, decls); err != nil {
   153  		return err
   154  	}
   155  
   156  	fmt.Fprintf(f, "`)))\n")
   157  
   158  	return nil
   159  }