diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 003f90d831b..363357efacd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -68,6 +68,10 @@ def find_rubygem end end + def find_versioned_links + @versioned_links = @rubygem.links(@latest_version) + end + def set_page @page = params[:page].respond_to?(:to_i) ? [1, params[:page].to_i].max : 1 end diff --git a/app/controllers/reverse_dependencies_controller.rb b/app/controllers/reverse_dependencies_controller.rb index 023ff1a49e9..b8610bef5ef 100644 --- a/app/controllers/reverse_dependencies_controller.rb +++ b/app/controllers/reverse_dependencies_controller.rb @@ -3,6 +3,7 @@ class ReverseDependenciesController < ApplicationController before_action :find_rubygem, only: [:index] before_action :latest_version, only: [:index] before_action :set_page, only: [:index] + before_action :find_versioned_links, only: [:index] def index @reverse_dependencies = @rubygem.reverse_dependencies diff --git a/app/controllers/rubygems_controller.rb b/app/controllers/rubygems_controller.rb index 020fc3ac0f9..2995693e0bd 100644 --- a/app/controllers/rubygems_controller.rb +++ b/app/controllers/rubygems_controller.rb @@ -4,6 +4,7 @@ class RubygemsController < ApplicationController 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 :find_versioned_links, only: [:show], unless: :blacklisted? before_action :load_gem, only: [:edit, :update] before_action :set_page, only: :index diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index 315db73a999..23269c983ab 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -8,6 +8,7 @@ def index def show @latest_version = Version.find_from_slug!(@rubygem.id, params[:id]) @versions = @rubygem.public_versions_with_extra_version(@latest_version) + @versioned_links = @rubygem.links(@latest_version) render "rubygems/show" end end diff --git a/app/helpers/rubygems_helper.rb b/app/helpers/rubygems_helper.rb index 88c9508425d..f26d813337f 100644 --- a/app/helpers/rubygems_helper.rb +++ b/app/helpers/rubygems_helper.rb @@ -72,19 +72,10 @@ def atom_link(rubygem) class: 'gem__link t-list__item', id: :rss end - 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 - end - def badge_link(rubygem) badge_url = "https://badge.fury.io/rb/#{rubygem.name}/install" link_to t(".links.badge"), badge_url, class: "gem__link t-list__item", id: :badge diff --git a/app/models/links.rb b/app/models/links.rb new file mode 100644 index 00000000000..c4b233bcbde --- /dev/null +++ b/app/models/links.rb @@ -0,0 +1,65 @@ +class Links + # Links available for indexed gems + LINKS = { + 'home' => 'homepage_uri', + 'code' => 'source_code_uri', + 'docs' => 'documentation_uri', + 'wiki' => 'wiki_uri', + 'mail' => 'mailing_list_uri', + 'bugs' => 'bug_tracker_uri', + 'download' => 'download_uri' + }.freeze + + # Links available for non-indexed gems + NON_INDEXED_LINKS = { + 'docs' => 'documentation_uri' + }.freeze + + attr_accessor :rubygem, :version, :linkset + + def initialize(rubygem, version) + self.rubygem = rubygem + self.version = version + self.linkset = rubygem.linkset + end + + def links + version.indexed ? LINKS : NON_INDEXED_LINKS + end + + delegate :keys, to: :links + + def each + return enum_for(:each) unless block_given? + links.each do |short, long| + value = send(long) + yield short, value if value + end + end + + # documentation uri: + # if metadata has it defined, use that + # or if linksets has it defined, use that + # else, generate one from gem name and version number + def documentation_uri + version.metadata["documentation_uri"].presence || + linkset&.docs.presence || + "http://www.rubydoc.info/gems/#{rubygem.name}/#{version.number}" + end + + # technically this is a path + def download_uri + "/downloads/#{version.full_name}.gem" if version.indexed + end + + # define getters for each of the uris (both short `home` or long `homepage_uri` versions) + # don't define for download_uri since it has special logic and is already defined + LINKS.each do |short, long| + unless method_defined?(long) + define_method(long) do + version.metadata[long].presence || linkset&.public_send(short) + end + end + alias_method short, long + end +end diff --git a/app/models/rubygem.rb b/app/models/rubygem.rb index 0bfc99908d1..24469dabc8d 100644 --- a/app/models/rubygem.rb +++ b/app/models/rubygem.rb @@ -141,7 +141,12 @@ def downloads gem_download.try(:count) || 0 end + def links(version = versions.most_recent) + Links.new(self, version) + end + def payload(version = versions.most_recent, protocol = Gemcutter::PROTOCOL, host_with_port = Gemcutter::HOST) + versioned_links = links(version) deps = version.dependencies.to_a { 'name' => name, @@ -156,12 +161,12 @@ def payload(version = versions.most_recent, protocol = Gemcutter::PROTOCOL, host 'sha' => version.sha256_hex, 'project_uri' => "#{protocol}://#{host_with_port}/gems/#{name}", 'gem_uri' => "#{protocol}://#{host_with_port}/gems/#{version.full_name}.gem", - 'homepage_uri' => linkset.try(:home), - 'wiki_uri' => linkset.try(:wiki), - 'documentation_uri' => linkset.try(:docs).presence || version.documentation_path, - 'mailing_list_uri' => linkset.try(:mail), - 'source_code_uri' => linkset.try(:code), - 'bug_tracker_uri' => linkset.try(:bugs), + 'homepage_uri' => versioned_links.homepage_uri, + 'wiki_uri' => versioned_links.wiki_uri, + 'documentation_uri' => versioned_links.documentation_uri, + 'mailing_list_uri' => versioned_links.mailing_list_uri, + 'source_code_uri' => versioned_links.source_code_uri, + 'bug_tracker_uri' => versioned_links.bug_tracker_uri, 'dependencies' => { 'development' => deps.select { |r| r.rubygem && 'development' == r.scope }, 'runtime' => deps.select { |r| r.rubygem && 'runtime' == r.scope } diff --git a/app/models/version.rb b/app/models/version.rb index e8eed164c47..7e94ad0b0f0 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -350,10 +350,6 @@ def assign_required_rubygems_version! update_column(:required_rubygems_version, required_rubygems_version.to_s) end - def documentation_path - "http://www.rubydoc.info/gems/#{rubygem.name}/#{number}" - end - private def get_spec_attribute(attribute_name) diff --git a/app/views/rubygems/_aside.html.erb b/app/views/rubygems/_aside.html.erb index dc4ba21572e..6e19722d85c 100644 --- a/app/views/rubygems/_aside.html.erb +++ b/app/views/rubygems/_aside.html.erb @@ -61,17 +61,9 @@