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 }