From fa8ab20d17be1da34764fdbb03be171199aa3149 Mon Sep 17 00:00:00 2001 From: Laurent Arnoud Date: Sun, 20 Nov 2016 18:50:38 +0100 Subject: [PATCH 1/5] Expose rubygem reverse depencencies * /gems/:rubygem_id/reverse_dependencies * search on reverse dependencies --- app/controllers/concerns/latest_version.rb | 9 ++++ .../reverse_dependencies_controller.rb | 15 ++++++ app/controllers/rubygems_controller.rb | 5 +- app/helpers/rubygems_helper.rb | 4 ++ app/models/rubygem.rb | 4 ++ .../_reverse_dependencies.html.erb | 12 +++++ app/views/reverse_dependencies/index.html.erb | 11 ++++ app/views/rubygems/_aside.html.erb | 1 + config/locales/en.yml | 5 ++ config/routes.rb | 1 + .../reverse_dependencies_controller_test.rb | 53 +++++++++++++++++++ 11 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 app/controllers/concerns/latest_version.rb create mode 100644 app/controllers/reverse_dependencies_controller.rb create mode 100644 app/views/reverse_dependencies/_reverse_dependencies.html.erb create mode 100644 app/views/reverse_dependencies/index.html.erb create mode 100644 test/functional/reverse_dependencies_controller_test.rb diff --git a/app/controllers/concerns/latest_version.rb b/app/controllers/concerns/latest_version.rb new file mode 100644 index 00000000000..b5dd791d848 --- /dev/null +++ b/app/controllers/concerns/latest_version.rb @@ -0,0 +1,9 @@ +module LatestVersion + extend ActiveSupport::Concern + + included do + def latest_version + @latest_version ||= @rubygem.versions.most_recent + end + end +end diff --git a/app/controllers/reverse_dependencies_controller.rb b/app/controllers/reverse_dependencies_controller.rb new file mode 100644 index 00000000000..0cae0a83a3e --- /dev/null +++ b/app/controllers/reverse_dependencies_controller.rb @@ -0,0 +1,15 @@ +class ReverseDependenciesController < ApplicationController + include LatestVersion + before_action :find_rubygem, only: [:index] + before_action :latest_version, only: [:index] + before_action :set_page, only: [:index] + + def index + @latest_version = @rubygem.versions.most_recent + @reverse_dependencies = @rubygem.reverse_dependencies.by_downloads + if params[:rdeps_query] && params[:rdeps_query].is_a?(String) + @reverse_dependencies = @reverse_dependencies.search(params[:rdeps_query]) + end + @reverse_dependencies = @reverse_dependencies.paginate(page: @page) + end +end diff --git a/app/controllers/rubygems_controller.rb b/app/controllers/rubygems_controller.rb index 17a8e269bda..020fc3ac0f9 100644 --- a/app/controllers/rubygems_controller.rb +++ b/app/controllers/rubygems_controller.rb @@ -1,7 +1,9 @@ class RubygemsController < ApplicationController + include LatestVersion before_action :redirect_to_root, only: [:edit, :update], unless: :signed_in? before_action :set_blacklisted_gem, only: [:show], if: :blacklisted? before_action :find_rubygem, only: [:edit, :update, :show], unless: :blacklisted? + before_action :latest_version, only: [:show], unless: :blacklisted? before_action :load_gem, only: [:edit, :update] before_action :set_page, only: :index @@ -22,8 +24,7 @@ def show if @blacklisted_gem render 'blacklisted' else - @latest_version = @rubygem.versions.most_recent - @versions = @rubygem.public_versions(5) + @versions = @rubygem.public_versions(5) if @rubygem.public_versions.any? render 'show' else diff --git a/app/helpers/rubygems_helper.rb b/app/helpers/rubygems_helper.rb index 700fc5dee4f..88c9508425d 100644 --- a/app/helpers/rubygems_helper.rb +++ b/app/helpers/rubygems_helper.rb @@ -76,6 +76,10 @@ def download_link(version) link_to_page :download, "/downloads/#{version.full_name}.gem" end + def reverse_dependencies_link(rubygem) + link_to_page :reverse_dependencies, rubygem_reverse_dependencies_path(rubygem) + end + def documentation_link(version, linkset) return unless linkset.nil? || linkset.docs.blank? link_to_page :docs, version.documentation_path diff --git a/app/models/rubygem.rb b/app/models/rubygem.rb index e1131cb9672..0bfc99908d1 100644 --- a/app/models/rubygem.rb +++ b/app/models/rubygem.rb @@ -269,6 +269,10 @@ def protected_days (updated_at + 101.days - Time.zone.now).to_i / 1.day end + def reverse_dependencies + self.class.reverse_dependencies(name) + end + private # a gem namespace is not protected if it is diff --git a/app/views/reverse_dependencies/_reverse_dependencies.html.erb b/app/views/reverse_dependencies/_reverse_dependencies.html.erb new file mode 100644 index 00000000000..1203e5d2ee4 --- /dev/null +++ b/app/views/reverse_dependencies/_reverse_dependencies.html.erb @@ -0,0 +1,12 @@ +
+ <%= form_tag rubygem_reverse_dependencies_path(@rubygem), + :id => "rdeps-search", :class => "header__search-wrap", :method => :get do %> + <%= search_field_tag :rdeps_query, params[:rdeps_query], :placeholder => "Search Reverse Deps Gems…".html_safe, :class => "header__search" %> + <%= label_tag :rdeps_query do %> + Search gems + <% end %> + <%= submit_tag '⌕', :id => 'rdeps_search_submit', :name => nil, :class => "header__search__icon" %> + <% end %> +
+ +<%= render dependencies %> diff --git a/app/views/reverse_dependencies/index.html.erb b/app/views/reverse_dependencies/index.html.erb new file mode 100644 index 00000000000..e99b500af93 --- /dev/null +++ b/app/views/reverse_dependencies/index.html.erb @@ -0,0 +1,11 @@ +<% @title = t('.title', name: @rubygem.name) %> +<% @subtitle = @latest_version.try(:slug) %> + +
+
+ <%= render partial: "reverse_dependencies", + locals: { dependencies: @reverse_dependencies } %> + <%= will_paginate @reverse_dependencies %> +
+ <%= render 'rubygems/aside' %> +
diff --git a/app/views/rubygems/_aside.html.erb b/app/views/rubygems/_aside.html.erb index c9a337ef9d8..dc4ba21572e 100644 --- a/app/views/rubygems/_aside.html.erb +++ b/app/views/rubygems/_aside.html.erb @@ -77,5 +77,6 @@ <%= unsubscribe_link(@rubygem) %> <%= atom_link(@rubygem) %> <%= report_abuse_link(@rubygem) %> + <%= reverse_dependencies_link(@rubygem) %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 1d54f92ffb8..b0d9e1d9db3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -149,6 +149,7 @@ en: report_abuse: Report Abuse badge: Badge rss: RSS + reverse_dependencies: Reverse dependencies downloads_for_this_version: "For this version" bundler_header: Gemfile copy_to_clipboard: Copy to clipboard @@ -164,6 +165,10 @@ en: no_licenses: N/A requirements_header: Requirements + reverse_dependencies: + index: + title: "Reverse dependencies for %{name}" + searches: show: subtitle: "for %{query}" diff --git a/config/routes.rb b/config/routes.rb index ae46bc68724..38983c7e486 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -139,6 +139,7 @@ constraints: { format: :js }, defaults: { format: :js } resources :versions, only: [:show, :index] + resources :reverse_dependencies, only: [:index] end end diff --git a/test/functional/reverse_dependencies_controller_test.rb b/test/functional/reverse_dependencies_controller_test.rb new file mode 100644 index 00000000000..d4cbd33a7f9 --- /dev/null +++ b/test/functional/reverse_dependencies_controller_test.rb @@ -0,0 +1,53 @@ +require 'test_helper' + +class ReverseDependenciesControllerTest < ActionController::TestCase + context "On GET to show for a gem reverse dependencies" do + setup do + @version_one = create(:version) + @rubygem_one = @version_one.rubygem + @version_two = create(:version) + @rubygem_two = @version_two.rubygem + @version_three = create(:version) + @rubygem_three = @version_three.rubygem + @version_four = create(:version) + @rubygem_four = @version_four.rubygem + + @version_two.dependencies << create(:dependency, + version: @version_two, + rubygem: @rubygem_one) + @version_three.dependencies << create(:dependency, + version: @version_three, + rubygem: @rubygem_two) + @version_four.dependencies << create(:dependency, + version: @version_four, + rubygem: @rubygem_two) + end + + should "render template" do + get :index, rubygem_id: @rubygem_one.to_param + respond_with :success + render_template :index + end + + should "show reverse dependencies" do + get :index, rubygem_id: @rubygem_one.to_param + assert page.has_content?(@rubygem_two.name) + refute page.has_content?(@rubygem_three.name) + end + + should "search reverse dependencies" do + get :index, + rubygem_id: @rubygem_two.to_param, + rdeps_query: @rubygem_three.name + assert page.has_content?(@rubygem_three.name) + refute page.has_content?(@rubygem_four.name) + end + + should "search only current reverse dependencies" do + get :index, + rubygem_id: @rubygem_two.to_param, + rdeps_query: @rubygem_one.name + refute page.has_content?(@rubygem_one.name) + end + end +end From 2cd4e199a428a008107e533e23fd968998aaacdf Mon Sep 17 00:00:00 2001 From: Laurent Arnoud Date: Sun, 18 Dec 2016 18:24:39 +0100 Subject: [PATCH 2/5] Remove duplicate @latest_version load --- app/controllers/reverse_dependencies_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/reverse_dependencies_controller.rb b/app/controllers/reverse_dependencies_controller.rb index 0cae0a83a3e..2664224a037 100644 --- a/app/controllers/reverse_dependencies_controller.rb +++ b/app/controllers/reverse_dependencies_controller.rb @@ -5,7 +5,6 @@ class ReverseDependenciesController < ApplicationController before_action :set_page, only: [:index] def index - @latest_version = @rubygem.versions.most_recent @reverse_dependencies = @rubygem.reverse_dependencies.by_downloads if params[:rdeps_query] && params[:rdeps_query].is_a?(String) @reverse_dependencies = @reverse_dependencies.search(params[:rdeps_query]) From 2a25ff4081d06c307c0826c814e36e9b61c27d97 Mon Sep 17 00:00:00 2001 From: Laurent Arnoud Date: Sun, 18 Dec 2016 18:40:50 +0100 Subject: [PATCH 3/5] Use I18n for search reverse deps input --- app/views/reverse_dependencies/_reverse_dependencies.html.erb | 4 ++-- config/locales/en.yml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/reverse_dependencies/_reverse_dependencies.html.erb b/app/views/reverse_dependencies/_reverse_dependencies.html.erb index 1203e5d2ee4..ac058f70d46 100644 --- a/app/views/reverse_dependencies/_reverse_dependencies.html.erb +++ b/app/views/reverse_dependencies/_reverse_dependencies.html.erb @@ -1,9 +1,9 @@
<%= form_tag rubygem_reverse_dependencies_path(@rubygem), :id => "rdeps-search", :class => "header__search-wrap", :method => :get do %> - <%= search_field_tag :rdeps_query, params[:rdeps_query], :placeholder => "Search Reverse Deps Gems…".html_safe, :class => "header__search" %> + <%= search_field_tag :rdeps_query, params[:rdeps_query], :placeholder => t('.search_reverse_dependencies').html_safe, :class => "header__search" %> <%= label_tag :rdeps_query do %> - Search gems + <%= t('.search_reverse_dependencies').html_safe %> <% end %> <%= submit_tag '⌕', :id => 'rdeps_search_submit', :name => nil, :class => "header__search__icon" %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index b0d9e1d9db3..50da05675e2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -168,6 +168,8 @@ en: reverse_dependencies: index: title: "Reverse dependencies for %{name}" + reverse_dependencies: + search_reverse_dependencies: "Search reverse dependencies Gems…" searches: show: From fa0f34b0406c0b28b82a8ea354b35758b5b8e40d Mon Sep 17 00:00:00 2001 From: Laurent Arnoud Date: Wed, 21 Dec 2016 18:56:28 +0100 Subject: [PATCH 4/5] Use Ruby 1.9 hash syntax for _reverse_dependencies.html --- .../reverse_dependencies/_reverse_dependencies.html.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/reverse_dependencies/_reverse_dependencies.html.erb b/app/views/reverse_dependencies/_reverse_dependencies.html.erb index ac058f70d46..14190c26be2 100644 --- a/app/views/reverse_dependencies/_reverse_dependencies.html.erb +++ b/app/views/reverse_dependencies/_reverse_dependencies.html.erb @@ -1,11 +1,11 @@
<%= form_tag rubygem_reverse_dependencies_path(@rubygem), - :id => "rdeps-search", :class => "header__search-wrap", :method => :get do %> - <%= search_field_tag :rdeps_query, params[:rdeps_query], :placeholder => t('.search_reverse_dependencies').html_safe, :class => "header__search" %> + id: "rdeps-search", class: "header__search-wrap", method: :get do %> + <%= search_field_tag :rdeps_query, params[:rdeps_query], placeholder: t('.search_reverse_dependencies').html_safe, class: "header__search" %> <%= label_tag :rdeps_query do %> <%= t('.search_reverse_dependencies').html_safe %> <% end %> - <%= submit_tag '⌕', :id => 'rdeps_search_submit', :name => nil, :class => "header__search__icon" %> + <%= submit_tag '⌕', id: 'rdeps_search_submit', name: nil, class: "header__search__icon" %> <% end %>
From 012c1e28a91e3c471bc6633205dbdfd90052a615 Mon Sep 17 00:00:00 2001 From: Laurent Arnoud Date: Wed, 21 Dec 2016 19:00:52 +0100 Subject: [PATCH 5/5] Include latest_version and gem_download for reverse Thanks-to: @sonalkr132 --- app/controllers/reverse_dependencies_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/reverse_dependencies_controller.rb b/app/controllers/reverse_dependencies_controller.rb index 2664224a037..8daae5bc250 100644 --- a/app/controllers/reverse_dependencies_controller.rb +++ b/app/controllers/reverse_dependencies_controller.rb @@ -5,7 +5,9 @@ class ReverseDependenciesController < ApplicationController before_action :set_page, only: [:index] def index - @reverse_dependencies = @rubygem.reverse_dependencies.by_downloads + @reverse_dependencies = @rubygem.reverse_dependencies + .by_downloads + .includes(:latest_version, :gem_download) if params[:rdeps_query] && params[:rdeps_query].is_a?(String) @reverse_dependencies = @reverse_dependencies.search(params[:rdeps_query]) end