python.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package buildpacks
  2. import (
  3. "strings"
  4. "sync"
  5. "github.com/google/go-github/github"
  6. )
  7. type pythonRuntime struct {
  8. wg sync.WaitGroup
  9. }
  10. func NewPythonRuntime() Runtime {
  11. return &pythonRuntime{}
  12. }
  13. func (runtime *pythonRuntime) detectPipenv(results chan struct {
  14. string
  15. bool
  16. }, directoryContent []*github.RepositoryContent) {
  17. pipfileFound := false
  18. pipfileLockFound := false
  19. for i := 0; i < len(directoryContent); i++ {
  20. name := directoryContent[i].GetName()
  21. if name == "Pipfile" {
  22. pipfileFound = true
  23. } else if name == "Pipfile.lock" {
  24. pipfileLockFound = true
  25. }
  26. if pipfileFound && pipfileLockFound {
  27. break
  28. }
  29. }
  30. if pipfileFound && pipfileLockFound {
  31. results <- struct {
  32. string
  33. bool
  34. }{pipenv, true}
  35. }
  36. runtime.wg.Done()
  37. }
  38. func (runtime *pythonRuntime) detectPip(results chan struct {
  39. string
  40. bool
  41. }, directoryContent []*github.RepositoryContent) {
  42. requirementsTxtFound := false
  43. for i := 0; i < len(directoryContent); i++ {
  44. name := directoryContent[i].GetName()
  45. if name == "requirements.txt" {
  46. requirementsTxtFound = true
  47. }
  48. }
  49. if requirementsTxtFound {
  50. results <- struct {
  51. string
  52. bool
  53. }{pip, true}
  54. }
  55. runtime.wg.Done()
  56. }
  57. func (runtime *pythonRuntime) detectConda(results chan struct {
  58. string
  59. bool
  60. }, directoryContent []*github.RepositoryContent) {
  61. environmentFound := false
  62. packageListFound := false
  63. for i := 0; i < len(directoryContent); i++ {
  64. name := directoryContent[i].GetName()
  65. if name == "environment.yml" {
  66. environmentFound = true
  67. break
  68. } else if name == "package-list.txt" {
  69. packageListFound = true
  70. break
  71. }
  72. }
  73. if environmentFound || packageListFound {
  74. results <- struct {
  75. string
  76. bool
  77. }{conda, true}
  78. }
  79. runtime.wg.Done()
  80. }
  81. func (runtime *pythonRuntime) detectStandalone(results chan struct {
  82. string
  83. bool
  84. }, directoryContent []*github.RepositoryContent) {
  85. pyFound := false
  86. for i := 0; i < len(directoryContent); i++ {
  87. name := directoryContent[i].GetName()
  88. if strings.HasSuffix(name, ".py") {
  89. pyFound = true
  90. break
  91. }
  92. }
  93. if pyFound {
  94. results <- struct {
  95. string
  96. bool
  97. }{standalone, true}
  98. }
  99. runtime.wg.Done()
  100. }
  101. func (runtime *pythonRuntime) Detect(
  102. client *github.Client,
  103. directoryContent []*github.RepositoryContent,
  104. owner, name, path string,
  105. repoContentOptions github.RepositoryContentGetOptions,
  106. paketo, heroku *BuilderInfo,
  107. ) error {
  108. results := make(chan struct {
  109. string
  110. bool
  111. }, 4)
  112. runtime.wg.Add(4)
  113. go runtime.detectPipenv(results, directoryContent)
  114. go runtime.detectPip(results, directoryContent)
  115. go runtime.detectConda(results, directoryContent)
  116. go runtime.detectStandalone(results, directoryContent)
  117. runtime.wg.Wait()
  118. close(results)
  119. paketoBuildpackInfo := BuildpackInfo{
  120. Name: "Python",
  121. Buildpack: "paketobuildpacks/python",
  122. }
  123. herokuBuildpackInfo := BuildpackInfo{
  124. Name: "Python",
  125. Buildpack: "heroku/python",
  126. }
  127. if len(results) == 0 {
  128. paketo.Others = append(paketo.Others, paketoBuildpackInfo)
  129. heroku.Others = append(heroku.Others, herokuBuildpackInfo)
  130. return nil
  131. }
  132. paketo.Detected = append(paketo.Detected, paketoBuildpackInfo)
  133. heroku.Detected = append(heroku.Detected, herokuBuildpackInfo)
  134. return nil
  135. }