From 8d54187e04446e0d88b51dd64332871763afddf1 Mon Sep 17 00:00:00 2001 From: huang Date: Fri, 3 Mar 2017 18:49:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=91=A8=E4=BA=94=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/javascripts/codes.js.coffee | 3 + app/assets/stylesheets/codes.css.scss | 3 + app/controllers/application_controller.rb | 2 + app/controllers/codes_controller.rb | 2 + app/controllers/repositories_controller.rb | 157 +++++++++++++++--- app/controllers/shixuns_controller.rb | 87 +++++++++- app/helpers/application_helper.rb | 5 + app/helpers/codes_helper.rb | 2 + app/helpers/shixuns_helper.rb | 16 ++ app/models/repository.rb | 5 +- app/models/shixun.rb | 3 +- app/models/user.rb | 8 +- .../repositories/_dir_list_content.html.erb | 2 +- .../repositories/_shixun_dir_list.html.erb | 27 +++ .../_shixun_dir_list_content.html.erb | 66 ++++++++ .../repositories/_shixun_navigation.html.erb | 34 ++++ app/views/repositories/commits.html.erb | 50 ++++++ app/views/repositories/shixun_show.html.erb | 45 +++++ .../shixuns/_settings_challenges.html.erb | 44 +++++ .../_settings_challenges_action_tip.html.erb | 7 + .../_settings_challenges_result_tip.html.erb | 3 + app/views/shixuns/_settings_edit.html | 1 + .../shixuns/_settings_repository.html.erb | 82 +++++++++ app/views/shixuns/_shixun_top.html.erb | 15 +- app/views/shixuns/add_script.js.erb | 2 + app/views/shixuns/settings.html.erb | 62 +++++++ config/routes.rb | 18 +- ...302094330_add_shixun_id_to_repositories.rb | 5 + ...70303071513_add_changeset_num_to_shixun.rb | 5 + db/schema.rb | 14 +- lib/redmine/scm/adapters/abstract_adapter.rb | 2 +- lib/redmine/scm/adapters/gitlab_adapter.rb | 18 +- lib/trustie/gitlab/helper.rb | 13 ++ lib/trustie/gitlab/sync.rb | 35 ++++ spec/controllers/codes_controller_spec.rb | 5 + 35 files changed, 798 insertions(+), 50 deletions(-) create mode 100644 app/assets/javascripts/codes.js.coffee create mode 100644 app/assets/stylesheets/codes.css.scss create mode 100644 app/controllers/codes_controller.rb create mode 100644 app/helpers/codes_helper.rb create mode 100644 app/views/repositories/_shixun_dir_list.html.erb create mode 100644 app/views/repositories/_shixun_dir_list_content.html.erb create mode 100644 app/views/repositories/_shixun_navigation.html.erb create mode 100644 app/views/repositories/commits.html.erb create mode 100644 app/views/repositories/shixun_show.html.erb create mode 100644 app/views/shixuns/_settings_challenges.html.erb create mode 100644 app/views/shixuns/_settings_challenges_action_tip.html.erb create mode 100644 app/views/shixuns/_settings_challenges_result_tip.html.erb create mode 100644 app/views/shixuns/_settings_edit.html create mode 100644 app/views/shixuns/_settings_repository.html.erb create mode 100644 app/views/shixuns/add_script.js.erb create mode 100644 app/views/shixuns/settings.html.erb create mode 100644 db/migrate/20170302094330_add_shixun_id_to_repositories.rb create mode 100644 db/migrate/20170303071513_add_changeset_num_to_shixun.rb create mode 100644 spec/controllers/codes_controller_spec.rb diff --git a/app/assets/javascripts/codes.js.coffee b/app/assets/javascripts/codes.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/codes.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/codes.css.scss b/app/assets/stylesheets/codes.css.scss new file mode 100644 index 000000000..51f919d1b --- /dev/null +++ b/app/assets/stylesheets/codes.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the codes 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/application_controller.rb b/app/controllers/application_controller.rb index 8a3445494..e973ae745 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -430,6 +430,8 @@ class ApplicationController < ActionController::Base def find_project_by_project_id if params[:project_id] @project = Project.find(params[:project_id]) + elsif params[:shixun_id] + @shixun = Shixun.find(params[:shixun_id]) elsif params[:course_id] @course = Course.find(params[:course_id]) elsif params[:org_subfield_id] diff --git a/app/controllers/codes_controller.rb b/app/controllers/codes_controller.rb new file mode 100644 index 000000000..1e5158602 --- /dev/null +++ b/app/controllers/codes_controller.rb @@ -0,0 +1,2 @@ +class CodesController < ApplicationController +end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 35fde54ac..e788c92d4 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -35,13 +35,17 @@ class RepositoriesController < ApplicationController 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, :export_rep_static, :training_project_extend] + before_filter :find_project_repository, :except => [:commits, :shixun_show, :new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo, :to_gitlab, :forked, :export_rep_static, :training_project_extend] + + # 实训项目新增 + before_filter :find_project_and_repository, :only => [:commits, :shixun_show] + # 连接gitlab # before_filter :connect_gitlab, :only => [:quality_analysis, :commit_diff] before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] # before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :project_archive, :quality_analysis, :commit_diff] - before_filter :authorize_visible , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :project_archive, :quality_analysis, :commit_diff] + before_filter :authorize_visible , :except => [:shixun_show, :newrepo,:newcreate,:fork, :to_gitlab, :forked, :project_archive, :quality_analysis, :commit_diff] # 版本库新增权限 # before_filter :show_rep, :only => [:show, :stats, :revisions, :revision, :diff, :commit_diff ] accept_rss_auth :revisions @@ -346,30 +350,24 @@ update } def create - # 判断版本库创建者是否有同名版本库,避免版本库路径一致问题 - unless is_sigle_identifier?(@project.user_id, params[:repository].first[1]) - flash[:notice] = l(:project_gitlab_create_double_message) - redirect_to settings_project_url(@project, :tab => 'repositories') - else - attrs = pickup_extra_info - @repository = Repository.factory('Git') - @repository.safe_attributes = params[:repository] - if attrs[:attrs_extra].keys.any? - @repository.merge_extra_info(attrs[:attrs_extra]) - end - @repository.project = @project + # 实训项目 + if @shixun + # REDO:报错信息处理 + @repository = Repository.new + @repository.shixun = @shixun @repository.type = 'Repository::Gitlab' - @repository.identifier = @repository.identifier.downcase + @repository.identifier = params[:repository][:identifier].downcase @repository.url = @repository.identifier + @repository.project_id = -1 ActiveRecord::Base.transaction do begin if request.post? && @repository.save s = Trustie::Gitlab::Sync.new - s.create_project(@project, @repository) - raise "sync failed" if @project.gpid.blank? - redirect_to(:controller => 'repositories', :action => 'show', :id => @project, :repository_id => gitlab_repository(@project).try(:identifier)) + s.create_shixun(@shixun, @repository) + raise "sync failed" if @shixun.gpid.blank? + redirect_to(:controller => 'repositories', :action => 'show', :shixun_id => @shixun, :identifier => @repository.try(:identifier)) else - redirect_to settings_project_url(@project, :tab => 'repositories',:repository_error_message=>@repository.errors.full_messages) + redirect_to settings_shixun_url(@shixun, :tab => 'repositories',:repository_error_message => @repository.errors.full_messages) end rescue Gitlab::Error::Forbidden => e @message = l(:label_pull_request_forbidden) @@ -379,6 +377,41 @@ update puts e end end + elsif @project + # 判断版本库创建者是否有同名版本库,避免版本库路径一致问题 + unless is_sigle_identifier?(@project.user_id, params[:repository].first[1]) + flash[:notice] = l(:project_gitlab_create_double_message) + redirect_to settings_project_url(@project, :tab => 'repositories') + else + attrs = pickup_extra_info + @repository = Repository.factory('Git') + @repository.safe_attributes = params[:repository] + if attrs[:attrs_extra].keys.any? + @repository.merge_extra_info(attrs[:attrs_extra]) + end + @repository.project = @project + @repository.type = 'Repository::Gitlab' + @repository.identifier = @repository.identifier.downcase + @repository.url = @repository.identifier + ActiveRecord::Base.transaction do + begin + if request.post? && @repository.save + s = Trustie::Gitlab::Sync.new + s.create_project(@project, @repository) + raise "sync failed" if @project.gpid.blank? + redirect_to(:controller => 'repositories', :action => 'show', :id => @project, :repository_id => gitlab_repository(@project).try(:identifier)) + else + redirect_to settings_project_url(@project, :tab => 'repositories',:repository_error_message=>@repository.errors.full_messages) + end + rescue Gitlab::Error::Forbidden => e + @message = l(:label_pull_request_forbidden) + rescue Gitlab::Error::NotFound => e + @message = l(:label_pull_request_notfound) + rescue Exception => e + puts e + end + end + end end end @@ -486,6 +519,40 @@ update redirect_to :controller => 'repositories', :action => 'show', :id => @project.id, to: 'gitlab' end + def shixun_show + # 顶部导航 + @project_menu_type = 5 + @entries = @repository.entries(@path, @rev) + if request.xhr? + @entries ? render(:partial => 'dir_list_content') : render(:nothing => true) + else + @changesets_latest_coimmit = @g.rep_last_changes(@shixun.gpid, :rev => @rev, :path => @path) + # @g.rep_last_changes(@project.gpid, :rev => @rev, :path => @path) + # 总的提交数 + @changesets_all_count = @g.user_static(@shixun.gpid, :rev => @rev).count + # 获取默认分支 + @g_default_branch = @g_project.default_branch.nil? ? "master" : @g_project.default_branch + + @creator = @shixun.owner.to_s + gitlab_address = Redmine::Configuration['gitlab_address'] + gitlab_token = Gitlab.private_token + # token值加密解密 + token = aes_encrypt("priEn3UwXfJs3Pmy", gitlab_token) + # token值解密 + # gitlab_token = aes_dicrypt("priEn3UwXfJs3Pmy", token) + @zip_path = Gitlab.endpoint.to_s + "/projects/" + @shixun.gpid.to_s + "/repository/archive?&private_token=" + token + + @creator = @shixun.owner.to_s + gitlab_address = Redmine::Configuration['gitlab_address'] + @repos_url = gitlab_address.to_s+"/" + @creator + "/" + @repository.identifier+"."+"git" + + # 提交总数同步更新 + @shixun.update_attribute(:changeset_num, @changesets_all_count) + render :layout => 'base_shixun' + + end + end + # 权限: # 如果项目隐藏了版本库,则非项目成员及项目报告人员不能够访问版本库 # 如果没有隐藏版本库,只要项目公开,其它成员都可以看到版本库 @@ -545,6 +612,20 @@ update end + def commits + # 顶部导航 + @project_menu_type = 5 + @entry = @repository.entry(@path, @rev) + (show_error_not_found; return) unless @entry + limit = 10 + # 每次页面的换回值从1开始,但是gitlab的页面查询是从0开始,所以先改变page的类型减一在改回来 + @commits = @g.commits(@shixun.gpid, page:(params[:page].to_i - 1).to_s, ref_name:@rev) + @commits_count = params[:commit_count].nil? ? @g.user_static(@shixun.gpid, :rev => @rev).count : params[:commit_count].to_i + @commits_pages = Paginator.new @commits_count, limit, params[:page] + + render :layout => 'base_shixun' + end + # 注:由于考虑到性能所以commits api每次返回20条记录 def changes # 顶部导航 @@ -699,6 +780,21 @@ update render :layout => 'base_projects' end + # 实训项目 + # 每次提交对应的文件差异 + def commit + # 顶部导航 + @project_menu_type = 5 + @commit_diff = @g.commit_diff(@project.gpid, params[:changeset]) + diff = ActiveSupport::JSON.decode(@commit_diff.to_json).first + diff = OpenStruct.new(diff) + @diff_file = Trustie::Gitlab::Diff::File.new(diff) + + + @commit_details = @g.commit(@project.gpid, params[:changeset]) + render :layout => 'base_projects' + end + def diff if params[:format] == 'diff' @diff = @repository.diff(@path, @rev, @rev_to) @@ -786,6 +882,29 @@ update end end + def find_project_and_repository + @shixun = Shixun.find(params[:id]) + @repository = @shixun.repository + render_404 if @shixun.gpid.nil? + @path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s + @g = Gitlab.client + @g_project = @g.project(@shixun.gpid) + @branchs = @g.branches(@shixun.gpid) + @g_default_branch = @g_project.default_branch + # gitlab端获取默认分支 + @rev = params[:rev].blank? ? @g_default_branch : params[:rev].to_s.strip + @rev_to = params[:rev_to] + unless @rev.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE) + if @branchs.blank? + raise InvalidRevisionParam + end + end + rescue ActiveRecord::RecordNotFound + render_404 + rescue InvalidRevisionParam + show_error_not_found + end + def authorize_visible allowed = authorize_allowed(params[:controller], params[:action], global = false) if allowed || User.current.admin? || (@project.hidden_repo && User.current.member_of?(@project) && !role_of_members_in_project(@project.id, User.current.id) == "Reporter") diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index c26ceabdf..6ca88fcf7 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -1,10 +1,11 @@ +# encoding: utf-8 class ShixunsController < ApplicationController layout 'base_shixun' before_filter :require_login before_filter :find_shixun, :except => [ :index, :new, :create, :training_execute, :training_task_status] before_filter :shixun_authorize, :only => [:show] - before_filter :require_manager, :only => [ :settings] + before_filter :require_manager, :only => [ :settings, :add_script] include ApplicationHelper @@ -53,6 +54,87 @@ class ShixunsController < ApplicationController end + def settings + @repository = Repository.where(:shixun_id => @shixun, :type => "Repository::Gitlab").first + unless @repository.nil? + gitlab_address = Redmine::Configuration['gitlab_address'] + creator = @shixun.owner.try(:login) + @repos_url = gitlab_address+"/" + creator + "/" + @repository.identifier+"."+"git" + end + + # scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first + # @repository = Repository.factory(scm) + # @repository.is_default = @project.repository.nil? + # @repository.project = @project + # @gitlab_rep = Repository.where(:type => "Repository::Gitlab", :project_id => @project).first + # unless @project.gpid.nil? + # 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 + end + + def rep_tree_changes + rev = params[:rev] + ent_path = params[:ent_path] + gpid = params[:gpid] + g = Gitlab.client + begin + result = g.rep_last_changes(gpid, :rev => rev, :path => ent_path) + result = {:message => result.message, :author_name => User.find_by_mail(result.author_email).nil? ? result.author_email : User.find_by_mail(result.author_email).show_name, :time => distance_of_time_in_words(result.time, Time.now)} + rescue Exception => e + puts e + end + render :json => result + end + + # 添加实训脚本 + def add_script + if User.current.admin? || User.current.member_of?(@project) + if @shixun.update_attribute(:script, params[:project_script]) + @notice = "脚本添加成功" + else + @notice = "脚本添加失败" + end + else + return render_403 + end + end + + # 创建实训job + def shixun_job_create + if @project.training_tasks.count == 0 + @notice = "实训开启失败:请先发布实训任务" + return + elsif Repository.where(:project_id => @project.id, :type => "Repository::Gitlab").count == 0 + @notice = "实训开启失败:请先创建版本库" + return + end + jobName = "#{@project.id}" + pipeLine = "#{Base64.encode64(@project.script)}" + uri = URI("http://123.59.135.74:9999/jenkins-exec/api/createJob") + params = {jobName: jobName, pipeLine: pipeLine} + res = uri_exec uri, params + training_project_notice res + if res['code'] == 0 + @project.update_attribute(:training_status, 1) + end + end + + # 更新实训job + def shixun_job_update + jobName = "#{@project.id}" + pipeLine = "#{Base64.encode64(@project.script)}" + uri = URI("http://123.59.135.74:9999/jenkins-exec/api/updateJob") + params = {jobName: jobName, pipeLine: pipeLine} + res = uri_exec uri, params + training_project_notice res + if res['code'] == 0 + @project.update_attribute(:training_status, 1) + end + end + # Find shixun of id params[:id] def find_shixun @shixun = Shixun.find(params[:id]) @@ -69,8 +151,9 @@ class ShixunsController < ApplicationController end end + # 实训管理员或者超级管理员 def require_manager - User.current.manager_of_shixun?(@shixun) + render_403 unless User.current.manager_of_shixun?(@shixun) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6dd20aceb..86d7133e3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1125,6 +1125,11 @@ module ApplicationHelper rep = Repository.where("project_id =? and type =?", project.id,"Repository::Gitlab" ).first end + # 获取单一gitlab项目 + def shixun_repository(shixun) + rep = Repository.where(:shixun_id => shixun, :type => "Repository::Gitlab" ).first + end + # 判断当前用户是否为项目管理员 def is_project_manager?(user_id, project_id) @result = false diff --git a/app/helpers/codes_helper.rb b/app/helpers/codes_helper.rb new file mode 100644 index 000000000..737330354 --- /dev/null +++ b/app/helpers/codes_helper.rb @@ -0,0 +1,2 @@ +module CodesHelper +end diff --git a/app/helpers/shixuns_helper.rb b/app/helpers/shixuns_helper.rb index 62912345d..d706dab91 100644 --- a/app/helpers/shixuns_helper.rb +++ b/app/helpers/shixuns_helper.rb @@ -1,2 +1,18 @@ module ShixunsHelper + + + #显示项目配置菜单 + def show_project_memu user + if user.allowed_to?(:edit_project, @shixun) + result = "edit_project" + elsif user.allowed_to?(:manage_members, @shixun) + result = "training_task" + elsif user.allowed_to?(:manage_versions, @shixun) + result = "manage_versions" + elsif user.allowed_to?(:manage_repository, @shixun) + result = "manage_repository" + end + result + end + end diff --git a/app/models/repository.rb b/app/models/repository.rb index c9346e15b..a4b9f4e01 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -25,6 +25,8 @@ class Repository < ActiveRecord::Base IDENTIFIER_MAX_LENGTH = 254 belongs_to :project + belongs_to :shixun + belongs_to :shixun has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC" has_many :filechanges, :class_name => 'Change', :through => :changesets @@ -106,8 +108,7 @@ class Repository < ActiveRecord::Base def scm unless @scm - @scm = self.scm_adapter.new(url, root_url, - login, password, path_encoding, project_id) + @scm = self.scm_adapter.new(url, root_url, login, password, path_encoding, project_id, shixun_id) if root_url.blank? && @scm.root_url.present? update_attribute(:root_url, @scm.root_url) end diff --git a/app/models/shixun.rb b/app/models/shixun.rb index 8ef07f6a7..38dd0c71f 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -1,8 +1,9 @@ class Shixun < ActiveRecord::Base - attr_accessible :description, :is_public, :name, :parent_id + attr_accessible :description, :is_public, :name, :parent_id, :changeset_num has_many :users, :through => :shixun_members has_many :shixun_members + has_one :repository def parent shixun = Shixun.find_by_parent_id(self.parent_id) diff --git a/app/models/user.rb b/app/models/user.rb index 5bae5aa5b..d2886b1b6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -898,12 +898,8 @@ class User < Principal end def manager_of_shixun?(shixun) - @result = false - mem = Member.where("user_id = ? and project_id = ?", self.id, shixun.id) - unless mem.blank? - @result = mem.first.roles.to_s.include?("Manager") ? true : false - end - return @result + member = ShixunMember.where(:user_id => self.id, :shixun_id => shixun.id, :role => 1) + (!member.blank? || User.current.admin?) ? true : false end def member_of_course?(course) diff --git a/app/views/repositories/_dir_list_content.html.erb b/app/views/repositories/_dir_list_content.html.erb index b45305e30..e039f041f 100644 --- a/app/views/repositories/_dir_list_content.html.erb +++ b/app/views/repositories/_dir_list_content.html.erb @@ -49,7 +49,7 @@ diff --git a/app/views/repositories/_shixun_dir_list_content.html.erb b/app/views/repositories/_shixun_dir_list_content.html.erb new file mode 100644 index 000000000..b45305e30 --- /dev/null +++ b/app/views/repositories/_shixun_dir_list_content.html.erb @@ -0,0 +1,66 @@ +<% @entries.each do |entry| %> + <% tr_id = Digest::MD5.hexdigest(entry.path) + depth = params[:depth].to_i %> + <% sub_path = entry.path[0] == "/" ? entry.path.sub("/", "") : entry.path %> + <% ent_path = Redmine::CodesetUtil.replace_invalid_utf8(sub_path) %> + <% ent_name = Redmine::CodesetUtil.replace_invalid_utf8(entry.name) %> + <%# latest_changes = get_trees_last_changes(@project.gpid, @rev, ent_path, @g) %> + + + + <% if entry.is_dir? %> + <%# 展开文件目录 %> +   + <% end %> + <%= 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}, + :class => (entry.is_dir? ? 'old-icon old-icon-folder' : "old-icon old-icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%> + +
+ + + + + + + + + + +
+ + + +<% end %> + + + diff --git a/app/views/repositories/_shixun_navigation.html.erb b/app/views/repositories/_shixun_navigation.html.erb new file mode 100644 index 000000000..0f04f8ab5 --- /dev/null +++ b/app/views/repositories/_shixun_navigation.html.erb @@ -0,0 +1,34 @@ + +<%#= link_to l(:label_statistics), + {:action => 'stats', :id => @project, :repository_id => @repository.identifier_param}, + :class => 'mt3 c_blue fl' if @repository.supports_all_revisions? %> +
+ <% content_for :header_tags do %> + <%= javascript_include_tag 'repository_navigation' %> + <% end %> + + + + <%= form_tag({:action => controller.action_name, + :id => @shixun, + :repository_id => @repository.identifier_param, + :path => to_path_param(@path), + :rev => nil}, + {:method => :get, :id => 'revision_selector'}) do -%> + + <% if @branchs.count > 0 -%> + + <%= select_tag :branch, options_for_select(@branchs.map{|map| map.name}, @rev), :id => 'branch', :class => "pro-fenzhi-select fl" %> + + <% end -%> + + <%# if !@repository.tags.nil? && @repository.tags.length > 0 -%> + <%#= select_tag :tag, options_for_select([''] + @repository.tags, @rev), :id => 'tag', :style=>" display:none" %> + <%# end -%> + + <% if @repository.supports_all_revisions? %> + <%= hidden_field_tag 'rev', @rev, :size => 8 %> + <% end %> + <% end -%> + +
diff --git a/app/views/repositories/commits.html.erb b/app/views/repositories/commits.html.erb new file mode 100644 index 000000000..ef58abfa6 --- /dev/null +++ b/app/views/repositories/commits.html.erb @@ -0,0 +1,50 @@ +
+
+
    + <%= render :partial => 'shixun_navigation' %> +
