Skip to content

Commit

Permalink
Refactor Project#status dependencies to Projects::StatusController
Browse files Browse the repository at this point in the history
  - Move private methods used by `status` action
  - Move specs from `ProjectController#status` to `Projects::StatusController#show`
  - Adapt specs, controllers and necessary views
  • Loading branch information
vpereira committed Oct 10, 2019
1 parent 1cdd016 commit 3f20d7e
Show file tree
Hide file tree
Showing 8 changed files with 377 additions and 358 deletions.
249 changes: 3 additions & 246 deletions src/api/app/controllers/webui/project_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Webui::ProjectController < Webui::WebuiController
:show, :buildresult,
:destroy, :remove_path_from_target,
:requests, :save, :monitor, :toggle_watch,
:edit_comment, :status,
:edit_comment,
:unlock, :save_person, :save_group, :remove_role,
:move_path, :clear_failed_comment, :pulse]

Expand All @@ -28,7 +28,7 @@ class Webui::ProjectController < Webui::WebuiController

after_action :verify_authorized, except: [:index, :autocomplete_projects, :autocomplete_incidents, :autocomplete_packages,
:autocomplete_repositories, :users, :subprojects, :new, :show,
:buildresult, :requests, :monitor, :status, :new_release_request,
:buildresult, :requests, :monitor, :new_release_request,
:remove_target_request, :toggle_watch, :edit_comment, :edit_comment_form]

def index
Expand Down Expand Up @@ -335,7 +335,7 @@ def clear_failed_comment
flash.now[:success] = 'Cleared comments for packages'

respond_to do |format|
format.html { redirect_to({ action: :status, project: @project }, success: 'Cleared comments for packages.') }
format.html { redirect_to(project_status_path(@project), success: 'Cleared comments for packages.') }
format.js { render 'clear_failed_comment' }
end
end
Expand All @@ -360,40 +360,6 @@ def edit_comment
@comment = params[:text]
end

def status
all_packages = 'All Packages'
no_project = 'No Project'
@no_project = '_none_'
@all_projects = '_all_'
@current_develproject = params[:filter_devel] || all_packages
@filter = @current_develproject
if @filter == all_packages
@filter = @all_projects
elsif @filter == no_project
@filter = @no_project
end
@ignore_pending = params[:ignore_pending] || false
@limit_to_fails = params[:limit_to_fails] != 'false'
@limit_to_old = !(params[:limit_to_old].nil? || params[:limit_to_old] == 'false')
@include_versions = !(!params[:include_versions].nil? && params[:include_versions] == 'false')
@filter_for_user = params[:filter_for_user]

@develprojects = {}
ps = calc_status(params[:project])

@packages = ps[:packages]
@develprojects = ps[:projects].sort_by(&:downcase)
@develprojects.insert(0, all_packages)
@develprojects.insert(1, no_project)

respond_to do |format|
format.json do
render json: ActiveSupport::JSON.encode(@packages)
end
format.html
end
end

def unlock
authorize @project, :unlock?
if @project.unlock(params[:comment])
Expand Down Expand Up @@ -635,215 +601,6 @@ def filter_matches?(input, filter_string)
result
end

def calc_status(project_name)
@api_obj = ::Project.where(name: project_name).includes(:packages).first
@status = {}

# needed to map requests to package id
@name2id = {}

@prj_status = Rails.cache.fetch("prj_status-#{@api_obj}", expires_in: 5.minutes) do
ProjectStatus::Calculator.new(@api_obj).calc_status(pure_project: true)
end

status_filter_packages
status_gather_attributes
status_gather_requests

@packages = []
@status.each_value do |p|
status_check_package(p)
end

{ packages: @packages, projects: @develprojects.keys }
end

def status_check_package(p)
currentpack = {}
pname = p.name

currentpack['requests_from'] = []
key = @api_obj.name + '/' + pname
if @submits.key?(key)
return if @ignore_pending
currentpack['requests_from'].concat(@submits[key])
end

currentpack['name'] = pname
currentpack['failedcomment'] = p.failed_comment if p.failed_comment.present?

newest = 0

p.fails.each do |repo, arch, time, md5|
next if newest > time
next if md5 != p.verifymd5
currentpack['failedarch'] = arch
currentpack['failedrepo'] = repo
newest = time
currentpack['firstfail'] = newest
end
return if !currentpack['firstfail'] && @limit_to_fails

currentpack['problems'] = []
currentpack['requests_to'] = []

currentpack['md5'] = p.verifymd5

check_devel_package_status(currentpack, p)
currentpack.merge!(project_status_set_version(p))

if p.links_to
if currentpack['md5'] != p.links_to.verifymd5
currentpack['problems'] << 'diff_against_link'
currentpack['lproject'] = p.links_to.project
currentpack['lpackage'] = p.links_to.name
end
end

