diff --git a/Gemfile b/Gemfile index 4012237ef..86f98629d 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,11 @@ unless RUBY_PLATFORM =~ /w32/ gem "rmagick", ">= 2.0.0" end -gem 'certified' +gem 'net-ssh', '2.9.1' +gem 'jenkins_api_client' +gem 'nokogiri' + +# gem 'certified' gem 'wechat',path: 'lib/wechat' gem 'grack', path:'lib/grack' diff --git a/app/assets/javascripts/quality_analyses.js.coffee b/app/assets/javascripts/quality_analyses.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/quality_analyses.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/quality_analyses.css.scss b/app/assets/stylesheets/quality_analyses.css.scss new file mode 100644 index 000000000..9404eb70f --- /dev/null +++ b/app/assets/stylesheets/quality_analyses.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the QualityAnalyses controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 43b488e96..7dea90e4b 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -1305,12 +1305,12 @@ class CoursesController < ApplicationController sheet[count_row,7] = stu.teaching_asistant_score.nil? ? l(:label_without_score) : stu.teaching_asistant_score.round(2) if home.anonymous_comment ==0 sheet[count_row,8] = stu.student_score.nil? ? l(:label_without_score) : stu.student_score.round(2) - sheet[count_row,9] = home.teacher_priority == 1 ? 0 : stu.absence_penalty - sheet[count_row,10] = home.teacher_priority == 1 ? 0 : stu.late_penalty + sheet[count_row,9] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.absence_penalty + sheet[count_row,10] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.late_penalty sheet[count_row,11] = stu.work_score.nil? ? l(:label_without_score) : stu.work_score.round(2) sheet[count_row,12] = format_time(stu.created_at) else - sheet[count_row,8] = home.teacher_priority == 1 ? 0 : stu.late_penalty + sheet[count_row,8] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.late_penalty sheet[count_row,9] = stu.work_score.nil? ? l(:label_without_score) : stu.work_score.round(2) sheet[count_row,10] = format_time(stu.created_at) end @@ -1338,12 +1338,12 @@ class CoursesController < ApplicationController sheet[count_row,8] = stu.system_score.nil? ? l(:label_without_score) : stu.system_score.round(2) if home.anonymous_comment ==0 sheet[count_row,9] = stu.student_score.nil? ? l(:label_without_score) : stu.student_score.round(2) - sheet[count_row,10] = home.teacher_priority == 1 ? 0 : stu.absence_penalty - sheet[count_row,11] = home.teacher_priority == 1 ? 0 : stu.late_penalty + sheet[count_row,10] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.absence_penalty + sheet[count_row,11] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.late_penalty sheet[count_row,12] = stu.work_score.nil? ? l(:label_without_score) : stu.work_score.round(2) sheet[count_row,13] = format_time(stu.created_at) else - sheet[count_row,9] = home.teacher_priority == 1 ? 0 : stu.late_penalty + sheet[count_row,9] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.late_penalty sheet[count_row,10] = stu.work_score.nil? ? l(:label_without_score) : stu.work_score.round(2) sheet[count_row,11] = format_time(stu.created_at) end @@ -1369,12 +1369,12 @@ class CoursesController < ApplicationController sheet[count_row,6] = stu.teaching_asistant_score.nil? ? l(:label_without_score) : stu.teaching_asistant_score.round(2) if home.anonymous_comment ==0 sheet[count_row,7] = stu.student_score.nil? ? l(:label_without_score) : stu.student_score.round(2) - sheet[count_row,8] = home.teacher_priority == 1 ? 0 : stu.absence_penalty - sheet[count_row,9] = home.teacher_priority == 1 ? 0 : stu.late_penalty + sheet[count_row,8] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.absence_penalty + sheet[count_row,9] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.late_penalty sheet[count_row,10] = stu.work_score.nil? ? l(:label_without_score) : stu.work_score.round(2) sheet[count_row,11] = format_time(stu.created_at) else - sheet[count_row,7] = home.teacher_priority == 1 ? 0 : stu.late_penalty + sheet[count_row,7] = (home.teacher_priority == 1 && !stu.teacher_score.nil?) ? 0 : stu.late_penalty sheet[count_row,8] = stu.work_score.nil? ? l(:label_without_score) : stu.work_score.round(2) sheet[count_row,9] = format_time(stu.created_at) end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 6029e7e37..8664a1372 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -404,7 +404,7 @@ class ProjectsController < ApplicationController unless @project.gpid.nil? g = Gitlab.client @gitlab_branches = g.branches(@project.gpid) - @branch_names = g.branches(@project.gpid).map{|b| b.name} + @branch_names = @gitlab_branches.map{|b| b.name} @gitlab_default_branch = g.project(@project.gpid).default_branch end end @@ -656,7 +656,7 @@ class ProjectsController < ApplicationController params[:project][:is_public] ? @project.is_public = 1 : @project.is_public = 0 params[:project][:hidden_repo] ? @project.hidden_repo = 1 : @project.hidden_repo = 0 # 更新公开私有时同步gitlab公开私有 - unless @project.gpid.nil? + if !@project.gpid.nil? && @project.is_public != (params[:project][:is_public] == "on" ? true : false) g = Gitlab.client params[:project][:is_public] ? g.edit_project(@project.gpid, 20, params[:branch]) : g.edit_project(@project.gpid, 0, params[:branch]) end diff --git a/app/controllers/quality_analysis_controller.rb b/app/controllers/quality_analysis_controller.rb new file mode 100644 index 000000000..83e5960b9 --- /dev/null +++ b/app/controllers/quality_analysis_controller.rb @@ -0,0 +1,99 @@ +class QualityAnalysisController < ApplicationController + before_filter :find_project_by_project_id#, :except => [:getattachtype] + before_filter :authorize + layout "base_projects" + include ApplicationHelper + require 'jenkins_api_client' + require 'nokogiri' + require 'json' + require 'open-uri' + + def show + + end + + def create + gitlab_address = Redmine::Configuration['gitlab_address'] + jenkins_address = Redmine::Configuration['jenkins_address'] + @client = JenkinsApi::Client.new(:server_url => jenkins_address, + :username => "temp", + :password => '123123') + #@client.exists?(job_name) + @g = Gitlab.client + user_name = User.find(params[:user_id]).try(:login) + branch = params[:branch].nil? ? "master" : params[:branch] + language = params[:language] + path = params[:path] + identifier = params[:identifier] + qa = QualityAnalysis.where(:project_id => @project.id, :author_login => user_name).first + version = qa.nil? ? 1 : qa.sonar_version + 1 + properties = "sonar.projectKey=#{user_name}:#{identifier} + sonar.projectName=#{user_name}:#{identifier} + 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 + @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 + # + # replace config.xml of jenkins + @client = @client.job.create("#{user_name}_#{identifier}", @doc.to_xml) + # relace gitlab hook + # genkins address + @g.add_project_hook(@project.gpid, jenkins_address + "/project/#{user_name}_#{identifier}") + if qa.nil? + QualityAnalysis.create(:project_id => @project.id, :author_login => user_name, :rep_identifier => identifier, :sonar_version => version, :path => path, :branch => branch, :language => language) + + else + qa.update_attribute(:sonar_version, version) + end + end + + def index + @sonar_address = Redmine::Configuration['sonar_address'] + # if params[:resource_id].nil? + # @name_flag = true + # @quality_analyses = QualityAnalysis.where(:project_id => @project.id) + # # @quality_analyses.map {|qa| qa.} + # # if @quality_analyses.count > 0 + # # @quality_analyses.each do |qa| + # # ["Hjqreturn:cc_rep", "Hjqreturn:putong", "Hjqreturn:sonar_rep2", "shitou:sonar_rep"] + # # + # # end + # # end + # # projects_date = open(@sonar_address + "/api/projects/index").read + # # arr = JSON.parse(projects_date).map {|m| m["nm"]} + # # arr.map + # else + qa = QualityAnalysis.where(:project_id => @project.id).first + @resource_id = qa.author_login+":"+qa.rep_identifier + @name_flag = false + 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 + 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 + + # 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 + +end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 9e785c562..cbb5b2f69 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -30,11 +30,13 @@ class RepositoriesController < ApplicationController menu_item :settings, :only => [:new, :create, :edit, :update, :destroy, :committers] default_search_scope :changesets - before_filter :find_project_by_project_id, :only => [:new, :create, :newrepo, :stats] + before_filter :find_project_by_project_id, :only => [:new, :create, :newrepo, :stats, :quality_analysis] before_filter :find_repository, :only => [:edit, :update, :destroy, :committers] before_filter :find_project_repository, :except => [:new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo, :to_gitlab, :forked, :project_archive] 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] + before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :commit_diff, :project_archive, :quality_analysis] + # 链接gitlab + before_filter :connect_gitlab, :only => [:quality_analysis] accept_rss_auth :revisions # hidden repositories filter // 隐藏代码过滤器 before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ] @@ -43,6 +45,7 @@ class RepositoriesController < ApplicationController helper :project_score #@root_path = RepositoriesHelper::ROOT_PATH $g=Gitlab.client + require 'net/ssh' rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed def new @@ -306,6 +309,37 @@ update end end + def quality_analysis + gitlab_branches = @g.branches(@project.gpid) + @branch_names = gitlab_branches.map{|b| b.name} + @gitlab_default_branch = @g.project(@project.gpid).default_branch + # language = params[:language] + # branch = params[:branch] + # path = params[:path] + # user_name = User.find(@project.user_id).try(:login) + # rep_name = params[:repository_id] + # host = "192.168.0.200" + # port = "1125" + # username = "git" + # password = "123123" + # server_cmd1 = "sh gitclone.sh" + " " + user_name + " " + rep_name + # # 连接到远程主机 foobar + # ssh = Net::SSH.start(host, username, :port => port, :password => password) do |ssh| + # result = ssh.exec!(server_cmd1) + # path = "/home/git/repo/" + user_name + "/" + rep_name + # # sonar 分析 + # # server_cmd2 + # # 删除clone的版本库 + # # server_cmd3 + # end + respond_to do |format| + format.js + format.html{ + render :layout => "base_projects" + } + end + end + def destroy DestroyRepositoryTask.new.destroy(User.current.id, @repository.id) @repository.hidden = true @@ -615,6 +649,14 @@ update project.project_score.update_attribute(:commit_time, date.created_at) end + # 链接gitlab + def connect_gitlab + @g = Gitlab.client + unless @project.gpid.nil? + @g_project = @g.project(@project.gpid) + end + end + def find_repository @repository = Repository.find(params[:id]) @project = @repository.project diff --git a/app/controllers/student_work_controller.rb b/app/controllers/student_work_controller.rb index 3a72ba55e..9006c8a79 100644 --- a/app/controllers/student_work_controller.rb +++ b/app/controllers/student_work_controller.rb @@ -1230,12 +1230,12 @@ class StudentWorkController < ApplicationController sheet1[count_row,8] = homework.teaching_asistant_score.nil? ? l(:label_without_score) : homework.teaching_asistant_score.round(2) if @homework.anonymous_comment ==0 sheet1[count_row,9] = homework.student_score.nil? ? l(:label_without_score) : homework.student_score.round(2) - sheet1[count_row,10] = @homework.teacher_priority == 1 ? 0 : homework.absence_penalty - sheet1[count_row,11] = @homework.teacher_priority == 1 ? 0 : homework.late_penalty + sheet1[count_row,10] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.absence_penalty + sheet1[count_row,11] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.late_penalty sheet1[count_row,12] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : homework.score.round(2) : l(:label_without_score) sheet1[count_row,13] = format_time(homework.created_at) else - sheet1[count_row,9] = @homework.teacher_priority == 1 ? 0 : homework.late_penalty + sheet1[count_row,9] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.late_penalty sheet1[count_row,10] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : homework.score.round(2) : l(:label_without_score) sheet1[count_row,11] = format_time(homework.created_at) end @@ -1263,12 +1263,12 @@ class StudentWorkController < ApplicationController sheet1[count_row,9] = homework.system_score.nil? ? l(:label_without_score) : homework.system_score.round(2) if @homework.anonymous_comment ==0 sheet1[count_row,10] = homework.student_score.nil? ? l(:label_without_score) : homework.student_score.round(2) - sheet1[count_row,11] = @homework.teacher_priority == 1 ? 0 : homework.absence_penalty - sheet1[count_row,12] = @homework.teacher_priority == 1 ? 0 : homework.late_penalty + sheet1[count_row,11] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.absence_penalty + sheet1[count_row,12] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.late_penalty sheet1[count_row,13] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : homework.score.round(2) : l(:label_without_score) sheet1[count_row,14] = format_time(homework.created_at) else - sheet1[count_row,10] = @homework.teacher_priority == 1 ? 0 : homework.late_penalty + sheet1[count_row,10] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.late_penalty sheet1[count_row,11] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : homework.score.round(2) : l(:label_without_score) sheet1[count_row,12] = format_time(homework.created_at) end @@ -1292,12 +1292,12 @@ class StudentWorkController < ApplicationController sheet1[count_row,5] = homework.teaching_asistant_score.nil? ? l(:label_without_score) : homework.teaching_asistant_score.round(2) if @homework.anonymous_comment ==0 sheet1[count_row,6] = homework.student_score.nil? ? l(:label_without_score) : homework.student_score.round(2) - sheet1[count_row,7] = @homework.teacher_priority == 1 ? 0 : homework.absence_penalty - sheet1[count_row,8] = @homework.teacher_priority == 1 ? 0 : homework.late_penalty + sheet1[count_row,7] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.absence_penalty + sheet1[count_row,8] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.late_penalty sheet1[count_row,9] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : homework.score.round(2) : l(:label_without_score) sheet1[count_row,10] = format_time(homework.created_at) else - sheet1[count_row,6] = @homework.teacher_priority == 1 ? 0 : homework.late_penalty + sheet1[count_row,6] = (@homework.teacher_priority == 1 && !homework.teacher_score.nil?) ? 0 : homework.late_penalty sheet1[count_row,7] = homework.respond_to?("score") ? homework.score.nil? ? l(:label_without_score) : homework.score.round(2) : l(:label_without_score) sheet1[count_row,8] = format_time(homework.created_at) end diff --git a/app/helpers/quality_analysis_helper.rb b/app/helpers/quality_analysis_helper.rb new file mode 100644 index 000000000..9c6c07109 --- /dev/null +++ b/app/helpers/quality_analysis_helper.rb @@ -0,0 +1,97 @@ +# encoding: utf-8 +module QualityAnalysisHelper + + def sqale_rating_status val + arr = [] + if val.to_i > 0 && val.to_i < 5 + arr << "很好" + arr << "b_green2" + elsif val.to_i > 5 && val.to_i < 10 + arr << "较好" + arr << "b_slow_yellow" + elsif val.to_i > 10 && val.to_i < 20 + arr << "中等" + arr << "b_yellow" + elsif val.to_i > 20 && val.to_i < 50 + arr << "较差" + arr << "b_slow_red" + elsif val.to_i > 20 + arr << "很差" + arr << "b_red" + end + end + + def complexity_status val + arr = [] + if val.to_i < 10 + arr << "良好" + arr << "b_green2" + elsif val.to_i > 10 && val.to_i < 15 + arr << "较高" + arr << "b_yellow" + elsif val.to_i > 15 + arr << "很高" + arr << "b_red" + end + end + + def duplicated_lines_density_status val + arr = [] + if val.to_i < 30 + arr << "良好" + arr << "b_green2" + elsif val.to_i > 30 && val.to_i < 50 + arr << "较高" + arr << "b_yellow" + elsif val.to_i > 50 + arr << "很高" + arr << "b_red" + end + end + + def comment_lines_density_status val + arr = [] + if val.to_i < 20 + arr << "较低" + arr << "b_yellow" + elsif val.to_i > 20 && val.to_i < 50 + arr << "正常" + arr << "b_green2" + elsif val.to_i > 50 + arr << "较高" + arr << "b_red" + end + end + + def score_sqale_rating val + if val.to_i > 0 && val.to_i < 5 + "5" + elsif val.to_i > 5 && val.to_i < 10 + "4" + elsif val.to_i > 10 && val.to_i < 20 + "3" + elsif val.to_i > 20 && val.to_i < 50 + "2" + elsif val.to_i > 20 + "1" + end + end + + def lines_scale val + if val.to_i < 5000 + "小型" + elsif val.to_i >5000 && val.to_i < 50000 + "中型" + else + "大型" + end + end + + #统计答题百分比,统计结果保留两位小数 + def statistics_result_percentage(e, t) + e = e.to_f + t = t.to_f + t == 0 ? 0 : format("%.2f", e*100/t) + end + +end diff --git a/app/models/project.rb b/app/models/project.rb index ceec0e182..bbc639f3d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -155,7 +155,7 @@ class Project < ActiveRecord::Base #ActiveModel::Dirty 这里有一个changed方法。对任何对象都可以用 after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?} # 创建project之后默认创建一个board,之后的board去掉了board的概念 - after_create :create_board_sync,:acts_as_forge_activities,:create_project_ealasticsearch_index + after_create :create_board_sync,:acts_as_forge_activities, :create_project_ealasticsearch_index before_destroy :delete_all_members,:delete_project_ealasticsearch_index after_update :update_project_ealasticsearch_index def remove_references_before_destroy diff --git a/app/models/quality_analysis.rb b/app/models/quality_analysis.rb new file mode 100644 index 000000000..229be9826 --- /dev/null +++ b/app/models/quality_analysis.rb @@ -0,0 +1,7 @@ +class QualityAnalysis < ActiveRecord::Base + attr_accessible :author_login, :project_id, :rep_identifier, :sonar_version, :branch, :path, :rep_identifier, :language + + def user_rep_name + self.author_login+":"+self.rep_identifier + end +end diff --git a/app/models/sonar_analysis.rb b/app/models/sonar_analysis.rb new file mode 100644 index 000000000..0bb2089de --- /dev/null +++ b/app/models/sonar_analysis.rb @@ -0,0 +1,3 @@ +class SonarAnalysis < ActiveRecord::Base + attr_accessible :author_login, :project_id, :rep_identifier +end diff --git a/app/views/courses/_join_private_course.html.erb b/app/views/courses/_join_private_course.html.erb index 0799953bf..96c9a2b7d 100644 --- a/app/views/courses/_join_private_course.html.erb +++ b/app/views/courses/_join_private_course.html.erb @@ -49,7 +49,7 @@
只要持有课程邀请码,就可以快速加入所在课程。课程页面搜索不到的私有课程只能从此通道进入哦!