Permalink
Browse files

Merge pull request #540 from alup/master

[feature] List reverse dependencies for a specific gem
  • Loading branch information...
sferik committed Mar 25, 2013
2 parents 94eeef2 + 7aaf055 commit 471671306c1bb2c365033a931d05543074dd6caa
@@ -46,6 +46,16 @@ def unyank
end
end
+ def reverse_dependencies
+ rubygems = Rubygem.reverse_dependencies(params[:id])
+
+ if params[:short]
+ respond_with(rubygems.map(&:name), :yamlish => true)
+ else
+ respond_with(rubygems, :yamlish => true)
+ end
+ end
+
private
def validate_gem_and_version
@@ -1,14 +1,29 @@
class Api::V1::VersionsController < Api::BaseController
respond_to :json, :xml, :yaml
+ before_filter :find_rubygem
def show
- if rubygem = Rubygem.find_by_name(params[:id]) and rubygem.public_versions.count.nonzero?
+ if @rubygem.public_versions.count.nonzero?
- if stale?(rubygem)
- respond_with(rubygem.public_versions, :yamlish => true)
+ if stale?(@rubygem)
+ respond_with(@rubygem.public_versions, :yamlish => true)
end
else
render :text => "This rubygem could not be found.", :status => 404
end
end
+
+ def reverse_dependencies
+ versions = Version.reverse_dependencies(params[:id])
+
+ if params[:short]
+ respond_with(versions.map(&:full_name), :yamlish => true)
+ else
+ respond_to do |format|
+ format.json { render :json => versions.map { |v| v.as_json.merge("full_name" => v.full_name) } }
+ format.xml { render :xml => versions.map { |v| v.payload.merge("full_name" => v.full_name) } }
+ format.yaml { render :text => versions.map { |v| v.payload.merge("full_name" => v.full_name) }.to_yaml }
+ end
+ end
+ end
end
View
@@ -45,6 +45,10 @@ def self.name_starts_with(letter)
where("upper(name) like upper(?)", "#{letter}%")
end
+ def self.reverse_dependencies(name)
+ find(Version.reverse_dependencies(name).map(&:rubygem_id))
+ end
+
def self.total_count
with_versions.count
end
View
@@ -15,6 +15,11 @@ class Version < ActiveRecord::Base
validate :platform_and_number_are_unique, :on => :create
validate :authors_format, :on => :create
+ def self.reverse_dependencies(name)
+ joins({ dependencies: :rubygem }).
+ where(rubygems: { name: name })
+ end
+
def self.owned_by(user)
where(:rubygem_id => user.rubygem_ids)
end
View
@@ -26,6 +26,12 @@
# resources :versions, :only => :show, :format => true do
get 'versions/:id.:format', :to => 'versions#show', :as => 'version'
resources :versions, :only => :show do
+ member do
+ # In Rails 3.1, the following line can be replaced with:
+ # get :reverse_dependencies, :format => true
+ get 'reverse_dependencies.:format', :to => 'versions#reverse_dependencies', :as => 'reverse_dependencies'
+ end
+
# In Rails 3.1, the next TWO lines can be replaced with:
# resources :downloads, :only => :show, :controller => 'versions/downloads', :format => true do
get 'downloads.:format', :to => 'versions/downloads#index', :as => 'downloads'
@@ -42,6 +48,9 @@
resources :dependencies, :only => :index
resources :rubygems, :path => 'gems', :only => [:create, :show, :index], :id => Patterns::LAZY_ROUTE_PATTERN, :format => /json|xml|yaml/ do
+ member do
+ get :reverse_dependencies
+ end
collection do
delete :yank
put :unyank
@@ -419,4 +419,50 @@ def should_return_just_updated_gems(gems)
end
end
end
+
+ context "on GET to reverse_dependencies" do
+ setup do
+ @dep_rubygem = create(:rubygem)
+ @gem_one = create(:rubygem)
+ @gem_two = create(:rubygem)
+ @gem_three = create(:rubygem)
+ @gem_four = create(:rubygem)
+ @version_one_latest = create(:version, :rubygem => @gem_one, :number => '0.2')
+ @version_one_earlier = create(:version, :rubygem => @gem_one, :number => '0.1')
+ @version_two_latest = create(:version, :rubygem => @gem_two, :number => '1.0')
+ @version_two_earlier = create(:version, :rubygem => @gem_two, :number => '0.5')
+ @version_three = create(:version, :rubygem => @gem_three, :number => '1.7')
+ @version_four = create(:version, :rubygem => @gem_four, :number => '3.9')
+
+ @version_one_latest.dependencies << create(:dependency, :version => @version_one_latest, :rubygem => @dep_rubygem)
+ @version_two_earlier.dependencies << create(:dependency, :version => @version_two_earlier, :rubygem => @dep_rubygem)
+ @version_three.dependencies << create(:dependency, :version => @version_three, :rubygem => @dep_rubygem)
+ end
+
+ should "give all reverse dependencies" do
+ get :reverse_dependencies, :id => @dep_rubygem.to_param, :format => "json"
+ gems = MultiJson.load(@response.body).map { |h| h["name"] }
+
+ assert_equal 3, gems.size
+
+ assert gems.include?(@gem_one.name)
+ assert gems.include?(@gem_two.name)
+ assert gems.include?(@gem_three.name)
+ assert ! gems.include?(@gem_four.name)
+ end
+
+ context "with 'short=true' param" do
+ should "return only names of reverse dependencies" do
+ get :reverse_dependencies, :id => @dep_rubygem.to_param, :format => "json", :short => true
+ gems = MultiJson.load(@response.body)
+
+ assert_equal 3, gems.size
+
+ assert gems.include?(@gem_one.name)
+ assert gems.include?(@gem_two.name)
+ assert gems.include?(@gem_three.name)
+ assert ! gems.include?(@gem_four.name)
+ end
+ end
+ end
end
@@ -5,6 +5,10 @@ def get_show(rubygem, format='json')
get :show, :id => rubygem.name, :format => format
end
+ def get_reverse_dependencies(rubygem, options={ :format => 'json' })
+ get :reverse_dependencies, options.merge(:id => rubygem.name)
+ end
+
def self.should_respond_to(format)
context "with #{format.to_s.upcase}" do
should "have a list of versions for the first gem" do
@@ -84,7 +88,7 @@ def set_cache_header(timestamp)
context "on GET to show for an unknown gem" do
setup do
- get :show, :id => "nonexistent_gem"
+ get :show, :id => "nonexistent_gem", :format => "json"
end
should "return a 404" do
@@ -126,4 +130,49 @@ def set_cache_header(timestamp)
end
end
+ context "on GET to reverse_dependencies" do
+ setup do
+ @dep_rubygem = create(:rubygem)
+ @gem_one = create(:rubygem)
+ @gem_two = create(:rubygem)
+ @gem_three = create(:rubygem)
+ @version_one_latest = create(:version, :rubygem => @gem_one, :number => '0.2', :full_name => "gem_one-0.2")
+ @version_one_earlier = create(:version, :rubygem => @gem_one, :number => '0.1', :full_name => "gem_one-0.1")
+ @version_two_latest = create(:version, :rubygem => @gem_two, :number => '1.0', :full_name => "gem_two-1.0")
+ @version_two_earlier = create(:version, :rubygem => @gem_two, :number => '0.5', :full_name => "gem_two-0.5")
+ @version_three = create(:version, :rubygem => @gem_three, :number => '1.7', :full_name => "gem_three-1.7")
+
+ @version_one_latest.dependencies << create(:dependency, :version => @version_one_latest, :rubygem => @dep_rubygem)
+ @version_two_earlier.dependencies << create(:dependency, :version => @version_two_earlier, :rubygem => @dep_rubygem)
+ @version_three.dependencies << create(:dependency, :version => @version_three, :rubygem => @dep_rubygem)
+ end
+
+ should "give all depended gem versions" do
+ get_reverse_dependencies(@dep_rubygem)
+ ret_versions = MultiJson.load(@response.body).map { |h| h["number"] }
+
+ assert_equal 3, ret_versions.size
+
+ assert ret_versions.include?(@version_one_latest.number)
+ assert ret_versions.include?(@version_two_earlier.number)
+ assert ret_versions.include?(@version_three.number)
+ assert ! ret_versions.include?(@version_one_earlier.number)
+ assert ! ret_versions.include?(@version_two_latest.number)
+ end
+
+ context "with 'short=true' param" do
+ should "return only names of reverse dependencies" do
+ get_reverse_dependencies(@dep_rubygem, :format => "json", :short => true)
+ ret_versions = MultiJson.load(@response.body)
+
+ assert_equal 3, ret_versions.size
+
+ assert ret_versions.include?(@version_one_latest.full_name)
+ assert ret_versions.include?(@version_two_earlier.full_name)
+ assert ret_versions.include?(@version_three.full_name)
+ assert ! ret_versions.include?(@version_one_earlier.full_name)
+ assert ! ret_versions.include?(@version_two_latest.full_name)
+ end
+ end
+ end
end
View
@@ -142,6 +142,37 @@ class RubygemTest < ActiveSupport::TestCase
end
end
+ context ".reverse_dependencies" do
+ setup do
+ @dep_rubygem = create(:rubygem)
+ @gem_one = create(:rubygem)
+ @gem_two = create(:rubygem)
+ @gem_three = create(:rubygem)
+ @gem_four = create(:rubygem)
+ @version_one_latest = create(:version, :rubygem => @gem_one, :number => '0.2')
+ @version_one_earlier = create(:version, :rubygem => @gem_one, :number => '0.1')
+ @version_two_latest = create(:version, :rubygem => @gem_two, :number => '1.0')
+ @version_two_earlier = create(:version, :rubygem => @gem_two, :number => '0.5')
+ @version_three = create(:version, :rubygem => @gem_three, :number => '1.7')
+ @version_four = create(:version, :rubygem => @gem_four, :number => '3.9')
+
+ @version_one_latest.dependencies << create(:dependency, :version => @version_one_latest, :rubygem => @dep_rubygem)
+ @version_two_earlier.dependencies << create(:dependency, :version => @version_two_earlier, :rubygem => @dep_rubygem)
+ @version_three.dependencies << create(:dependency, :version => @version_three, :rubygem => @dep_rubygem)
+ end
+
+ should "return all depended rubygems" do
+ gem_list = Rubygem.reverse_dependencies(@dep_rubygem.name)
+
+ assert_equal 3, gem_list.size
+
+ assert gem_list.include?(@gem_one)
+ assert gem_list.include?(@gem_two)
+ assert gem_list.include?(@gem_three)
+ assert ! gem_list.include?(@gem_four)
+ end
+ end
+
context "with a rubygem" do
setup do
@rubygem = build(:rubygem, :linkset => nil)
View
@@ -58,6 +58,37 @@ class VersionTest < ActiveSupport::TestCase
end
end
+ context ".reverse_dependencies" do
+ setup do
+ @dep_rubygem = create(:rubygem)
+ @gem_one = create(:rubygem)
+ @gem_two = create(:rubygem)
+ @gem_three = create(:rubygem)
+ @version_one_latest = create(:version, :rubygem => @gem_one, :number => '0.2')
+ @version_one_earlier = create(:version, :rubygem => @gem_one, :number => '0.1')
+ @version_two_latest = create(:version, :rubygem => @gem_two, :number => '1.0')
+ @version_two_earlier = create(:version, :rubygem => @gem_two, :number => '0.5')
+ @version_three = create(:version, :rubygem => @gem_three, :number => '1.7')
+
+ @version_one_latest.dependencies << create(:dependency, :version => @version_one_latest, :rubygem => @dep_rubygem)
+ @version_two_earlier.dependencies << create(:dependency, :version => @version_two_earlier, :rubygem => @dep_rubygem)
+ @version_three.dependencies << create(:dependency, :version => @version_three, :rubygem => @dep_rubygem)
+ end
+
+ should "return all depended gem versions" do
+ version_list = Version.reverse_dependencies(@dep_rubygem.name)
+
+ assert_equal 3, version_list.size
+
+ assert version_list.include?(@version_one_latest)
+ assert version_list.include?(@version_two_earlier)
+ assert version_list.include?(@version_three)
+ assert ! version_list.include?(@version_one_earlier)
+ assert ! version_list.include?(@version_two_latest)
+ end
+ end
+
+
context "updated gems" do
setup do
Timecop.freeze Date.today

0 comments on commit 4716713

Please sign in to comment.