return unless currentpack['firstfail'] || currentpack['failedcomment'] || currentpack['upstream_version'] ||
!currentpack['problems'].empty? || !currentpack['requests_from'].empty? || !currentpack['requests_to'].empty?
if @limit_to_old
return unless currentpack['upstream_version']
end
@packages << currentpack
end

def check_devel_package_status(currentpack, p)
dp = p.develpack
return unless dp
dproject = dp.project
currentpack['develproject'] = dproject
currentpack['develpackage'] = dp.name
key = "#{dproject}/#{dp.name}"
currentpack['requests_to'].concat(@submits[key]) if @submits.key?(key)

currentpack['develmd5'] = dp.verifymd5
currentpack['develmtime'] = dp.maxmtime

currentpack['problems'] << "error-#{dp.error}" if dp.error

return unless currentpack['md5'] && currentpack['develmd5'] && currentpack['md5'] != currentpack['develmd5']

if p.declined_request
@declined_requests[p.declined_request].bs_request_actions.each do |action|
next unless action.source_project == dp.project && action.source_package == dp.name

sourcerev = Rails.cache.fetch("rev-#{dp.project}-#{dp.name}-#{currentpack['md5']}") do
Directory.hashed(project: dp.project, package: dp.name)['rev']
end
if sourcerev == action.source_rev
currentpack['currently_declined'] = p.declined_request
currentpack['problems'] << 'currently_declined'
end
end
end

return unless currentpack['currently_declined'].nil?
return currentpack['problems'] << 'different_changes' if p.changesmd5 != dp.changesmd5
currentpack['problems'] << 'different_sources'
end

def status_filter_packages
filter_for_user = User.find_by_login!(@filter_for_user) if @filter_for_user.present?
current_develproject = @filter || @all_projects
@develprojects = {}
packages_to_filter_for = nil
if filter_for_user
packages_to_filter_for = filter_for_user.user_relevant_packages_for_status
end
@prj_status.each_value do |value|
if value.develpack
dproject = value.develpack.project
@develprojects[dproject] = 1
if (current_develproject != dproject || current_develproject == @no_project) && current_develproject != @all_projects
next
end
elsif @current_develproject == @no_project
next
end
if filter_for_user
if value.develpack
next unless packages_to_filter_for.include?(value.develpack.package_id)
else
next unless packages_to_filter_for.include?(value.package_id)
end
end
@status[value.package_id] = value
@name2id[value.name] = value.package_id
end
end

def status_gather_requests
# we do not filter requests for project because we need devel projects too later on and as long as the
# number of open requests is limited this is the easiest solution
raw_requests = BsRequest.order(:number).where(state: [:new, :review, :declined]).joins(:bs_request_actions).
where(bs_request_actions: { type: 'submit' }).pluck('bs_requests.number', 'bs_requests.state',
'bs_request_actions.target_project',
'bs_request_actions.target_package')

@declined_requests = {}
@submits = {}
raw_requests.each do |number, state, tproject, tpackage|
if state == 'declined'
next if tproject != @api_obj.name || !@name2id.key?(tpackage)
@status[@name2id[tpackage]].declined_request = number
@declined_requests[number] = nil
else
key = "#{tproject}/#{tpackage}"
@submits[key] ||= []
@submits[key] << number
end
end
BsRequest.where(number: @declined_requests.keys).each do |r|
@declined_requests[r.number] = r
end
end

def status_gather_attributes
project_status_attributes(@status.keys, 'OBS', 'ProjectStatusPackageFailComment') do |package, value|
@status[package].failed_comment = value
end

return unless @include_versions || @limit_to_old

project_status_attributes(@status.keys, 'openSUSE', 'UpstreamVersion') do |package, value|
@status[package].upstream_version = value
end
project_status_attributes(@status.keys, 'openSUSE', 'UpstreamTarballURL') do |package, value|
@status[package].upstream_url = value
end
end

def project_status_attributes(packages, namespace, name)
ret = {}
at = AttribType.find_by_namespace_and_name(namespace, name)
return unless at
attribs = at.attribs.where(package_id: packages)
AttribValue.where(attrib_id: attribs).joins(:attrib).pluck('attribs.package_id, value').each do |id, value|
yield id, value
end
ret
end

def project_status_set_version(p)
ret = {}
ret['version'] = p.version
if p.upstream_version
begin
gup = Gem::Version.new(p.version)
guv = Gem::Version.new(p.upstream_version)
rescue ArgumentError
# if one of the versions can't be parsed we simply can't say
end

if gup && guv && gup < guv
ret['upstream_version'] = p.upstream_version
ret['upstream_url'] = p.upstream_url
end
end
ret
end

def set_project_by_name
@project = Project.get_by_name(params['project'])
rescue Project::UnknownObjectError
Expand Down
Loading

0 comments on commit 3f20d7e

Please sign in to comment.