229 lines
9.1 KiB
Ruby
229 lines
9.1 KiB
Ruby
class QualityAnalysisController < ApplicationController
|
||
before_filter :find_project_by_project_id#, :except => [:getattachtype]
|
||
before_filter :find_quality_analysis, :only => [:edit, :update_jenkins_job]
|
||
before_filter :authorize
|
||
before_filter :connect_jenkins, :only => [:create, :edit, :update_jenkins_job, :index]
|
||
layout "base_projects"
|
||
include ApplicationHelper
|
||
include QualityAnalysisHelper
|
||
require 'jenkins_api_client'
|
||
require 'nokogiri'
|
||
require 'json'
|
||
require 'open-uri'
|
||
|
||
def show
|
||
|
||
end
|
||
|
||
# params 说明:{identifier:版本库名}
|
||
def create
|
||
begin
|
||
user_name = User.find(params[:user_id]).try(:login)
|
||
identifier = params[:identifier]
|
||
rep_id = params[:rep_id]
|
||
|
||
# job_name and sonar_name 前者为job名字,后者为jenkins配置名
|
||
job_name = "#{user_name}-#{rep_id}"
|
||
sonar_name = "#{user_name}:#{rep_id}"
|
||
|
||
# Checks if the given job exists in Jenkins.
|
||
unless @client.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 = qa.nil? ? 1 : qa.sonar_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.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.job.build("#{job_name}")
|
||
logger.error("build result ==> #{code}")
|
||
|
||
# 判断调用sonar分析是否成功
|
||
# 等待启动时间处理, 最长时间为30分钟
|
||
for i in 0..60 do
|
||
sleep(60)
|
||
@current_build_status = @client.job.get_current_build_status("#{job_name}")
|
||
if (@current_build_status != "not_run" || @current_build_status != "running")
|
||
break
|
||
if i == 60
|
||
@build_console_result = false
|
||
break
|
||
end
|
||
end
|
||
end
|
||
|
||
@console_build = @client.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'text')
|
||
logger.info("@current_build_status is ==> #{@current_build_status}")
|
||
logger.info("@console_build is ==> #{@console_build}")
|
||
|
||
d = @client.job.delete("#{job_name}") if jenkins_job == '200' && code != '201'
|
||
logger.error("delete result ==> #{code}")
|
||
if qa.blank? && @current_build_status == "success"
|
||
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
|
||
end
|
||
rescue => e
|
||
puts e
|
||
end
|
||
respond_to do |format|
|
||
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)}
|
||
# format.js{redirect_to project_quality_analysis_path(:project_id => @project.id, :resource_id => sonar_name, :branch => branch)}
|
||
end
|
||
end
|
||
|
||
# get language type
|
||
def swith_language_type language
|
||
if language == "c#"
|
||
"cs"
|
||
elsif language == "python"
|
||
"py"
|
||
elsif language == "c"
|
||
"c++"
|
||
else
|
||
language
|
||
end
|
||
end
|
||
|
||
def edit
|
||
@g = Gitlab.client
|
||
gitlab_branches = @g.branches(@project.gpid)
|
||
@branch_names = gitlab_branches.map{|b| b.name}
|
||
@gitlab_default_branch = @g.project(@project.gpid).default_branch
|
||
end
|
||
|
||
# 更新Jenkins job,主要包括相关配置文件参数的更新,Trustie平台数据的更新
|
||
def update_jenkins_job
|
||
begin
|
||
rep_id = Repository.where(:project_id => @project.id).first.try(:id)
|
||
logger.error("#############################===>666")
|
||
sonar_name = @quality_analysis.sonar_name
|
||
job_name = "#{@quality_analysis.author_login}-#{rep_id}"
|
||
version = @quality_analysis.sonar_version
|
||
path = params[:path].blank? ? "./" : params[:path]
|
||
language = swith_language_type(params[:language])
|
||
branch = params[:branch]
|
||
identifier = @quality_analysis.rep_identifier
|
||
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"
|
||
|
||
# modify config.yml
|
||
@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
|
||
|
||
# update成功则返回 ‘200’
|
||
jenkins_job = @client.job.update("#{job_name}", @doc.to_xml)
|
||
get_current_build_status = @client.job.get_current_build_status("Hjqreturn-1280")
|
||
logger.error("Failed to update job: ==> #{jenkins_job}") unless jenkins_job == '200'
|
||
|
||
# 数据更新到Trustie数据库
|
||
if jenkins_job == '200'
|
||
logger.info("quality_ananlysis will be updated: ==> #{jenkins_job}")
|
||
@quality_analysis.path = path
|
||
@quality_analysis.language = language
|
||
@quality_analysis.branch = branch
|
||
@quality_analysis.save
|
||
end
|
||
rescue Exception => e
|
||
logger.error("Update jenkins job: #{e}")
|
||
end
|
||
respond_to do |format|
|
||
format.html{redirect_to project_quality_analysis_path(:project_id => @project.id)}
|
||
format.js
|
||
end
|
||
end
|
||
|
||
# resource_id: login + @repository.id
|
||
def index
|
||
begin
|
||
@branch = params[:branch]
|
||
@resource_id = params[:resource_id]
|
||
@sonar_address = Redmine::Configuration['sonar_address']
|
||
@jenkins_address = Redmine::Configuration['jenkins_address']
|
||
if params[:resource_id].nil?
|
||
@name_flag = true
|
||
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_analyses = QualityAnalysis.where(:project_id => @project.id).select{|qa| arr.include?(qa.sonar_name)}
|
||
|
||
else
|
||
if params[:current_build_status] == "failure"
|
||
job_name = params[:job_name]
|
||
@console_build = @client.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'text')["output"]
|
||
end
|
||
complexity_date = open(@sonar_address + "/api/resources/index?resource=#{@resource_id}&depth=0&metrics=sqale_rating,function_complexity,duplicated_lines_density,comment_lines_density,sqale_index,lines,file_line,files,functions,classes,directories").read
|
||
@complexity =JSON.parse(complexity_date).first
|
||
issue_date = open(@sonar_address + "/api/resources/index?resource=#{@resource_id}&depth=0&metrics=blocker_violations,critical_violations,major_violations,minor_violations,info_violations,violations").read
|
||
@sonar_issues = JSON.parse(issue_date).first
|
||
end
|
||
rescue => e
|
||
puts e
|
||
end
|
||
|
||
end
|
||
|
||
# Find project of id params[:project_id]
|
||
def find_project_by_project_id
|
||
@project = Project.find(params[:project_id])
|
||
rescue ActiveRecord::RecordNotFound
|
||
render_404
|
||
end
|
||
|
||
def find_quality_analysis
|
||
begin
|
||
@quality_analysis = QualityAnalysis.find(params[:id])
|
||
rescue
|
||
render_404
|
||
end
|
||
end
|
||
|
||
# Authorize the user for the requested action
|
||
def authorize(ctrl = params[:controller], action = params[:action], global = false)
|
||
unless @project.archived? && @project.gpid.nil?
|
||
true
|
||
else
|
||
render_403 :message => :notice_not_authorized_archived_project
|
||
end
|
||
end
|
||
|
||
def connect_jenkins
|
||
@gitlab_address = Redmine::Configuration['gitlab_address']
|
||
@jenkins_address = Redmine::Configuration['jenkins_address']
|
||
|
||
# connect jenkins
|
||
@client = JenkinsApi::Client.new(:server_url => @jenkins_address, :username => "temp", :password => '123123')
|
||
rescue => e
|
||
logger.error("failed to connect Jenkins ==> #{e}")
|
||
end
|
||
|
||
end
|