+
+ <% @commits.chunk { |c| format_date(c.created_at).to_date }.each do |day, commits| %> +
+
+

<%= day %>

+

当前页<%= commits.count %>个提交

+
+
    + <% commits.each do |commit| %> +
  • + <%= time_tag(commit.created_at) %>前 + <%= link_to_user_mail(commit.author_email, "pullreques_pull_name fl ml10") %> +

    <%= commit.title %>

    + <%= link_to truncate(commit.short_id, :length => 20), {:controller => 'repositories', :action => 'commits', :id => @shixun.id, :changeset_id => commit.id}, :target => "_blank", :class => "fr mr15 c_grey" %> + <% unless get_commit_issues(commit.short_id, @shixun.id, 0).nil? %> + <% get_commit_issues(commit.short_id, @shixun.id, 0).each do |issue_id| %> +
    + <% if issue_id == "more" %> + <%= link_to "更多", {:controller => 'repositories', :action => 'commit_diff', :id => @shixun.id, :changeset => commit.id}, :target => "_blank", :class => "commit_id_value mr5" %> + <% else %> + <%= link_to "##{issue_id}", issue_path(issue_id), :target => "_blank", :class => "commit_id_value mr5" %> + <% end %> +
    + <% end %> + <% end %> +
    +
  • + <% end %> +
