src/api/app/models/bs_request_action/differ/query_builder.rb
class BsRequestAction
module Differ
class QueryBuilder
include ActiveModel::Model
attr_accessor :target_project, :target_package, :action, :source_package
def build
# the target is by default the _link target
# maintenance_release creates new packages instance, but are changing the source only according to the link
provided_in_other_action = check_for_local_linked_packages(source_package)
# fallback name as last resort
self.target_package ||= action.source_package
# maintenance incidents shall show the final result after release
self.target_project = action.target_releaseproject if action.target_releaseproject
# maintenance release targets will have a base link
tprj = Project.get_by_name(target_project)
if tprj && tprj.is_maintenance_release?
tpkg = tprj.find_package(target_package.gsub(/\.[^.]*$/, ''))
if tpkg
if tpkg.project.is_maintenance_release? && tpkg.is_local_link?
# use package container from former incident update
self.target_package = tpkg.linkinfo['package']
else
self.target_project = tprj.name
self.target_package = tpkg.name
end
end
end
tpkg = Package.get_by_project_and_name(target_project, target_package) if Package.exists_by_project_and_name(target_project, target_package)
query = {}
if !provided_in_other_action && !action.updatelink
# do show the same diff multiple times, so just diff unexpanded so we see possible link changes instead
# also get sure that the request would not modify the link in the target
query[:expand] = 1
end
if tpkg
query[:oproject] = target_project
query[:opackage] = target_package
query[:rev] = action.source_rev if action.source_rev
elsif action.source_rev # Use source rev for diffing (if available)
# No target package means diffing the source package against itself.
query[:orev] = 0
query[:rev] = action.source_rev
else # Otherwise generate diff for latest source package revision
# FIXME: move to Package model
spkg_rev = Directory.hashed(project: action.source_project, package: source_package)['rev']
query[:orev] = 0
query[:rev] = spkg_rev
end
query
end
private
def check_for_local_linked_packages(spkg)
# the target is by default the _link target
# maintenance_release creates new packages instance, but are changing the source only according to the link
return if action.target_package && action.action_type == :maintenance_incident
begin
data = Xmlhash.parse(Backend::Api::Sources::Package.files(action.source_project, spkg))
rescue Backend::Error
return
end
linkinfo = data['linkinfo']
return unless linkinfo
self.target_project ||= linkinfo['project']
self.target_package ||= linkinfo['package']
return unless linkinfo['project'] == action.source_project
# a local link, check if the real source change gets also transported in a seperate action
action.bs_request.bs_request_actions.any? { |a| check_action_target(a, linkinfo['package']) } if action.bs_request
end
# check if the action is the same target
def check_action_target(other, linked_package_name)
action.source_project == other.source_project &&
linked_package_name == other.source_package &&
action.target_project == other.target_project
end
end
end
end