node.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package runtimes
  2. import (
  3. "sync"
  4. nodemodulebom "github.com/paketo-buildpacks/node-module-bom"
  5. npminstall "github.com/paketo-buildpacks/npm-install"
  6. "github.com/paketo-buildpacks/packit"
  7. yarninstall "github.com/paketo-buildpacks/yarn-install"
  8. )
  9. type NodeRuntime struct {
  10. // An internal representation of https://github.com/paketo-buildpacks/nodejs/blob/main/buildpack.toml
  11. packs map[string]*BuildpackInfo
  12. wg sync.WaitGroup
  13. }
  14. func NewNodeRuntime() *NodeRuntime {
  15. packs := make(map[string]*BuildpackInfo)
  16. // yarn
  17. packs["yarn"] = newBuildpackInfo()
  18. packs["yarn"].addPack("paketo-buildpacks/ca-certificates")
  19. packs["yarn"].addPack("paketo-buildpacks/node-engine")
  20. packs["yarn"].addPack("paketo-buildpacks/yarn")
  21. packs["yarn"].addPack("paketo-buildpacks/yarn-install")
  22. packs["yarn"].addPack("paketo-buildpacks/node-module-bom")
  23. packs["yarn"].addPack("paketo-buildpacks/node-run-script")
  24. packs["yarn"].addPack("paketo-buildpacks/yarn-start")
  25. packs["yarn"].addPack("paketo-buildpacks/procfile")
  26. packs["yarn"].addPack("paketo-buildpacks/environment-variables")
  27. packs["yarn"].addPack("paketo-buildpacks/image-labels")
  28. packs["yarn"].addEnvVar("SSL_CERT_DIR", "")
  29. packs["yarn"].addEnvVar("SSL_CERT_FILE", "")
  30. packs["yarn"].addEnvVar("BP_NODE_OPTIMIZE_MEMORY", "")
  31. packs["yarn"].addEnvVar("BP_NODE_PROJECT_PATH", "")
  32. packs["yarn"].addEnvVar("BP_NODE_VERSION", "")
  33. packs["yarn"].addEnvVar("BP_NODE_RUN_SCRIPTS", "")
  34. // npm
  35. packs["npm"] = newBuildpackInfo()
  36. packs["npm"].addPack("paketo-buildpacks/ca-certificates")
  37. packs["npm"].addPack("paketo-buildpacks/node-engine")
  38. packs["npm"].addPack("paketo-buildpacks/npm-install")
  39. packs["npm"].addPack("paketo-buildpacks/node-module-bom")
  40. packs["npm"].addPack("paketo-buildpacks/node-run-script")
  41. packs["npm"].addPack("paketo-buildpacks/npm-start")
  42. packs["npm"].addPack("paketo-buildpacks/procfile")
  43. packs["npm"].addPack("paketo-buildpacks/environment-variables")
  44. packs["npm"].addPack("paketo-buildpacks/image-labels")
  45. packs["npm"].addEnvVar("SSL_CERT_DIR", "")
  46. packs["npm"].addEnvVar("SSL_CERT_FILE", "")
  47. packs["npm"].addEnvVar("BP_NODE_OPTIMIZE_MEMORY", "")
  48. packs["npm"].addEnvVar("BP_NODE_PROJECT_PATH", "")
  49. packs["npm"].addEnvVar("BP_NODE_VERSION", "")
  50. packs["npm"].addEnvVar("BP_NODE_RUN_SCRIPTS", "")
  51. // no package manager
  52. packs["standalone"] = newBuildpackInfo()
  53. packs["standalone"].addPack("paketo-buildpacks/ca-certificates")
  54. packs["standalone"].addPack("paketo-buildpacks/node-engine")
  55. packs["standalone"].addPack("paketo-buildpacks/node-module-bom")
  56. packs["standalone"].addPack("paketo-buildpacks/node-start")
  57. packs["standalone"].addPack("paketo-buildpacks/procfile")
  58. packs["standalone"].addPack("paketo-buildpacks/environment-variables")
  59. packs["standalone"].addPack("paketo-buildpacks/image-labels")
  60. packs["standalone"].addEnvVar("SSL_CERT_DIR", "")
  61. packs["standalone"].addEnvVar("SSL_CERT_FILE", "")
  62. packs["standalone"].addEnvVar("BP_NODE_OPTIMIZE_MEMORY", "")
  63. packs["standalone"].addEnvVar("BP_NODE_PROJECT_PATH", "")
  64. packs["standalone"].addEnvVar("BP_NODE_VERSION", "")
  65. packs["standalone"].addEnvVar("BP_LAUNCHPOINT", "")
  66. packs["standalone"].addEnvVar("BP_LIVE_RELOAD_ENABLED", "")
  67. return &NodeRuntime{
  68. packs: packs,
  69. }
  70. }
  71. func (runtime *NodeRuntime) detectYarn(results chan struct {
  72. string
  73. bool
  74. }, workingDir string) {
  75. yarnProjectPathParser := yarninstall.NewProjectPathParser()
  76. yarnVersionParser := yarninstall.NewPackageJSONParser()
  77. detect := yarninstall.Detect(yarnProjectPathParser, yarnVersionParser)
  78. _, err := detect(packit.DetectContext{
  79. WorkingDir: workingDir,
  80. })
  81. if err == nil {
  82. results <- struct {
  83. string
  84. bool
  85. }{"yarn", true}
  86. } else {
  87. results <- struct {
  88. string
  89. bool
  90. }{"yarn", false}
  91. }
  92. runtime.wg.Done()
  93. }
  94. func (runtime *NodeRuntime) detectNPM(results chan struct {
  95. string
  96. bool
  97. }, workingDir string) {
  98. npmProjectPathParser := npminstall.NewProjectPathParser()
  99. npmVersionParser := npminstall.NewPackageJSONParser()
  100. detect := npminstall.Detect(npmProjectPathParser, npmVersionParser)
  101. _, err := detect(packit.DetectContext{
  102. WorkingDir: workingDir,
  103. })
  104. if err == nil {
  105. results <- struct {
  106. string
  107. bool
  108. }{"npm", true}
  109. } else {
  110. results <- struct {
  111. string
  112. bool
  113. }{"npm", false}
  114. }
  115. runtime.wg.Done()
  116. }
  117. func (runtime *NodeRuntime) detectStandalone(results chan struct {
  118. string
  119. bool
  120. }, workingDir string) {
  121. // FIXME: the detect function seems to be working for non-node projects as well?
  122. detect := nodemodulebom.Detect()
  123. _, err := detect(packit.DetectContext{
  124. WorkingDir: workingDir,
  125. })
  126. if err == nil {
  127. results <- struct {
  128. string
  129. bool
  130. }{"standalone", true}
  131. } else {
  132. results <- struct {
  133. string
  134. bool
  135. }{"standalone", false}
  136. }
  137. runtime.wg.Done()
  138. }
  139. func (runtime *NodeRuntime) Detect(workingDir string) *BuildpackInfo {
  140. results := make(chan struct {
  141. string
  142. bool
  143. }, 3)
  144. runtime.wg.Add(3)
  145. go runtime.detectYarn(results, workingDir)
  146. go runtime.detectNPM(results, workingDir)
  147. go runtime.detectStandalone(results, workingDir)
  148. runtime.wg.Wait()
  149. close(results)
  150. detected := make(map[string]bool)
  151. for result := range results {
  152. detected[result.string] = result.bool
  153. }
  154. if detected["yarn"] {
  155. return runtime.packs["yarn"]
  156. } else if detected["npm"] {
  157. return runtime.packs["npm"]
  158. } else if detected["standalone"] {
  159. return runtime.packs["standalone"]
  160. }
  161. return nil
  162. }