github.com/singlemusic/buffalo@v0.16.30/buffalo/cmd/fix/npm.go (about)

     1  package fix
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"html/template"
     8  	"io/ioutil"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  
    13  	"github.com/gobuffalo/buffalo/genny/assets/webpack"
    14  )
    15  
    16  // AddPackageJSONScripts rewrites the package.json file
    17  // to add dev and build scripts if there are missing.
    18  func AddPackageJSONScripts(r *Runner) error {
    19  	if !r.App.WithWebpack {
    20  		return nil
    21  	}
    22  	fmt.Println("~~~ Patching package.json to add dev and build scripts ~~~")
    23  
    24  	b, err := ioutil.ReadFile("package.json")
    25  	if err != nil {
    26  		return err
    27  	}
    28  
    29  	needRewrite := false
    30  	packageJSON := map[string]interface{}{}
    31  	if err := json.Unmarshal(b, &packageJSON); err != nil {
    32  		return fmt.Errorf("could not rewrite package.json: %s", err.Error())
    33  	}
    34  
    35  	if _, ok := packageJSON["scripts"]; !ok {
    36  		needRewrite = true
    37  		// Add scripts
    38  		packageJSON["scripts"] = map[string]string{
    39  			"dev":   "webpack --watch",
    40  			"build": "webpack -p --progress",
    41  		}
    42  	} else {
    43  		// Add missing scripts
    44  		scripts, ok := packageJSON["scripts"].(map[string]interface{})
    45  		if !ok {
    46  			return fmt.Errorf("could not rewrite package.json: invalid scripts section")
    47  		}
    48  		if _, ok := scripts["dev"]; !ok {
    49  			needRewrite = true
    50  			scripts["dev"] = "webpack --watch"
    51  		}
    52  		if _, ok := scripts["build"]; !ok {
    53  			needRewrite = true
    54  			scripts["build"] = "webpack -p --progress"
    55  		}
    56  		packageJSON["scripts"] = scripts
    57  	}
    58  
    59  	if needRewrite {
    60  		b, err = json.MarshalIndent(packageJSON, "", "  ")
    61  		if err != nil {
    62  			return fmt.Errorf("could not rewrite package.json: %s", err.Error())
    63  		}
    64  
    65  		ioutil.WriteFile("package.json", b, 0644)
    66  	} else {
    67  		fmt.Println("~~~ package.json doesn't need to be patched, skipping. ~~~")
    68  	}
    69  
    70  	return nil
    71  }
    72  
    73  // PackageJSONCheck will compare the current default Buffalo
    74  // package.json against the applications package.json. If they are
    75  // different you have the option to overwrite the existing package.json
    76  // file with the new one.
    77  func PackageJSONCheck(r *Runner) error {
    78  	fmt.Println("~~~ Checking package.json ~~~")
    79  
    80  	if !r.App.WithWebpack {
    81  		return nil
    82  	}
    83  
    84  	box := webpack.Templates
    85  
    86  	f, err := box.FindString("package.json.tmpl")
    87  	if err != nil {
    88  		return err
    89  	}
    90  
    91  	tmpl, err := template.New("package.json").Parse(f)
    92  	if err != nil {
    93  		return err
    94  	}
    95  
    96  	bb := &bytes.Buffer{}
    97  	err = tmpl.Execute(bb, map[string]interface{}{
    98  		"opts": &webpack.Options{
    99  			App: r.App,
   100  		},
   101  	})
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	b, err := ioutil.ReadFile("package.json")
   107  	if err != nil {
   108  		return err
   109  	}
   110  
   111  	if string(b) == bb.String() {
   112  		return nil
   113  	}
   114  
   115  	if !ask("Your package.json file is different from the latest Buffalo template.\nWould you like to REPLACE yours with the latest template?") {
   116  		fmt.Println("\tskipping package.json")
   117  		return nil
   118  	}
   119  
   120  	pf, err := os.Create("package.json")
   121  	if err != nil {
   122  		return err
   123  	}
   124  	_, err = pf.Write(bb.Bytes())
   125  	if err != nil {
   126  		return err
   127  	}
   128  	err = pf.Close()
   129  	if err != nil {
   130  		return err
   131  	}
   132  
   133  	os.RemoveAll(filepath.Join(r.App.Root, "node_modules"))
   134  	var cmd *exec.Cmd
   135  	if r.App.WithYarn {
   136  		cmd = exec.Command("yarnpkg", "install")
   137  	} else {
   138  		cmd = exec.Command("npm", "install")
   139  	}
   140  
   141  	cmd.Stdin = os.Stdin
   142  	cmd.Stdout = os.Stdout
   143  	cmd.Stderr = os.Stderr
   144  	return cmd.Run()
   145  }