Merge branch 'rep_quality' into develop

daiao_dev
huang 9 years ago
commit 61e2e427fd

@ -57,7 +57,7 @@ group :development do
gem 'grape-swagger' gem 'grape-swagger'
gem 'better_errors', '~> 1.1.0' gem 'better_errors', '~> 1.1.0'
# gem "query_reviewer" # gem "query_reviewer"
# gem 'rack-mini-profiler', '~> 0.9.3' gem 'rack-mini-profiler', '~> 0.9.3'
if RUBY_PLATFORM =~ /w32/ if RUBY_PLATFORM =~ /w32/
gem 'win32console' gem 'win32console'
end end

@ -26,14 +26,25 @@ class QualityAnalysisController < ApplicationController
job_name = "#{user_name}-#{rep_id}" job_name = "#{user_name}-#{rep_id}"
sonar_name = "#{user_name}:#{rep_id}" sonar_name = "#{user_name}:#{rep_id}"
# 考虑到历史数据有些用户创建类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.job.exists?(job_name) && QualityAnalysis.where(:sonar_name => sonar_name).select{|qa| arr.include?(qa.sonar_name)}.blank?
logger.info("88888888888888888888")
aa = @client.job.delete("#{job_name}")
quality_an.delete unless quality_an.blank?
end
# Checks if the given job exists in Jenkins. # Checks if the given job exists in Jenkins.
unless @client.job.exists?(job_name) unless @client.job.exists?(job_name)
@g = Gitlab.client @g = Gitlab.client
branch = params[:branch] branch = params[:branch]
language = swith_language_type(params[:language]) language = swith_language_type(params[:language])
path = params[:path].blank? ? "./" : params[:path] path = params[:path].blank? ? "./" : params[:path]
qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first # qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first
version = qa.nil? ? 1 : qa.sonar_version + 1 version = quality_an.nil? ? 1 : quality_an.sonar_version + 1
properties = "sonar.projectKey=#{sonar_name} properties = "sonar.projectKey=#{sonar_name}
sonar.projectName=#{sonar_name} sonar.projectName=#{sonar_name}
sonar.projectVersion=#{version} sonar.projectVersion=#{version}
@ -61,7 +72,7 @@ class QualityAnalysisController < ApplicationController
# 判断调用sonar分析是否成功 # 判断调用sonar分析是否成功
# 等待启动时间处理, 最长时间为30分钟 # 等待启动时间处理, 最长时间为30分钟
for i in 0..60 do for i in 0..60 do
sleep(60) sleep(30)
@current_build_status = @client.job.get_current_build_status("#{job_name}") @current_build_status = @client.job.get_current_build_status("#{job_name}")
if (@current_build_status != "not_run" || @current_build_status != "running") if (@current_build_status != "not_run" || @current_build_status != "running")
break break
@ -72,25 +83,49 @@ class QualityAnalysisController < ApplicationController
end end
end end
@console_build = @client.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'text') # 获取sonar output结果
console_build = @client.job.get_console_output("#{job_name}", build_num = 0, start = 0, mode = 'text')["output"]
logger.info("@current_build_status is ==> #{@current_build_status}") 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' # 两种情况需要删除job
logger.error("delete result ==> #{code}") # 1/创建成功但是build失败则删除job
if qa.blank? && @current_build_status == "success" # 2/creat和build成功调用sonar启动失败则删除job
# 错误信息存储需存到Trustie数据库否则一旦job删除则无法获取这些信息
if jenkins_job == '200' && code != '201'
@client.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.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, 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}") :sonar_version => version, :path => path, :branch => branch, :language => language, :sonar_name => "#{user_name}:#{rep_id}")
else else
qa.update_attribute(:sonar_version, version) qa.update_attribute(:sonar_version, version)
end end
end end
end
end
rescue => e rescue => e
puts e puts e
end end
respond_to do |format| 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)} 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)} 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
end
def error_list
@error_list = SonarError.where(:jenkins_job_name => params[:job_name]).first
respond_to do |format|
format.html
end end
end end
@ -145,7 +180,7 @@ class QualityAnalysisController < ApplicationController
get_current_build_status = @client.job.get_current_build_status("Hjqreturn-1280") get_current_build_status = @client.job.get_current_build_status("Hjqreturn-1280")
logger.error("Failed to update job: ==> #{jenkins_job}") unless jenkins_job == '200' logger.error("Failed to update job: ==> #{jenkins_job}") unless jenkins_job == '200'
# 数据更新到Trustie数据 # 数据更新到Trustie数据
if jenkins_job == '200' if jenkins_job == '200'
logger.info("quality_ananlysis will be updated: ==> #{jenkins_job}") logger.info("quality_ananlysis will be updated: ==> #{jenkins_job}")
@quality_analysis.path = path @quality_analysis.path = path
@ -168,18 +203,12 @@ class QualityAnalysisController < ApplicationController
@branch = params[:branch] @branch = params[:branch]
@resource_id = params[:resource_id] @resource_id = params[:resource_id]
@sonar_address = Redmine::Configuration['sonar_address'] @sonar_address = Redmine::Configuration['sonar_address']
@jenkins_address = Redmine::Configuration['jenkins_address']
if params[:resource_id].nil? if params[:resource_id].nil?
@name_flag = true @name_flag = true
projects_date = open(@sonar_address + "/api/projects/index").read 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"] 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)} @quality_analyses = QualityAnalysis.where(:project_id => @project.id).select{|qa| arr.include?(qa.sonar_name)}
else 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_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 @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 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
@ -188,7 +217,6 @@ class QualityAnalysisController < ApplicationController
rescue => e rescue => e
puts e puts e
end end
end end
# Find project of id params[:project_id] # Find project of id params[:project_id]