+
+ <% end %> + +
+
+
    + <%= pagination_links_full @commits_pages, @commits_count, :per_page_links => false, :remote => false, :flag => true, :is_new => true %> +
+
+
+
+
+ + <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @shixun }) %> + <% html_title(l(:label_change_plural)) -%> +
diff --git a/app/views/repositories/shixun_show.html.erb b/app/views/repositories/shixun_show.html.erb new file mode 100644 index 000000000..3cb515feb --- /dev/null +++ b/app/views/repositories/shixun_show.html.erb @@ -0,0 +1,45 @@ +
+
+
    +
  • + <%=link_to "#{choise_commit_count(@changesets_all_count, @g_project.commit_count.to_i)}", + {:action => 'commits', :path => to_path_param(@path), :id => @shixun, :repository_id => @repository.identifier_param, + :rev => @rev, :page => 1 ,:commit_count =>"#{@changesets_all_count}"}, :class => "linkBlue fb" %> 提交 +
  • +
  • + <%= @branchs.count %>分支 +
  • +
+
+
+ <%= render :partial => 'shixun_navigation' %> +
+ <% if !@entries.blank? %> + ZIP下载 + <% end %> + +
+ + + +
+
+ +
+ <%= render :partial => 'latest_commit' %> +
+ + <% if !@entries.blank? && authorize_for('repositories', 'browse') %> + <%= render :partial => 'shixun_dir_list' %> + <% else %> + <%= render :partial => "projects/no_data" %> + <% end %> + + <% memo = Memo.where(:id => 1232).first %> + <% unless memo.nil? %> + <%=Setting.host_name %>/forums/1/memos/1232" class="linkBlue2" target="_blank">如何提交代码 + <% end %> +
+
+ +<% html_title(l(:label_repository)) -%> diff --git a/app/views/shixuns/_settings_challenges.html.erb b/app/views/shixuns/_settings_challenges.html.erb new file mode 100644 index 000000000..47b108f19 --- /dev/null +++ b/app/views/shixuns/_settings_challenges.html.erb @@ -0,0 +1,44 @@ +
+ <%= render :partial => "shixuns/settings_challenges_result_tip" %> +
+ +
+
+ <%= render :partial => "shixuns/settings_challenges_action_tip" %> +
+
+
+ <%= form_tag(url_for(:controller => 'shixuns', :action => 'add_script', :id => @shixun), :method => "post", :remote => true) do %> + + + 取消 + 确定 + <% end %> +
+
+ + diff --git a/app/views/shixuns/_settings_challenges_action_tip.html.erb b/app/views/shixuns/_settings_challenges_action_tip.html.erb new file mode 100644 index 000000000..ba22aaa1f --- /dev/null +++ b/app/views/shixuns/_settings_challenges_action_tip.html.erb @@ -0,0 +1,7 @@ +<% unless @shixun.script.blank? %> + <% if @shixun.training_status == 1 %> + <%= link_to "重启实训", training_project_update_project_path, :class => "fr sy_btn_green mb10", :remote => true %> + <% else %> + <%= link_to "开启实训", training_project_execute_project_path, :class => "fr sy_btn_green mb10", :remote => true %> + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/shixuns/_settings_challenges_result_tip.html.erb b/app/views/shixuns/_settings_challenges_result_tip.html.erb new file mode 100644 index 000000000..3445f4c9b --- /dev/null +++ b/app/views/shixuns/_settings_challenges_result_tip.html.erb @@ -0,0 +1,3 @@ +<% if @notice %> +

