PageRenderTime 23ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Library/Homebrew/dependency_collector.rb

https://gitlab.com/0072016/0072016-Googlebot2
Ruby | 175 lines | 144 code | 19 blank | 12 comment | 10 complexity | 585bf47bcedc6d826240143ae32deeb0 MD5 | raw file
  1. require "dependency"
  2. require "dependencies"
  3. require "ld64_dependency"
  4. require "requirement"
  5. require "requirements"
  6. require "set"
  7. ## A dependency is a formula that another formula needs to install.
  8. ## A requirement is something other than a formula that another formula
  9. ## needs to be present. This includes external language modules,
  10. ## command-line tools in the path, or any arbitrary predicate.
  11. ##
  12. ## The `depends_on` method in the formula DSL is used to declare
  13. ## dependencies and requirements.
  14. # This class is used by `depends_on` in the formula DSL to turn dependency
  15. # specifications into the proper kinds of dependencies and requirements.
  16. class DependencyCollector
  17. # Define the languages that we can handle as external dependencies.
  18. LANGUAGE_MODULES = Set[
  19. :lua, :lua51, :perl, :python, :python3, :ruby
  20. ].freeze
  21. CACHE = {}
  22. def self.clear_cache
  23. CACHE.clear
  24. end
  25. attr_reader :deps, :requirements
  26. def initialize
  27. @deps = Dependencies.new
  28. @requirements = Requirements.new
  29. end
  30. def add(spec)
  31. case dep = fetch(spec)
  32. when Dependency
  33. @deps << dep
  34. when Requirement
  35. @requirements << dep
  36. end
  37. dep
  38. end
  39. def fetch(spec)
  40. CACHE.fetch(cache_key(spec)) { |key| CACHE[key] = build(spec) }
  41. end
  42. def cache_key(spec)
  43. if Resource === spec && spec.download_strategy == CurlDownloadStrategy
  44. File.extname(spec.url)
  45. else
  46. spec
  47. end
  48. end
  49. def build(spec)
  50. spec, tags = Hash === spec ? spec.first : spec
  51. parse_spec(spec, Array(tags))
  52. end
  53. private
  54. def parse_spec(spec, tags)
  55. case spec
  56. when String
  57. parse_string_spec(spec, tags)
  58. when Resource
  59. resource_dep(spec, tags)
  60. when Symbol
  61. parse_symbol_spec(spec, tags)
  62. when Requirement, Dependency
  63. spec
  64. when Class
  65. parse_class_spec(spec, tags)
  66. else
  67. raise TypeError, "Unsupported type #{spec.class.name} for #{spec.inspect}"
  68. end
  69. end
  70. def parse_string_spec(spec, tags)
  71. if HOMEBREW_TAP_FORMULA_REGEX === spec
  72. TapDependency.new(spec, tags)
  73. elsif tags.empty?
  74. Dependency.new(spec, tags)
  75. elsif (tag = tags.first) && LANGUAGE_MODULES.include?(tag)
  76. LanguageModuleRequirement.new(tag, spec, tags[1])
  77. else
  78. Dependency.new(spec, tags)
  79. end
  80. end
  81. def parse_symbol_spec(spec, tags)
  82. case spec
  83. when :x11 then X11Requirement.new(spec.to_s, tags)
  84. when :xcode then XcodeRequirement.new(tags)
  85. when :macos then MinimumMacOSRequirement.new(tags)
  86. when :mysql then MysqlRequirement.new(tags)
  87. when :postgresql then PostgresqlRequirement.new(tags)
  88. when :gpg then GPGRequirement.new(tags)
  89. when :fortran then FortranRequirement.new(tags)
  90. when :mpi then MPIRequirement.new(*tags)
  91. when :tex then TeXRequirement.new(tags)
  92. when :arch then ArchRequirement.new(tags)
  93. when :hg then MercurialRequirement.new(tags)
  94. when :python then PythonRequirement.new(tags)
  95. when :python3 then Python3Requirement.new(tags)
  96. when :java then JavaRequirement.new(tags)
  97. when :rbenv then RbenvRequirement.new(tags)
  98. when :ruby then RubyRequirement.new(tags)
  99. when :osxfuse then OsxfuseRequirement.new(tags)
  100. when :tuntap then TuntapRequirement.new(tags)
  101. when :ant then ant_dep(spec, tags)
  102. when :apr then AprRequirement.new(tags)
  103. when :emacs then EmacsRequirement.new(tags)
  104. # Tiger's ld is too old to properly link some software
  105. when :ld64 then LD64Dependency.new if MacOS.version < :leopard
  106. when :python2
  107. PythonRequirement.new(tags)
  108. else
  109. raise ArgumentError, "Unsupported special dependency #{spec.inspect}"
  110. end
  111. end
  112. def parse_class_spec(spec, tags)
  113. if spec < Requirement
  114. spec.new(tags)
  115. else
  116. raise TypeError, "#{spec.inspect} is not a Requirement subclass"
  117. end
  118. end
  119. def ant_dep(spec, tags)
  120. if MacOS.version >= :mavericks
  121. Dependency.new(spec.to_s, tags)
  122. end
  123. end
  124. def resource_dep(spec, tags)
  125. tags << :build
  126. strategy = spec.download_strategy
  127. case
  128. when strategy <= CurlDownloadStrategy
  129. parse_url_spec(spec.url, tags)
  130. when strategy <= GitDownloadStrategy
  131. GitRequirement.new(tags)
  132. when strategy <= MercurialDownloadStrategy
  133. MercurialRequirement.new(tags)
  134. when strategy <= FossilDownloadStrategy
  135. Dependency.new("fossil", tags)
  136. when strategy <= BazaarDownloadStrategy
  137. Dependency.new("bazaar", tags)
  138. when strategy <= CVSDownloadStrategy
  139. Dependency.new("cvs", tags) if MacOS.version >= :mavericks || !MacOS::Xcode.provides_cvs?
  140. when strategy < AbstractDownloadStrategy
  141. # allow unknown strategies to pass through
  142. else
  143. raise TypeError,
  144. "#{strategy.inspect} is not an AbstractDownloadStrategy subclass"
  145. end
  146. end
  147. def parse_url_spec(url, tags)
  148. case File.extname(url)
  149. when ".xz" then Dependency.new("xz", tags)
  150. when ".lha", ".lzh" then Dependency.new("lha", tags)
  151. when ".lz" then Dependency.new("lzip", tags)
  152. when ".rar" then Dependency.new("unrar", tags)
  153. when ".7z" then Dependency.new("p7zip", tags)
  154. end
  155. end
  156. end