@ -38,7 +38,9 @@ class RepositoriesController < ApplicationController
before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue]
before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :commit_diff, :project_archive, :quality_analysis] before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :commit_diff, :project_archive, :quality_analysis]
# 链接gitlab # 链接gitlab
before_filter :connect_gitlab, :only => [:quality_analysis] before_filter :connect_gitlab, :only => [:quality_analysis, :show]
# 版本库新增权限
before_filter :show_rep, :only => [:show]
accept_rss_auth :revisions accept_rss_auth :revisions
# hidden repositories filter // 隐藏代码过滤器 # hidden repositories filter // 隐藏代码过滤器
before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ] before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ]
@ -361,44 +363,42 @@ update
def show def show
## TODO: the below will move to filter, done. ## TODO: the below will move to filter, done.
if !User.current.member_of?(@project) && @project.hidden_repo
render_403 # 获取版本库目录结构
return
end
@entries = @repository.entries(@path, @rev) @entries = @repository.entries(@path, @rev)
@changeset = @repository.find_changeset_by_name(@rev)
if request.xhr? if request.xhr?
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true) @entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
else else
g = Gitlab.client @changesets = @g.commits(@project.gpid, :ref_name => @rev)
@changesets = g.commits(@project.gpid, :ref_name => @rev) # 最近一次提交
g_project = g.project(@project.gpid) @changesets_latest_coimmit = @changesets[0]
g_project = @g.project(@project.gpid)
# 总的提交数 # 总的提交数
@changesets_all_count = @project.gpid.nil? ? 0 : commit_count(@project, @rev) @changesets_all_count = @g.user_static(@project.gpid, :rev => @rev).count
# 获取默认分支
@g_default_branch = g_project.default_branch.nil? ? "master" : g_project.default_branch @g_default_branch = g_project.default_branch.nil? ? "master" : g_project.default_branch
# 访问该页面的是会后则刷新
if @project.project_score.nil? # 访问版本庫后更新project_score表数据changeset_num为提交总数
project_score = @project.project_score
if project_score.nil?
ProjectScore.create(:project_id => @project.id, :score => false) ProjectScore.create(:project_id => @project.id, :score => false)
else
project_score.update_column(:changeset_num, @changesets_all_count)
end end
# 刷新改页面的时候,更新统计数
if @changesets_all_count != @project.project_score.changeset_num && @changesets_all_count != 0 # unless @changesets_latest_coimmit.blank?
update_commits_count(@project, @changesets_all_count) # update_commits_date(@project, @changesets_latest_coimmit)
end # end
# 最近一次提交 @creator = @project.owner.to_s
@changesets_latest_coimmit = @changesets[0]
unless @changesets[0].blank?
update_commits_date(@project, @changesets_latest_coimmit)
end
@creator = User.where("id =?", @project.user_id).first.try(:login)
# @properties = @repository.properties(@path, @rev)
# @repositories = @project.repositories
# project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT
# ip = RepositoriesHelper::REPO_IP_ADDRESS
gitlab_address = Redmine::Configuration['gitlab_address'] gitlab_address = Redmine::Configuration['gitlab_address']
# REDO:需优化,仅测试用 # REDO:需优化,仅测试用
@zip_path = Gitlab.endpoint.to_s + "/projects/" + @project.gpid.to_s + "/repository/archive?&private_token=" + Gitlab.private_token @zip_path = Gitlab.endpoint.to_s + "/projects/" + @project.gpid.to_s + "/repository/archive?&private_token=" + Gitlab.private_token
# 获取版本库路径主要分为两种一种随Gitlab类型另一种为Git类型Git类型为无用数据最终需要删掉这种类型。
if @repository.type.to_s == "Repository::Gitlab" if @repository.type.to_s == "Repository::Gitlab"
@repos_url = gitlab_address.to_s+"/"+@project.owner.to_s+"/"+@repository.identifier+"."+"git" @repos_url = gitlab_address.to_s+"/" + @creator + "/" + @repository.identifier+"."+"git"
else else
@repos_url = "http://"+@repository.login.to_s+"_"+@repository.identifier.to_s+"@"+ip.to_s + @repository.url.slice(project_path_cut, @repository.url.length).to_s @repos_url = "http://"+@repository.login.to_s+"_"+@repository.identifier.to_s+"@"+ip.to_s + @repository.url.slice(project_path_cut, @repository.url.length).to_s
end end
@ -653,10 +653,21 @@ update
# 链接gitlab # 链接gitlab
def connect_gitlab def connect_gitlab
begin
@g = Gitlab.client @g = Gitlab.client
unless @project.gpid.nil? unless @project.gpid.nil?
@g_project = @g.project(@project.gpid) @g_project = @g.project(@project.gpid)
end end
rescue => e
logger.error("failed to connect gitlab ==> #{e}")
end
end
def show_rep
if !User.current.member_of?(@project) && @project.hidden_repo
render_403
return
end
end end
def find_repository def find_repository

