github.com/segakazzz/buffalo@v0.16.22-0.20210119082501-1f52048d3feb/genny/assets/webpack/webpack.go (about)

     1  package webpack
     2  
     3  import (
     4  	"fmt"
     5  	"os/exec"
     6  	"path/filepath"
     7  	"runtime"
     8  
     9  	"github.com/gobuffalo/genny/v2"
    10  	"github.com/gobuffalo/genny/v2/gogen"
    11  	"github.com/gobuffalo/packr/v2"
    12  )
    13  
    14  // BinPath is the path to the local install of webpack
    15  var BinPath = func() string {
    16  	s := filepath.Join("node_modules", ".bin", "webpack")
    17  	if runtime.GOOS == "windows" {
    18  		s += ".cmd"
    19  	}
    20  	return s
    21  }()
    22  
    23  // Templates used for generating webpack
    24  // (exported mostly for the "fix" command)
    25  var Templates = packr.New("github.com/gobuffalo/buffalo/genny/assets/webpack", "../webpack/templates")
    26  
    27  // New generator for creating webpack asset files
    28  func New(opts *Options) (*genny.Generator, error) {
    29  	g := genny.New()
    30  
    31  	if err := opts.Validate(); err != nil {
    32  		return g, err
    33  	}
    34  
    35  	g.RunFn(func(r *genny.Runner) error {
    36  		if opts.App.WithYarn {
    37  			if _, err := r.LookPath("yarnpkg"); err == nil {
    38  				return nil
    39  			}
    40  			// If yarn is not installed, it still can be installed with npm.
    41  		}
    42  		if _, err := r.LookPath("npm"); err != nil {
    43  			return fmt.Errorf("could not find npm executable")
    44  		}
    45  		return nil
    46  	})
    47  
    48  	g.Box(Templates)
    49  
    50  	data := map[string]interface{}{
    51  		"opts": opts,
    52  	}
    53  	t := gogen.TemplateTransformer(data, gogen.TemplateHelpers)
    54  	g.Transformer(t)
    55  	g.Transformer(genny.Dot())
    56  
    57  	g.RunFn(func(r *genny.Runner) error {
    58  		return installPkgs(r, opts)
    59  	})
    60  
    61  	return g, nil
    62  }
    63  
    64  func installPkgs(r *genny.Runner, opts *Options) error {
    65  	command := "yarnpkg"
    66  
    67  	if !opts.App.WithYarn {
    68  		command = "npm"
    69  	} else {
    70  		if err := installYarn(r); err != nil {
    71  			return err
    72  		}
    73  	}
    74  	args := []string{"install", "--no-progress", "--save"}
    75  
    76  	c := exec.Command(command, args...)
    77  	c.Stdout = yarnWriter{
    78  		fn: r.Logger.Debug,
    79  	}
    80  	c.Stderr = yarnWriter{
    81  		fn: r.Logger.Debug,
    82  	}
    83  	return r.Exec(c)
    84  }
    85  
    86  type yarnWriter struct {
    87  	fn func(...interface{})
    88  }
    89  
    90  func (y yarnWriter) Write(p []byte) (int, error) {
    91  	y.fn(string(p))
    92  	return len(p), nil
    93  }
    94  
    95  func installYarn(r *genny.Runner) error {
    96  	// if there's no yarn, install it!
    97  	if _, err := r.LookPath("yarnpkg"); err == nil {
    98  		return nil
    99  	}
   100  	yargs := []string{"install", "-g", "yarn"}
   101  	return r.Exec(exec.Command("npm", yargs...))
   102  }