class DependencyWorker

Constants

EMPTY_STATUS_HASH
OUTDATED_TYPES
STATUS_TYPES

Order is significant for purposes of calculating results

Public Instance Methods

perform(identifier, lang, locations, dependency_types, to_addr, auth_token = nil) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 16
def perform(identifier, lang, locations, dependency_types, to_addr, auth_token = nil)
  log_info 'Running Worker!'
  @lang = get_lang(lang)
  @provider = get_provider(identifier)
  @auth_token = auth_token
  old_dependencies = get_from_store(identifier) || {}
  begin
    dependencies = {:locations => {}}
    locations.each do |name, url|
      contents = http_get(url)
      dependencies[:locations][name] = get_results(@lang.parse_file(name, contents), dependency_types)
    end
    dependencies.merge!(generate_stats(dependencies[:locations]))
    @nothing_changed = dependencies == old_dependencies
    unless @nothing_changed
      add_to_store(identifier, dependencies)
      add_to_store("diff-#{identifier}", diff_dependencies(old_dependencies[:locations], dependencies[:locations]))
    end
  ensure
    unless @nothing_changed
      badge_worker(identifier)
      mail_worker(identifier, to_addr) if to_addr && (!old_dependencies.empty? || ::CuttingEdge::ALWAYS_MAIL)
    end
    GC.start
  end
end

Private Instance Methods

change_type(old_status, new_status) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 67
def change_type(old_status, new_status)
  case
  when new_status == :ok
    :good_change
  when outdated_type?(new_status) && old_status && STATUS_TYPES.find_index(new_status) > STATUS_TYPES.find_index(old_status)
    :good_change
  else
    :bad_change
  end
end
dependency(name, requirement, latest, type) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 127
def dependency(name, requirement, latest, type)
  {
    :name => name,
    :required => requirement,
    :latest => latest,
    :type => type,
    :url => requirement == 'unknown' ? nil : @lang.website(name)
  }
end
diff_dependencies(old, new) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 45
def diff_dependencies(old, new)
  base = old ? old : new.transform_values {|_v| empty_status_hash }
  diff = Hashdiff.diff(base, new)
  additions = diff.select {|x| x.first == '+'}
  deletions = diff.select {|x| x.first == '-'}
  result = {}
  
  additions.each do |addition|
    status = parse_diff_status(addition[1])
    name = addition.last[:name]
    old_status = deletions.find {|x| x.last[:name] == name}
    old_status = parse_diff_status(old_status[1]) if old_status
    result[name] = change_type(old_status, status)
  end
  result
end
empty_status_hash() click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 78
def empty_status_hash
  STATUS_TYPES.inject({}) {|result, type| result[type] = []; result }
end
generate_stats(locations) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 103
def generate_stats(locations)
  results = {}
  STATUS_TYPES.each do |type|
    num = stats(type, locations)
    results[type] = num
    if outdated_type?(type)
      results[:outdated_total] = results[:outdated_total].to_i + num
      results[:outdated] = type unless results[:outdated] || num == 0
    end
  end
  results[:outdated] = :unknown if results[:outdated_total] == 0 && results[:ok] == 0
  results[:outdated] = :up_to_date unless results[:outdated]
  results
end
get_lang(lang) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 137
def get_lang(lang)
  Object.const_get("#{lang.capitalize}Lang")
end
get_provider(identifier) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 141
def get_provider(identifier)
  ::CuttingEdge.const_get("#{identifier.split('/').first.capitalize}Repository")
end
get_results(dependencies, dependency_types) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 82
def get_results(dependencies, dependency_types)
  results = empty_status_hash
  if dependencies
    dependencies.select! {|dep| dependency_types.include?(dep.first.type)}
    dependencies.each do |dep, latest_version|
      dependency_hash = dependency(dep.name, dep.requirement.to_s, latest_version.to_s, dep.type)
      if dependency_hash[:required] == 'unknown'
        results[:no_requirement] << dependency_hash
      elsif latest_version.nil?
        results[:unknown] << dependency_hash
      elsif is_outdated?(dep, latest_version)
        outdated = version_requirement_diff(dep.requirement, latest_version.respond_to?(:last) ? latest_version.last : latest_version)
        results[outdated] << dependency_hash
      else
        results[:ok] << dependency_hash
      end 
    end
  end
  results
end
http_get(url) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 145
def http_get(url)
  begin
    response = HTTP.headers(@provider.headers(@auth_token)).get(url)
    response.status == 200 ? response.to_s : nil
  rescue HTTP::TimeoutError => e
    log_info("Encountered error when fetching latest version of #{url}: #{e.class} #{e.message}")
  end
end
is_outdated?(dependency, latest_version) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 154
def is_outdated?(dependency, latest_version)
  !dependency.requirement.satisfied_by?(latest_version)
end
outdated_type?(type) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 158
def outdated_type?(type)
  OUTDATED_TYPES.include?(type)
end
parse_diff_status(str) click to toggle source
# File lib/cutting_edge/workers/dependency.rb, line 62
def parse_diff_status(str)
  # Hashdiff generates strings of the form "gemfile.ok[1]" to indicate this is the first change to the Hash under the :ok key
  str.split('.').last.split('[').first.to_sym
end
stats(stat, locations) click to toggle source

Add up the number of dependencies of type `stat` (e.g. :ok) in the different locations where dependencies are stored.

# File lib/cutting_edge/workers/dependency.rb, line 119
def stats(stat, locations)
  sum = 0
  locations.each do |name, dependencies|
    sum = sum + dependencies[stat].length
  end
  sum
end