@ -0,0 +1,3 @@
class SonarError < ActiveRecord::Base
attr_accessible :jenkins_job_name, :output, :project_id
end

@ -43,7 +43,15 @@
<div class="analysis-tag-wrap f16"> <span class="analysis-tag fl mr15"></span> <span class="fb fl mr10">质量等级</span><span class="mr10 fontGrey2"><span class="c_red f18" style="margin-top:-5px; display:inline-block;"><%=@complexity["msr"][9].nil? ? 0 : score_sqale_rating(@complexity["msr"][9]["val"].to_i) %></span>/5分</span> <div class="analysis-tag-wrap f16"> <span class="analysis-tag fl mr15"></span> <span class="fb fl mr10">质量等级</span><span class="mr10 fontGrey2"><span class="c_red f18" style="margin-top:-5px; display:inline-block;"><%=@complexity["msr"][9].nil? ? 0 : score_sqale_rating(@complexity["msr"][9]["val"].to_i) %></span>/5分</span>
<span class="fontGrey2">可定性评价为:<span class="c_red">质量<%=@complexity["msr"][9].nil? ? "很好" : sqale_rating_status(@complexity["msr"][9]["val"])[0] %></span></span></div> <span class="fontGrey2">可定性评价为:<span class="c_red">质量<%=@complexity["msr"][9].nil? ? "很好" : sqale_rating_status(@complexity["msr"][9]["val"])[0] %></span></span></div>
<div class="analysis-block mt10 mb40 f14"> <div class="analysis-block mt10 mb40 f14">
<div><span class="fontGrey3 mr30">技术债务</span><span class="w70 pInline"><%=@complexity["msr"][8].nil? ? 0 : @complexity["msr"][8]["frmt_val"] %></span> <div><span class="fontGrey3 mr30">技术债务</span>
<span class="w70 pInline">
<% if @complexity["msr"][8].nil? %>
0
<% else %>
<%= /[0-9]*/.match(@complexity["msr"][8]["frmt_val"])[0] %>天
<%= / [0-9]*/.match(@complexity["msr"][8]["frmt_val"]) %>小时
<% end %>
</span>
<span class="fontGrey2"><a class="linkBlue2" target="_blank" href="<%= @sonar_address %>/drilldown/measures/<%= @resource_id %>?metric=sqale_index">查看详情</a></span></div> <span class="fontGrey2"><a class="linkBlue2" target="_blank" href="<%= @sonar_address %>/drilldown/measures/<%= @resource_id %>?metric=sqale_index">查看详情</a></span></div>
<div><span class="fontGrey3 mr30 fl">质量问题</span> <div><span class="fontGrey3 mr30 fl">质量问题</span>
<span class="fontBlue2 w70 pInline"><a class="fontBlue2 w70 pInline" target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false"><%=@sonar_issues["msr"][0].nil? ? 0 : @sonar_issues["msr"][0]["frmt_val"] %></a></span><span class="fontGrey2">&nbsp;问题分类如下:</span></div> <span class="fontBlue2 w70 pInline"><a class="fontBlue2 w70 pInline" target="_blank" href="<%= @sonar_address %>/component_issues?id=<%= @resource_id %>#resolved=false"><%=@sonar_issues["msr"][0].nil? ? 0 : @sonar_issues["msr"][0]["frmt_val"] %></a></span><span class="fontGrey2">&nbsp;问题分类如下:</span></div>

