@ -16,8 +16,8 @@ class QualityAnalysisController < ApplicationController
end
# params 说明:{identifier: 版本库名}
# type: 1 新的分析 2 重新分析
def create
logger . info ( " 11111111111111111111111111111 " )
begin
user_name = User . find ( params [ :user_id ] ) . try ( :login )
identifier = params [ :identifier ]
@ -30,98 +30,98 @@ class QualityAnalysisController < ApplicationController
# 考虑到历史数据: 有些用户创建类job但是build失败,即sonar没有结果, 这个时候需要把job删除,并且删掉quality_analyses表数据
# 如果不要这句则需要迁移数据
@sonar_address = Redmine :: Configuration [ 'sonar_address' ]
projects_date = open ( @sonar_address + " /api/projects/index " ) . read
arr = JSON . parse ( projects_date ) . map { | m | m [ " nm " ] } # eg: ["Hjqreturn:cc_rep", "Hjqreturn:putong", "Hjqreturn:sonar_rep2", "shitou:sonar_rep"]
quality_an = QualityAnalysis . where ( :sonar_name = > sonar_name ) . first
if @client_jenkins . job . exists? ( job_name ) && QualityAnalysis . where ( :sonar_name = > sonar_name ) . select { | qa | arr . include? ( qa . sonar_name ) } . blank?
aa = @client_jenkins . job . delete ( " #{ job_name } " )
quality_an . delete unless quality_an . blank?
end
# projects_date = open(@sonar_address + "/api/projects/index").read
# arr = JSON.parse(projects_date).map {|m| m["nm"]} # eg: ["Hjqreturn:cc_rep", "Hjqreturn:putong", "Hjqreturn:sonar_rep2", "shitou:sonar_rep"]
quality_an = QualityAnalysis . where ( :sonar_name = > sonar_name )
# if @client_jenkins.job.exists?(job_name) && QualityAnalysis.where(:sonar_name => sonar_name).select{|qa| arr.include?(qa.sonar_name)}.blank?
# aa = @client_jenkins.job.delete("#{job_name}")
# quality_an.delete unless quality_an.blank?
# end
# type 1的时候之所以判断job是否存在, 为了防止特殊情况, 正常情况是不会出现的
# 重新分析的时候需要删除以前的分析结果
@client_jenkins . job . delete ( " #{ job_name } " ) if @client_jenkins . job . exists? ( job_name )
quality_an . delete_all unless quality_an . blank?
# Checks if the given job exists in Jenkins.
unless @client_jenkins . job . exists? ( job_name )
@g = Gitlab . client
branch = params [ :branch ]
language = swith_language_type ( params [ :language ] )
path = params [ :path ] . blank? ? " ./ " : params [ :path ]
# qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first
version = quality_an . nil? ? 1 : quality_an . sonar_version + 1
properties = " sonar.projectKey= #{ sonar_name }
@g = Gitlab . client
branch = params [ :branch ]
language = swith_language_type ( params [ :language ] )
path = params [ :path ] . blank? ? " ./ " : params [ :path ]
# qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first
version = 1
properties = " sonar.projectKey= #{ sonar_name }
sonar . projectName = #{sonar_name}
sonar . projectVersion = #{version}
sonar . sources = #{path}
sonar . language = #{language.downcase}
sonar . sourceEncoding = utf - 8 "
git_url = @gitlab_address . to_s + " / " + @project . owner . to_s + " / " + identifier + " . " + " git "
# 替换配置文件
@doc = Nokogiri :: XML ( File . open ( File . join ( Rails . root , 'tmp' , 'config.xml' ) ) )
@doc . at_xpath ( " //hudson.plugins.git.UserRemoteConfig/url " ) . content = git_url
@doc . at_xpath ( " //hudson.plugins.git.BranchSpec/name " ) . content = " */ #{ branch } "
@doc . at_xpath ( " //hudson.plugins.sonar.SonarRunnerBuilder/properties " ) . content = properties # sonar-properties
# jenkins job创建
jenkins_job = @client_jenkins . job . create ( " #{ job_name } " , @doc . to_xml )
logger . info ( " Jenkins status of create ==> #{ jenkins_job } " )
# 将地址作为hook值添加到gitlab
@g . add_project_hook ( @project . gpid , @jenkins_address + " /project/ #{ job_name } " )
# job创建完成后自动运行job,如果运行成功则返回‘ 200’
code = @client_jenkins . job . build ( " #{ job_name } " )
logger . error ( " build result ==> #{ code } " )
# 判断调用sonar分析是否成功
# 等待启动时间处理, 最长时间为30分钟
for i in 0 .. 360 do
sleep ( 5 )
@current_build_status = @client_jenkins . job . get_current_build_status ( " #{ job_name } " )
if ( @current_build_status == " success " || @current_build_status == " failure " )
git_url = @gitlab_address . to_s + " / " + @project . owner . to_s + " / " + identifier + " . " + " git "
# 替换配置文件
@doc = Nokogiri :: XML ( File . open ( File . join ( Rails . root , 'tmp' , 'config.xml' ) ) )
@doc . at_xpath ( " //hudson.plugins.git.UserRemoteConfig/url " ) . content = git_url
@doc . at_xpath ( " //hudson.plugins.git.BranchSpec/name " ) . content = " */ #{ branch } "
@doc . at_xpath ( " //hudson.plugins.sonar.SonarRunnerBuilder/properties " ) . content = properties # sonar-properties
# jenkins job创建
jenkins_job = @client_jenkins . job . create ( " #{ job_name } " , @doc . to_xml )
# 将地址作为hook值添加到gitlab
# @g.add_project_hook(@project.gpid, @jenkins_address + "/project/#{job_name}")
# job创建完成后自动运行job,如果运行成功则返回‘ 200’
code = @client_jenkins . job . build ( " #{ job_name } " )
# 判断调用sonar分析是否成功
# 等待启动时间处理, 最长时间为30分钟
for i in 0 .. 360 do
sleep ( 5 )
@current_build_status = @client_jenkins . job . get_current_build_status ( " #{ job_name } " )
if ( @current_build_status == " success " || @current_build_status == " failure " )
break
if i == 360
@build_console_result = false
break
if i == 360
@build_console_result = false
break
end
end
end
end
# sonar 缓冲, sonar生成数据
sleep ( 10 )
# sonar 缓冲, sonar生成数据
sleep ( 10 )
# 获取sonar output结果
console_build = @client_jenkins . job . get_console_output ( " #{ job_name } " , build_num = 0 , start = 0 , mode = 'text' ) [ " output " ]
logger . info ( " @current_build_status is ==> #{ @current_build_status } " )
# 获取sonar output结果
console_build = @client_jenkins . job . get_console_output ( " #{ job_name } " , build_num = 0 , start = 0 , mode = 'text' ) [ " output " ]
logger . info ( " @current_build_status is ==> #{ @current_build_status } " )
# 两种情况需要删除job:
# 1/创建成功但是build失败则删除job
# 2/creat和build成功, 调用sonar启动失败则删除job
# 错误信息存储需存到Trustie数据库, 否则一旦job删除则无法获取这些信息
if jenkins_job == '200' && code != '201'
# 两种情况需要删除job:
# 1/创建成功但是build失败则删除job
# 2/creat和build成功, 调用sonar启动失败则删除job
# 错误信息存储需存到Trustie数据库, 否则一旦job删除则无法获取这些信息
if jenkins_job == '200' && code != '201'
@client_jenkins . job . delete ( " #{ job_name } " )
else
if @current_build_status == " failure "
reg_console = / Exception:.*? \ r / . match ( console_build )
output = reg_console [ 0 ] . gsub ( " \r " , " " ) unless reg_console . nil?
se = SonarError . where ( :jenkins_job_name = > job_name ) . first
se . nil? ? SonarError . create ( :project_id = > @project . id , :jenkins_job_name = > job_name , :output = > output ) : se . update_column ( :output , output )
@client_jenkins . job . delete ( " #{ job_name } " )
else
if @current_build_status == " failure "
reg_console = / Exception:.*? \ r / . match ( console_build )
output = reg_console [ 0 ] . gsub ( " \r " , " " ) unless reg_console . nil?
se = SonarError . where ( :jenkins_job_name = > job_name ) . first
se . nil? ? SonarError . create ( :project_id = > @project . id , :jenkins_job_name = > job_name , :output = > output ) : se . update_column ( :output , output )
@client_jenkins . job . delete ( " #{ job_name } " )
elsif @current_build_status == " success "
if quality_an . blank?
QualityAnalysis . create ( :project_id = > @project . id , :author_login = > user_name , :rep_identifier = > identifier ,
:sonar_version = > version , :path = > path , :branch = > branch , :language = > language , :sonar_name = > " #{ user_name } : #{ rep_id } " )
else
qa . update_attribute ( :sonar_version , version )
end
elsif @current_build_status == " success "
if quality_an . blank?
QualityAnalysis . create ( :project_id = > @project . id , :author_login = > user_name , :rep_identifier = > identifier ,
:sonar_version = > version , :path = > path , :branch = > branch , :language = > language , :sonar_name = > " #{ user_name } : #{ rep_id } " )
end
end
end
respond_to do | format |
if @current_build_status == " success "
format . html { redirect_to project_quality_analysis_path ( :project_id = > @project . id , :resource_id = > sonar_name , :branch = > branch , :current_build_status = > @current_build_status , :job_name = > job_name ) }
elsif @current_build_status == " failure "
format . html { redirect_to error_list_project_quality_analysi_path ( :project_id = > @project . id , :job_name = > job_name ) }
end
respond_to do | format |
if @current_build_status == " success "
format . html { redirect_to project_quality_analysis_path ( :project_id = > @project . id , :resource_id = > sonar_name , :branch = > branch , :current_build_status = > @current_build_status , :job_name = > job_name ) }
elsif @current_build_status == " failure "
format . html { redirect_to error_list_project_quality_analysi_path ( :project_id = > @project . id , :job_name = > job_name ) }
end
end
rescue = > e
@message = e . message
logger . error ( " # # # # # # # # # # # # # # # # # # # # # # ====> #{ e . message } " )
@ -241,6 +241,21 @@ class QualityAnalysisController < ApplicationController
complexity_date = open ( @sonar_address + " /api/resources/index?resource= #{ @resource_id } &depth=0&metrics= #{ filter } " ) . read
@complexity = JSON . parse ( complexity_date ) . first
# 获取排名结果
@g = Gitlab . client
@author_infos = @g . rep_user_stats ( @project . gpid , :rev = > @branch )
@user_quality_infos = [ ]
@author_infos . each do | author_info |
email = author_info . email
changes = author_info . changes . to_i
unresolved_issues = open ( @sonar_address + " /api/issues/search?projectKeys= #{ @resource_id } &authors= #{ email } &resolved=false " ) . read
unresolved_issue_count = JSON . parse ( unresolved_issues ) [ " total " ] . to_i
all_issues = open ( @sonar_address + " /api/issues/search?projectKeys= #{ @resource_id } &authors= #{ email } " ) . read
all_issue_count = JSON . parse ( all_issues ) [ " total " ] . to_i
ratio = ( changes == 0 ? 0 : format ( " %0.4f " , unresolved_issue_count . to_f / changes . to_f ) )
@user_quality_infos << { :email = > email , :changes = > changes , :unresolved_issue_count = > unresolved_issue_count , :ratio = > ratio , :all_issue_count = > all_issue_count }
end
# 按名称转换成hash键值对
@ha = { }
@complexity [ " msr " ] . each do | com |
@ -287,10 +302,8 @@ class QualityAnalysisController < ApplicationController
@jenkins_address = Redmine :: Configuration [ 'jenkins_address' ]
jenkins_username = Redmine :: Configuration [ 'jenkins_username' ]
jenkins_password = Redmine :: Configuration [ 'jenkins_password' ]
logger . info ( " 22222222222222222222222222222222 " )
# connect jenkins
@client_jenkins = JenkinsApi :: Client . new ( :server_url = > @jenkins_address , :username = > jenkins_username , :password = > jenkins_password )
logger . info ( " 333333333333333333333333333333 " )
rescue = > e
logger . error ( " failed to connect Jenkins ==> #{ e } " )
end