require "set" require "clouseau" module VMC class Detector # "Basic" framework names for a detected language PSEUDO_FRAMEWORKS = { :node => "node", :python => "wsgi", :java => "java_web", :php => "php", :erlang => "otp_rebar", :dotnet => "dotNet" } # Mismatched framework names FRAMEWORK_NAMES = { :rails => "rails3" } # Clouseau language symbol => matching runtime names LANGUAGE_RUNTIMES = { :ruby => /^ruby.*/, :java => /^java.*/, :node => /^node.*/, :erlang => /^erlang.*/, :dotnet => /^dotNet.*/, :python => /^python.*/, :php => /^php.*/ } def initialize(client, path) @client = client @path = path end # detect the framework def detect_framework detected && frameworks[detected] end # detect the language and return the appropriate runtimes def detect_runtimes if detected && lang = detected.language_name runtimes_for(lang) else [] end end # determine runtimes for a given framework based on the language its # detector reports itself as def runtimes(framework) if detector = detectors[framework] runtimes_for(detector.language_name) else [] end end # determine suitable memory allocation via the framework's detector def suggested_memory(framework) if detector = detectors[framework] detector.memory_suggestion end end # helper so that this is cached somewhere def all_runtimes @all_runtimes ||= @client.runtimes end # helper so that this is cached somewhere def all_frameworks @all_frameworks ||= @client.frameworks end def detected @detected ||= Clouseau.detect(@path) end private def map_detectors! @framework_detectors = {} @detector_frameworks = {} Clouseau.detectors.each do |d| name = d.framework_name lang = d.language_name framework = all_frameworks.find { |f| f.name == name.to_s || f.name == FRAMEWORK_NAMES[name] } framework ||= all_frameworks.find { |f| f.name == PSEUDO_FRAMEWORKS[lang] } next unless framework @framework_detectors[framework] = d @detector_frameworks[d] = framework end nil end # Framework -> Detector def detectors map_detectors! unless @framework_detectors @framework_detectors end # Detector -> Framework def frameworks map_detectors! unless @detector_frameworks @detector_frameworks end def runtimes_for(language) all_runtimes.select do |r| LANGUAGE_RUNTIMES[language] === r.name end end end end