@ -1,9 +1,11 @@
<% if @current_build_status == "success" %> <div class="project_r_h">
<%= render :partial => "show", :locals => {:branch => params[:branch]} %> <h2 class="project_h2" style="width:180px;">质量分析</h2>
<% else %> </div>
<% if @build_console_result %> <div>
运行结果超时 <div class="c_red">本次分析失败,原因如下:</div>
<% if @build_console_result == false %>
分析超时
<% else %> <% else %>
<%= render :partial => "console_output" %> <%= h @sonar_error.to_json %>
<% end %> <% end %>
<% end %> </div>

@ -0,0 +1,11 @@
<div class="project_r_h">
<h2 class="project_h2" style="width:180px;">质量分析</h2>
</div>
<div>
<div class="c_red">本次分析失败,原因如下:</div>
<% if @build_console_result == false %>
分析超时
<% else %>
<%= h @error_list.output %>
<% end %>
</div>

@ -9,7 +9,7 @@
<tr id="<%= tr_id %>" class="<%= h params[:parent_id] %> entry <%= entry.kind %>"> <tr id="<%= tr_id %>" class="<%= h params[:parent_id] %> entry <%= entry.kind %>">
<td style="padding-left: <%=18 * depth%>px;" class="filename_no_report hidden"> <td style="padding-left: <%=18 * depth%>px;" class="filename_no_report hidden">
<% if entry.is_dir? %> <% if entry.is_dir? %>
<%# 展开文件目录 %> <%# 展开文件目录 %>
<span class="expander" onclick="scmEntryClick('<%= tr_id %>', '<%= escape_javascript(url_for( <span class="expander" onclick="scmEntryClick('<%= tr_id %>', '<%= escape_javascript(url_for(
:action => 'show', :action => 'show',
:id => @project, :id => @project,
@ -20,17 +20,10 @@
:depth => (depth + 1), :depth => (depth + 1),
:parent_id => tr_id)) %>');">&nbsp;</span> :parent_id => tr_id)) %>');">&nbsp;</span>
<% end %> <% end %>
<!--<a class="<%#= (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}") %>">--> <%= link_to h(ent_name),
<!--<%#= h(ent_name) %>-->
<!--</a>-->
<%#= h(ent_name), :class => "(entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
<%= link_to h(ent_name),
{:action => (entry.is_dir? ? 'show' : 'entry'), :id => @project, :repository_id => @repository.identifier_param, :path => to_path_param(ent_path), :rev => @rev}, {:action => (entry.is_dir? ? 'show' : 'entry'), :id => @project, :repository_id => @repository.identifier_param, :path => to_path_param(ent_path), :rev => @rev},
:class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%> :class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
</td> </td>
<!--<td class="size"><%#= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>-->
<!--<td class="size"><%#= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>-->
<%# if @repository.report_last_commit %>
<div id="children_tree"> <div id="children_tree">
<td class="tree-comments c_grey hidden"> <td class="tree-comments c_grey hidden">
<div class="hidden" title="<%= (latest_changes.message) if latest_changes && latest_changes.message %>"> <div class="hidden" title="<%= (latest_changes.message) if latest_changes && latest_changes.message %>">
@ -46,10 +39,8 @@
<div class="hidden" title="<%= format_time(latest_changes.time) %>"> <div class="hidden" title="<%= format_time(latest_changes.time) %>">
<%# 为了转换UTC时间时差8小时 %> <%# 为了转换UTC时间时差8小时 %>
<%= distance_of_time_in_words(latest_changes.time, Time.now + 8.hours) if latest_changes && latest_changes.time %> <%= distance_of_time_in_words(latest_changes.time, Time.now + 8.hours) if latest_changes && latest_changes.time %>
<%#= latest_changes.time if latest_changes && latest_changes.time %>
</div> </div>
</td> </td>
</div> </div>
<%# end %>
</tr> </tr>
<% end %> <% end %>

