You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.2 KiB

  1. package config
  2. import (
  3. "gerrit.wikimedia.org/r/blubber/build"
  4. )
  5. // NodeConfig holds configuration fields related to the Node environment and
  6. // whether/how to install NPM packages.
  7. //
  8. type NodeConfig struct {
  9. Requirements []string `json:"requirements"` // install requirements from given files
  10. Env string `json:"env" validate:"omitempty,nodeenv"` // environment name ("production" install)
  11. }
  12. // Merge takes another NodeConfig and merges its fields into this one's,
  13. // overwriting both the environment and requirements files.
  14. //
  15. func (nc *NodeConfig) Merge(nc2 NodeConfig) {
  16. if nc2.Requirements != nil {
  17. nc.Requirements = nc2.Requirements
  18. }
  19. if nc2.Env != "" {
  20. nc.Env = nc2.Env
  21. }
  22. }
  23. // InstructionsForPhase injects instructions into the build related to Node
  24. // dependency installation and setting of the NODE_ENV.
  25. //
  26. // PhasePreInstall
  27. //
  28. // Installs Node package dependencies declared in requirements files into the
  29. // application directory. Only production related packages are install if
  30. // NodeConfig.Env is set to "production" in which case `npm dedupe` is also
  31. // run. Installing dependencies during the build.PhasePreInstall phase allows
  32. // a compiler implementation (e.g. Docker) to produce cache-efficient output
  33. // so only changes to package.json will invalidate these steps of the image
  34. // build.
  35. //
  36. // PhasePostInstall
  37. //
  38. // Injects build.Env instructions for NODE_ENV, setting the environment
  39. // according to the configuration.
  40. //
  41. func (nc NodeConfig) InstructionsForPhase(phase build.Phase) []build.Instruction {
  42. switch phase {
  43. case build.PhasePreInstall:
  44. if len(nc.Requirements) > 0 {
  45. npmInstall := build.RunAll{[]build.Run{
  46. {"npm install", []string{}},
  47. }}
  48. if nc.Env == "production" {
  49. npmInstall.Runs[0].Arguments = []string{"--production"}
  50. npmInstall.Runs = append(npmInstall.Runs,
  51. build.Run{"npm dedupe", []string{}},
  52. )
  53. }
  54. return append(
  55. build.SyncFiles(nc.Requirements, "."),
  56. npmInstall,
  57. )
  58. }
  59. case build.PhasePostInstall:
  60. if nc.Env != "" || len(nc.Requirements) > 0 {
  61. return []build.Instruction{build.Env{map[string]string{
  62. "NODE_ENV": nc.Env,
  63. }}}
  64. }
  65. }
  66. return []build.Instruction{}
  67. }