From 507d2cfeca7efd8569130c02c2cc72ddabb4bb8d Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 7 Nov 2024 16:46:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E:=20compare=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E5=88=97=E8=A1=A8=E6=8B=86=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/projects/compare_controller.rb | 58 +++++++++++++++++++ .../_simple_gitea_commit.json.jbuilder | 12 ++++ .../v1/projects/compare/files.json.jbuilder | 21 +++++++ config/routes/api.rb | 5 ++ 4 files changed, 96 insertions(+) create mode 100644 app/controllers/api/v1/projects/compare_controller.rb create mode 100644 app/views/api/v1/projects/compare/_simple_gitea_commit.json.jbuilder create mode 100644 app/views/api/v1/projects/compare/files.json.jbuilder diff --git a/app/controllers/api/v1/projects/compare_controller.rb b/app/controllers/api/v1/projects/compare_controller.rb new file mode 100644 index 000000000..82594eb28 --- /dev/null +++ b/app/controllers/api/v1/projects/compare_controller.rb @@ -0,0 +1,58 @@ +class Api::V1::Projects::CompareController < Api::V1::BaseController + + before_action :require_public_and_member_above, only: [:files] + + def files + load_compare_params + if params[:type] == "sha" + @compare_result ||= gitea_compare_files(@base, @head) + else + @compare_result ||= @head.include?(":") ? gitea_compare_files(@base, @head) : gitea_compare_files(@head, @base) + @merge_status, @merge_message = get_merge_message + end + end + + private + def load_compare_params + @base = params[:base].include?(":") ? Addressable::URI.unescape(params[:base].split(":")[0]) + ':' + Base64.decode64(params[:base].split(":")[1]) : Base64.decode64(params[:base]) + @head = params[:head].include?(":") ? Addressable::URI.unescape(params[:head].split(":")[0]) + ':' + Base64.decode64(params[:head].split(":")[1]) : Base64.decode64(params[:head]) + end + + def gitea_compare_files(base, head) + if params[:filepath].present? + $gitea_hat_client.get_repos_compare_files_by_owner_repo_baseref_headref_filepath(@project&.owner&.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), params[:filepath], {query: {token: current_user&.gitea_token}}) + else + $gitea_hat_client.get_repos_compare_files_by_owner_repo_baseref_headref(@project&.owner&.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), {query: {token: current_user&.gitea_token}}) + end + end + + def get_merge_message + if @base.blank? || @head.blank? + return -2, "请选择分支" + else + return -2, "目标仓库未开启合并请求(PR)功能" unless @project.has_menu_permission("pulls") + if @head.include?(":") + fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take + return -2, "请选择正确的仓库" unless fork_project.present? + @exist_pullrequest = @project.pull_requests.where(is_original: true, head: @head.to_s.split(":")[1], base: @base, status: 0, fork_project_id: fork_project.id).take + else + @exist_pullrequest = @project.pull_requests.where(is_original: false, head: @base, base: @head, status: 0).take + end + if @exist_pullrequest.present? + return -2, "在这些分支之间的合并请求已存在:#{@exist_pullrequest.try(:title)}" + else + Rails.logger.info @compare_result + if params[:filepath].present? + if @compare_result["Commits"].blank? && @compare_result["Diff"].blank? + return -2, "分支内容相同,无需创建合并请求" + end + else + if @compare_result[:total_data].to_i < 1 + return -2, "分支内容相同,无需创建合并请求" + end + end + end + end + return 0, "可以合并" + end +end \ No newline at end of file diff --git a/app/views/api/v1/projects/compare/_simple_gitea_commit.json.jbuilder b/app/views/api/v1/projects/compare/_simple_gitea_commit.json.jbuilder new file mode 100644 index 000000000..400e9860c --- /dev/null +++ b/app/views/api/v1/projects/compare/_simple_gitea_commit.json.jbuilder @@ -0,0 +1,12 @@ +json.author do + json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] } +end + +json.committer do + json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] } +end +json.timestamp render_unix_time(commit['Committer']['When']) +json.time_from_now time_from_now(commit['Committer']['When']) +json.created_at render_format_time_with_date(commit['Committer']['When']) +json.message commit['CommitMessage'] +json.sha commit['Sha'] \ No newline at end of file diff --git a/app/views/api/v1/projects/compare/files.json.jbuilder b/app/views/api/v1/projects/compare/files.json.jbuilder new file mode 100644 index 000000000..54fc61218 --- /dev/null +++ b/app/views/api/v1/projects/compare/files.json.jbuilder @@ -0,0 +1,21 @@ +if params[:filepath].present? + json.commits_count @compare_result['CommitsCount'] + json.last_commit_sha @compare_result['LatestSha'] + json.commits @compare_result['Commits'] do |commit| + json.partial! 'api/v1/projects/compare/simple_gitea_commit', locals: { commit: commit} + end + json.diff do + if @compare_result['Diff'].present? + json.partial! "api/v1/projects/simple_gitea_diff_detail", diff: @compare_result['Diff'] + else + json.nil! + end + end +else + json.file_numbers @compare_result[:total_data].to_i + json.files @compare_result[:data] do |file| + json.partial! "api/v1/projects/simple_gitea_file", file: file + end +end +json.status @merge_status +json.message @merge_message \ No newline at end of file diff --git a/config/routes/api.rb b/config/routes/api.rb index 7f0a68ed6..4aaa4beab 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -167,6 +167,9 @@ defaults format: :json do post :save_yaml, on: :collection end resources :pulls, module: 'pulls' do + member do + get :files + end resources :versions, only: [:index] do member do get :diff @@ -197,6 +200,7 @@ defaults format: :json do resources :tags, param: :name, only: [:index, :show, :destroy] delete 'tags/*name', to: "tags#destroy", via: :all get 'tags/*name', to: "tags#show", via: :all + get '/compare/:base...:head/files' => 'compare#files', :constraints => { base: /.+/, head: /.+/ } resources :commits, only: [:index] do collection do @@ -210,6 +214,7 @@ defaults format: :json do end end get '/commits/:sha/diff', to: 'commits#diff' + get '/commits/:sha/files', to: 'commits#files' get '/git/blobs/:sha', to: 'git#blobs' get '/git/trees/:sha', to: 'git#trees'