@ -21,9 +21,9 @@
<%= select_tag :branch, options_for_select(@repository.branches, @rev), :id => 'branch' %> <%= select_tag :branch, options_for_select(@repository.branches, @rev), :id => 'branch' %>
<% end -%> <% end -%>
<% if !@repository.tags.nil? && @repository.tags.length > 0 -%> <%# if !@repository.tags.nil? && @repository.tags.length > 0 -%>
<%= select_tag :tag, options_for_select([''] + @repository.tags, @rev), :id => 'tag', :style=>" display:none" %> <%#= select_tag :tag, options_for_select([''] + @repository.tags, @rev), :id => 'tag', :style=>" display:none" %>
<% end -%> <%# end -%>
<% if @repository.supports_all_revisions? %> <% if @repository.supports_all_revisions? %>
<%= hidden_field_tag 'rev', @rev, :size => 8 %> <%= hidden_field_tag 'rev', @rev, :size => 8 %>

@ -15,7 +15,7 @@
<%= select_tag :language, options_for_select(["java","python","ruby","c++","c#","c"]), :id => 'branch', :class => "analysis-option-box" %> <%= select_tag :language, options_for_select(["java","python","ruby","c++","c#","c"]), :id => 'branch', :class => "analysis-option-box" %>
</div> </div>
</div> </div>
<div class="courseSendSubmit mr15"><a href="javascript:void(0);" class="sendSourceText" onclick="$('#ajax-indicator').text('正在分析中…………(大概需要30分钟请耐心等待)').show();$('#quality_analyses_form').submit();hideModal()">提交</a></div> <div class="courseSendSubmit mr15"><a href="javascript:void(0);" class="sendSourceText" onclick="$('#ajax-indicator').css('opacity','0.8').text('正在分析中…………(大概需要30分钟请耐心等待)').show();$('#quality_analyses_form').submit();hideModal()">提交</a></div>
<div class="courseSendCancel"><a href="javascript:void(0);" class="sendSourceText" onclick="hideModal()">取消</a></div> <div class="courseSendCancel"><a href="javascript:void(0);" class="sendSourceText" onclick="hideModal()">取消</a></div>
<div class="cl"></div> <div class="cl"></div>
</div> </div>