<%= @notice %>

+<% end %> diff --git a/app/views/shixuns/_settings_edit.html b/app/views/shixuns/_settings_edit.html new file mode 100644 index 000000000..24d08952d --- /dev/null +++ b/app/views/shixuns/_settings_edit.html @@ -0,0 +1 @@ +bianji \ No newline at end of file diff --git a/app/views/shixuns/_settings_repository.html.erb b/app/views/shixuns/_settings_repository.html.erb new file mode 100644 index 000000000..f5acca9a4 --- /dev/null +++ b/app/views/shixuns/_settings_repository.html.erb @@ -0,0 +1,82 @@ +

温馨提示:每个项目只能创建一个版本库

+<% if @repository.nil? %> +
+ <%= labelled_form_for :repository, @repository, :url => shixun_repositories_path(@shixun), :html => {:method => "post", :autocomplete => 'off'} do |f| %> + + <%=l(:button_cancel)%> + <%=l(:lable_project_rep_create) %> + <% end %> +
+<% else %> +
+ + + + + + + + + + + + + + + + +
+
+<% end %> + + diff --git a/app/views/shixuns/_shixun_top.html.erb b/app/views/shixuns/_shixun_top.html.erb index f3d26028f..e5b6438e3 100644 --- a/app/views/shixuns/_shixun_top.html.erb +++ b/app/views/shixuns/_shixun_top.html.erb @@ -34,13 +34,16 @@ <%= link_to 1 > 0 ? "#{l(:project_module_boards)}#{switch_integer_into_k 99999}".html_safe : "#{l(:project_module_boards)}", project_boards_path(@shixun), :class => "pro_new_proname", :title => "#{99999}" %> - -
  • <%= link_to 1 > 0 ? "#{l(:project_module_repository)}#{switch_integer_into_k 99999}".html_safe : "#{l(:project_module_repository)}",({:controller => 'repositories', :action => 'show', :id => @shixun, :repository_id => gitlab_repository(@shixun).try(:identifier)}), :class => "pro_new_proname", :title => "#{99999}" %>
  • - -
  • - <%= link_to "#{l(:button_configure)}", settings_project_path(@shixun), :class => "pro_new_proname" %> -
  • + <% unless @shixun.repository.nil? %> +
  • + <%= link_to (1 > 0 ? "#{l(:project_module_repository)}#{switch_integer_into_k 99999}".html_safe : "#{l(:project_module_repository)}"), + ({:controller => 'repositories', :action => 'show', :repository_id => shixun_repository(@shixun).try(:identifier)}), + :class => "pro_new_proname", :title => "#{99999}" %>
  • + <% end %> +
  • + <%= link_to "#{l(:button_configure)}", settings_shixun_path(@shixun), :class => "pro_new_proname" %> +
  • diff --git a/app/views/shixuns/add_script.js.erb b/app/views/shixuns/add_script.js.erb new file mode 100644 index 000000000..1ea38dc5a --- /dev/null +++ b/app/views/shixuns/add_script.js.erb @@ -0,0 +1,2 @@ +$("#training_project_exec_tip").html('<%= escape_javascript(render :partial => 'shixuns/training_project_exec_tip') %>'); +$("#training_project_filter_tip").html('<%= escape_javascript(render :partial => 'projects/settings/training_projects_filter_tip') %>'); \ No newline at end of file diff --git a/app/views/shixuns/settings.html.erb b/app/views/shixuns/settings.html.erb new file mode 100644 index 000000000..316e5d087 --- /dev/null +++ b/app/views/shixuns/settings.html.erb @@ -0,0 +1,62 @@ +
    +
    + +
    +
    +
    + <%= render :partial=>"shixuns/settings_edit" %> +
    +
    + <%= render :partial=>"shixuns/settings_repository" %> +
    + +
    + <%= render :partial=>"shixuns/settings_challenges" %> +
    +
    +
    + + + diff --git a/config/routes.rb b/config/routes.rb index 8e916a794..02b0ef097 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,11 +30,19 @@ RedmineApp::Application.routes.draw do resources :shixuns do member do - + post 'add_script' + get 'settings(/:tab)', :action => 'settings', :as => 'settings' + get 'shixun_job_create' + get 'shixun_job_update' + get 'rep_tree_changes', :action => 'rep_tree_changes', :as => 'rep_tree_changes' end collection do + end - + resources :repositories, :shallow => true, :except => [:index, :show] do + member do + match 'committers', :via => [:get, :post] + end end end @@ -1163,6 +1171,9 @@ RedmineApp::Application.routes.draw do get 'projects/:id/repository/:repository_id/graph', :to => 'repositories#graph' get 'projects/:id/repository/:repository_id/changes(/*path(.:ext))', :to => 'repositories#changes' + # shixun + get 'shixuns/:id/repository/:repository_id/commits(/*path(.:ext))', :to => 'repositories#commits' + get 'shixuns/:id/repository/:repository_id/commits/:changeset_id', :to => 'repositories#commits' get 'projects/:id/repository/:repository_id/revisions/:rev', :to => 'repositories#revision' get 'projects/:id/repository/:repository_id/revision', :to => 'repositories#revision' @@ -1209,6 +1220,9 @@ RedmineApp::Application.routes.draw do :action => /(browse|show|entry|raw|changes|annotate|diff|commit_diff)/ get 'projects/:id/repository/:repository_id', :to => 'repositories#show', :path => nil + # shixun + get 'shixuns/:id/repository/:repository_id', :to => 'repositories#shixun_show', :path => nil + # get 'projects/:id/repository', :to => 'repositories#show', :path => nil get 'projects/:id/exit', :to => 'projects#exit_project', :as => 'exit_cur_project' diff --git a/db/migrate/20170302094330_add_shixun_id_to_repositories.rb b/db/migrate/20170302094330_add_shixun_id_to_repositories.rb new file mode 100644 index 000000000..a06b6eef3 --- /dev/null +++ b/db/migrate/20170302094330_add_shixun_id_to_repositories.rb @@ -0,0 +1,5 @@ +class AddShixunIdToRepositories < ActiveRecord::Migration + def change + add_column :repositories, :shixun_id, :integer + end +end diff --git a/db/migrate/20170303071513_add_changeset_num_to_shixun.rb b/db/migrate/20170303071513_add_changeset_num_to_shixun.rb new file mode 100644 index 000000000..08e4d7377 --- /dev/null +++ b/db/migrate/20170303071513_add_changeset_num_to_shixun.rb @@ -0,0 +1,5 @@ +class AddChangesetNumToShixun < ActiveRecord::Migration + def change + add_column :shixuns, :changeset_num, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index adad92153..93730c693 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20170302032957) do +ActiveRecord::Schema.define(:version => 20170303071513) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -1915,6 +1915,7 @@ ActiveRecord::Schema.define(:version => 20170302032957) do t.string "identifier" t.boolean "is_default", :default => false t.boolean "hidden", :default => false + t.integer "shixun_id" end add_index "repositories", ["project_id"], :name => "index_repositories_on_project_id" @@ -2031,14 +2032,15 @@ ActiveRecord::Schema.define(:version => 20170302032957) do t.string "name" t.text "description" t.text "script" - t.boolean "is_public", :default => true + t.boolean "is_public", :default => true t.integer "parent_id" t.integer "user_id" t.integer "gpid" - t.integer "forked_count", :default => 0 - t.integer "visits", :default => 0 - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.integer "forked_count", :default => 0 + t.integer "visits", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "changeset_num" end create_table "softapplications", :force => true do |t| diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb index 2dd520b92..f2459ad5f 100644 --- a/lib/redmine/scm/adapters/abstract_adapter.rb +++ b/lib/redmine/scm/adapters/abstract_adapter.rb @@ -80,7 +80,7 @@ module Redmine end def initialize(url, root_url=nil, login=nil, password=nil, - path_encoding=nil, project_id) + path_encoding=nil, project_id, shixun_id) @url = url @login = login if login && !login.empty? @password = (password || "") if @login diff --git a/lib/redmine/scm/adapters/gitlab_adapter.rb b/lib/redmine/scm/adapters/gitlab_adapter.rb index 4aaf8fc91..91ef1ae34 100644 --- a/lib/redmine/scm/adapters/gitlab_adapter.rb +++ b/lib/redmine/scm/adapters/gitlab_adapter.rb @@ -13,11 +13,17 @@ module Redmine attr_accessor :is_default end - def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil, project_id) + def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil, project_id, shixun_id) super @g = Gitlab.client - r = Repository.where("url =? and project_id =?", url, project_id).first - @project = r.project.gpid + # shixun project + if project_id == -1 + r = Repository.where("url =? and shixun_id =?", url, shixun_id).first + @shixun = r.shixun.gpid + else + r = Repository.where("url =? and project_id =?", url, project_id).first + @project = r.project.gpid + end # @project = Repository.find_by_url(url).project.gpid @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding end @@ -89,7 +95,11 @@ module Redmine def entries(path=nil, identifier=nil, options={}) entries = Entries.new - trees = @g.trees(@project, path: path, ref_name: identifier) + if @project + trees = @g.trees(@project, path: path, ref_name: identifier) + else + trees = @g.trees(@shixun, path: path, ref_name: identifier) + end trees.each do |tree| entries << Entry.new({ :name => tree.name, diff --git a/lib/trustie/gitlab/helper.rb b/lib/trustie/gitlab/helper.rb index 615bb6ac3..366cdff13 100644 --- a/lib/trustie/gitlab/helper.rb +++ b/lib/trustie/gitlab/helper.rb @@ -71,6 +71,19 @@ module Trustie end end + def shixun_gitlab_role m + case m + when 3 + REPORTER + when 2 + DEVELOPER + when 1 + MASTER + else + GUEST + end + end + end end end \ No newline at end of file diff --git a/lib/trustie/gitlab/sync.rb b/lib/trustie/gitlab/sync.rb index 21c3bce47..140609ac3 100644 --- a/lib/trustie/gitlab/sync.rb +++ b/lib/trustie/gitlab/sync.rb @@ -68,6 +68,41 @@ module Trustie end end + def create_shixun(shixun, repository) + gid = shixun.owner.gid + unless gid + gid = sync_user(shixun.owner).id + end + raise "unknow gid" unless gid + + gshixun = g.create_project(repository.identifier, + path: repository.identifier, + description: false, + wiki_enabled: false, + wall_enabled: false, + issues_enabled: false, + snippets_enabled: false, + public: false, + user_id: gid, + visibility_level: shixun.is_public? ? UserLevel::PUBLIC : UserLevel::PRIVATE + ) + shixun.gpid = gshixun.id + shixun.save! + + # 创建的时候一并同步成员及角色 + shixun.shixun_members.each do |m| + begin + gid = m.user.gid + unless gid + gid = sync_user(m.user).id + end + self.g.add_team_member(gshixun.id, gid, shixun_gitlab_role(m.role)) + rescue => e + puts e + end + end + end + def sync_project(project, opt={}) gid = project.owner.gid unless gid diff --git a/spec/controllers/codes_controller_spec.rb b/spec/controllers/codes_controller_spec.rb new file mode 100644 index 000000000..2218047cf --- /dev/null +++ b/spec/controllers/codes_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe CodesController, :type => :controller do + +end