@ -1,17 +1,11 @@
<%= call_hook(:view_repositories_show_contextual, {:repository => @repository, :project => @project}) %> <%#= call_hook(:view_repositories_show_contextual, {:repository => @repository, :project => @project}) %>
<div class="project_r_h"> <div class="project_r_h">
<div class="fl"><h2 class="project_h2_repository"><%= render :partial => 'breadcrumbs', :locals => {:path => @path, :kind => 'dir', :revision => @rev} %></h2></div> <div class="fl"><h2 class="project_h2_repository"><%= render :partial => 'breadcrumbs', :locals => {:path => @path, :kind => 'dir', :revision => @rev} %></h2></div>
<% unless @entries.nil? %> <% unless @entries.nil? %>
<a href="<%= @zip_path %>" class="btn_zipdown fr" onclick="">ZIP下载</a> <a href="<%= @zip_path %>" class="btn_zipdown fr" onclick="">ZIP下载</a>
<%# if is_project_manager?(User.current, @project.id) && QualityAnalysis.where(:project_id => @project.id).first.nil? %>
<%# if User.current.member_of?(@project) %>
<% if quality_analysis(User.current.try(:login), @repository.id).nil? && User.current.member_of?(@project) && @project.is_public? %> <% if quality_analysis(User.current.try(:login), @repository.id).nil? && User.current.member_of?(@project) && @project.is_public? %>
<%= link_to "质量分析", quality_analysis_path(:id => @project.id, :repository_id => @repository.identifier, :rev => @rev, :default_branch => @g_default_branch ), :remote => true, :class => "btn_zipdown fr" %> <%= link_to "质量分析", quality_analysis_path(:id => @project.id, :repository_id => @repository.identifier, :rev => @rev, :default_branch => @g_default_branch ), :remote => true, :class => "btn_zipdown fr" %>
<% end %> <% end %>
<%# end %>
<%# else %>
<%#= link_to "质量分析", project_quality_analysis_path(:project_id => @project.id, :resource_id => @proje), :class => "btn_zipdown fr" %>
<%# end %>
<% end %> <% end %>
</div> </div>
<div class="repository_con" style="line-height:1.9;"> <div class="repository_con" style="line-height:1.9;">
@ -23,29 +17,29 @@
该版本库还没有上传代码! 该版本库还没有上传代码!
</div> </div>
<% end %> <% end %>
<% if @repository.type.to_s=="Repository::Gitlab" %> <% if @repository.type.to_s == "Repository::Gitlab" %>
版本库地址:<%= @repos_url %> 版本库地址:<%= @repos_url %>
<% else %> <% else %>
版本库地址:<%= h @repository.url %> 版本库地址:<%= h @repository.url %>
<% end %> <% end %>
<!-- added by bai -->
<div class="cl"></div> <div class="cl"></div>
</div> </div>
<% else %> <% else %>
<%= render :partial => 'navigation' %> <%= render :partial => 'navigation' %>
<div class="fl c_grey02 mt5 mr5">克隆网址:</div> <div class="fl c_grey02 mt5 mr5">克隆网址:</div>
<textarea id="copy_rep_content" class="cloneUrl mt5 fl" type="input" ><%= @repository.type.to_s=="Repository::Gitlab" ? @repos_url.to_s.lstrip : @repository.url %></textarea> <textarea id="copy_rep_content" class="cloneUrl mt5 fl" type="input" ><%= @repos_url.to_s.lstrip %></textarea>
<a href="javascript:void(0);" class="clone_btn mt5" onclick="jsCopy()"><span class="vl_copy" title="点击复制版本库地址"></span></a> <a href="javascript:void(0);" class="clone_btn mt5" onclick="jsCopy()"><span class="vl_copy" title="点击复制版本库地址"></span></a>
<div class="fl mt5 ml15"> <div class="fl mt5 ml15">
<%=link_to "代码统计", stats_repository_project_path(:id => @project.id, :repository_id => @repository.identifier, :rev => @rev, :creator => @creator, :default_branch => @g_default_branch ), :class => "fl vl_zip" %> <%=link_to "代码统计", stats_repository_project_path(:id => @project.id, :repository_id => @repository.identifier, :rev => @rev, :creator => @creator, :default_branch => @g_default_branch ), :class => "fl vl_zip" %>
</div> </div>
<%# 针对公开项目:用户必须创建了项目,否则用户无法同步 %>
<% if User.current.id != @project.user_id %> <% if User.current.id != @project.user_id %>
<div class="fr mt5"><%= link_to "<span class='vl_fork'></span>".html_safe+"Fork", {:controller => 'repositories', :action => 'forked'}, :class=>"vl_btn", :target => "_blank", :confirm=>"平台将为您创建一个新的同名项目和版本库,请问是否继续?" %> <div class="fr mt5"><%= link_to "<span class='vl_fork'></span>".html_safe+"Fork", {:controller => 'repositories', :action => 'forked'}, :class=>"vl_btn", :target => "_blank", :confirm=>"平台将为您创建一个新的同名项目和版本库,请问是否继续?" %>
<span href="javascript:void(0);" class="vl_btn_2 fb"><%= @project.forked_count.to_i %></span> <span href="javascript:void(0);" class="vl_btn_2 fb"><%= @project.forked_count.to_i %></span>
</div> </div>
<% end %> <% end %>
<div class="cl"></div> <div class="cl"></div>
<div class="recordBanner mt10"> <div class="recordBanner mt10">
<% if @changesets && !@changesets.empty? %> <% if @changesets && !@changesets.empty? %>
<% if !user_commit_rep(@changesets_latest_coimmit.author_email).nil? %> <% if !user_commit_rep(@changesets_latest_coimmit.author_email).nil? %>
@ -71,24 +65,14 @@
</div> </div>
<% end %> <% end %>
<!--contextual end-->
<% if !@entries.nil? && authorize_for('repositories', 'browse') %> <% if !@entries.nil? && authorize_for('repositories', 'browse') %>
<%# 数据统计 %>
<%#= render :partial => 'summary' %>
<%# end %>
<%= render :partial => 'dir_list' %> <%= render :partial => 'dir_list' %>
<% end %> <% end %>
<%#= render_properties(@properties) %>
<!-- 代码修订 -->
<%#= render_properties(@properties) %>
<a href="https://<%=Setting.host_name %>/forums/1/memos/1232" >如何提交代码</a> <a href="https://<%=Setting.host_name %>/forums/1/memos/1232" >如何提交代码</a>
</div> </div>
<% content_for :header_tags do %> <%# content_for :header_tags do %>
<%= stylesheet_link_tag "scm" %> <%#= stylesheet_link_tag "scm" %>
<% end %> <%# end %>
<% html_title(l(:label_repository)) -%> <% html_title(l(:label_repository)) -%>

@ -797,6 +797,7 @@ RedmineApp::Application.routes.draw do
match 'update_jenkins_job' match 'update_jenkins_job'
match 'edit' match 'edit'
match 'create' match 'create'
get 'error_list'
end end
end end
# resources :files, :only => [:index, :new, :create] do # resources :files, :only => [:index, :new, :create] do

@ -0,0 +1,11 @@
class CreateSonarErrors < ActiveRecord::Migration
def change
create_table :sonar_errors do |t|
t.integer :project_id
t.string :jenkins_job_name
t.text :output
t.timestamps
end
end
end

@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20160627090316) do ActiveRecord::Schema.define(:version => 20160707031248) do
create_table "activities", :force => true do |t| create_table "activities", :force => true do |t|
t.integer "act_id", :null => false t.integer "act_id", :null => false
@ -57,6 +57,18 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
t.integer "user_id", :null => false t.integer "user_id", :null => false
end end
create_table "apply_add_schools", :force => true do |t|
t.string "name"
t.string "province"
t.string "city"
t.string "address"
t.string "remarks"
t.integer "school_id"
t.integer "status", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "apply_homeworks", :force => true do |t| create_table "apply_homeworks", :force => true do |t|
t.integer "status" t.integer "status"
t.integer "user_id" t.integer "user_id"
@ -1637,6 +1649,7 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
t.string "logo_link" t.string "logo_link"
t.string "pinyin" t.string "pinyin"
t.integer "school_type", :default => 0
end end
create_table "secdomains", :force => true do |t| create_table "secdomains", :force => true do |t|
@ -1725,6 +1738,14 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
t.integer "project_id" t.integer "project_id"
end end
create_table "sonar_errors", :force => true do |t|
t.integer "project_id"
t.string "jenkins_job_name"
t.text "output"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "ssos", :force => true do |t| create_table "ssos", :force => true do |t|
t.integer "user_id" t.integer "user_id"
t.string "openid" t.string "openid"
@ -1851,6 +1872,16 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
t.integer "user_id" t.integer "user_id"
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
t.string "eng_name"
t.integer "syllabus_type"
t.integer "credit"
t.integer "hours"
t.integer "theory_hours"
t.integer "practice_hours"
t.string "applicable_major"
t.string "pre_course"
t.integer "visits", :default => 0
t.integer "des_status", :default => 0
end end
add_index "syllabuses", ["user_id"], :name => "index_syllabuses_on_user_id" add_index "syllabuses", ["user_id"], :name => "index_syllabuses_on_user_id"

@ -75,6 +75,17 @@ class Gitlab::Client
end end
alias_method :repo_commits, :commits_total_count alias_method :repo_commits, :commits_total_count
# Gets total project commits.
#
# @example
# @param [Integer] project The ID of a project.
# @param [Hash] options A customizable set of options.
# @option options [String] :rev The branch or tag name of a project repository.
# @return [Hash<Gitlab::ObjectifiedHash>]
def user_static(project, options={})
get("/projects/#{project}/repository/user_static", :query => options)
end
# Gets a specific commit identified by the commit hash or name of a branch or tag. # Gets a specific commit identified by the commit hash or name of a branch or tag.
# #
# @example # @example

@ -246,7 +246,7 @@ a.c_green{ color:#28be6c;}
.b_blue{background:#64bdd9;} .b_blue{background:#64bdd9;}
.b_green{background:#28be6c;} .b_green{background:#28be6c;}
.b_slow_yellow{background:#adde18;} .b_slow_yellow{background:#adde18;}
.b_yellow{background:#DDDF0D;} .b_yellow{background:#e4de4b;}
.b_slow_red{background:#df8538;} .b_slow_red{background:#df8538;}
.b_green2 {background:#63c360;} .b_green2 {background:#63c360;}
.b_red {background:#d60308;} .b_red {background:#d60308;}

@ -0,0 +1,7 @@
FactoryGirl.define do
factory :sonar_error do
project_id 1
jenkins_job_name "MyString"
output "MyText"
end
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe SonarError, :type => :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save