* api/v1/repos/{owner}/{repo}/pulls/{number}/commits
* api/v1/repos/{owner}/{repo}/pulls/{number}/files
* api/v1/repos/{owner}/{repo}/compare/{base}...{head}
tags/v1.0.0
| @@ -2542,6 +2542,335 @@ http://localhost:3000/api//api/repositories/3868/delete_file | jq | |||
| ``` | |||
| --- | |||
| ### 获取pull request文件列表 | |||
| ``` | |||
| GET /api/:owner/:repo/pulls/:id/files.json | |||
| ``` | |||
| *示例* | |||
| ``` | |||
| curl -X GET \ | |||
| http://localhost:3000/api/Jason/repo/1/files.json | jq | |||
| ``` | |||
| *请求参数说明:* | |||
| |参数名|必选|类型|说明| | |||
| |-|-|-|-| | |||
| |owner |是|string |用户登录名 | | |||
| |repo |是|string |project's identifier | | |||
| |id |是|int |pull request's id | | |||
| *返回参数说明:* | |||
| |参数名|类型|说明| | |||
| |-|-|-| | |||
| |files_count |int|文件更改的总数量| | |||
| |total_addition |int|添加代码总行数| | |||
| |total_deletion |int|删除代码总行数| | |||
| |files |array|| | |||
| |-- name |string|当前文件名| | |||
| |-- old_name |string| 修改之前的文件名称,与name相同的话,说明文件名未更改| | |||
| |-- addition |int|文件添加的行数| | |||
| |-- deletion |int|文件删除的行数| | |||
| |-- type |int|文件类型, 1: 表示该文件只添加了内容,2: 表示该文件内容有修改, 3: 表示文件被删除或者改文件只删除了内容| | |||
| |-- isCreated |boolean|当前文件是否为新增文件, true: 是, false: 否| | |||
| |-- isDeleted |boolean|当前文件是否被删除, true: 是,false: 否| | |||
| |-- isBin |boolean|当前文件是否为二进制文件,true: 是,false: 否| | |||
| |-- isLFSFile |boolean|当前文件是否为LFS文件,true: 是,false: 否| | |||
| |-- isRenamed |boolean|当前文件是否被重命名,true: 是,false: 否| | |||
| |-- sections |array|| | |||
| |---- fileName |string|文件名称| | |||
| |---- lines |array|| | |||
| |------ leftIdx |string|文件变动之前所在行数| | |||
| |------ rightIdx |string|文件更改后所在行数| | |||
| |------ type |string|文件变更类型,1: 新增,2: 修改, 3: 删除, 4: diff统计信息| | |||
| |------ content |string|文件变更的内容| | |||
| |------ sectionInfo |object|| | |||
| |-------- path |string|文件相对仓库的路径| | |||
| |-------- lastLeftIdx |int|| | |||
| |-------- lastRightIdx |int|| | |||
| |-------- leftHunkSize |int|文件变更之前的行数| | |||
| |-------- rightHunkSize |int|文件变更之后的行数(及当前页面编辑器显示的总行数)| | |||
| |-------- leftIdx |int|文件变更之前所在行数| | |||
| |-------- rightIdx |int|文件变更之后所在行数(即:页面编辑器开始显示的行数)| | |||
| 返回值 | |||
| ```json | |||
| { | |||
| "files_count": 6, | |||
| "total_addition": 447, | |||
| "total_deletion": 0, | |||
| "files": [ | |||
| { | |||
| "name": "文件.txt", | |||
| "old_name": "文件.txt", | |||
| "index": 6, | |||
| "addition": 2, | |||
| "deletion": 0, | |||
| "type": 1, | |||
| "isCreated": true, | |||
| "isDeleted": false, | |||
| "isBin": false, | |||
| "isLFSFile": false, | |||
| "isRenamed": false, | |||
| "isSubmodule": false, | |||
| "sections": [ | |||
| { | |||
| "fileName": "文件.txt", | |||
| "name": "", | |||
| "lines": [ | |||
| { | |||
| "leftIdx": 0, | |||
| "rightIdx": 0, | |||
| "type": 4, | |||
| "content": "@@ -0,0 +1,2 @@", | |||
| "sectionInfo": { | |||
| "path": null, | |||
| "lastLeftIdx": null, | |||
| "lastRightIdx": null, | |||
| "leftIdx": 0, | |||
| "rightIdx": 0, | |||
| "leftHunkSize": null, | |||
| "rightHunkSize": null | |||
| } | |||
| }, | |||
| { | |||
| "leftIdx": 0, | |||
| "rightIdx": 1, | |||
| "type": 2, | |||
| "content": "+用例图一致性更新", | |||
| "sectionInfo": null | |||
| }, | |||
| { | |||
| "leftIdx": 0, | |||
| "rightIdx": 2, | |||
| "type": 2, | |||
| "content": "+工程文件直接上传会有文件缺失,现在压缩后上传", | |||
| "sectionInfo": null | |||
| } | |||
| ] | |||
| } | |||
| ] | |||
| } | |||
| ] | |||
| } | |||
| ``` | |||
| --- | |||
| ### 获取pull request的commits列表 | |||
| ``` | |||
| GET /api/:owner/:repo/pulls/:id/commits.json | |||
| ``` | |||
| *示例* | |||
| ``` | |||
| curl -X GET \ | |||
| http://localhost:3000/api/Jason/repo/1/commits.json | jq | |||
| ``` | |||
| *请求参数说明:* | |||
| |参数名|必选|类型|说明| | |||
| |-|-|-|-| | |||
| |owner |是|string |用户登录名 | | |||
| |repo |是|string |project's identifier | | |||
| |id |是|int |pull request's id | | |||
| *返回参数说明:* | |||
| |参数名|类型|说明| | |||
| |-|-|-| | |||
| |commits_count |int|commits总数量| | |||
| |commits |array|| | |||
| |-- author |object|项目作者| | |||
| |---- login |string|用户login| | |||
| |---- name |string|用户姓名| | |||
| |---- image_url |string|用户头像| | |||
| |-- committer |object|commit提交用户| | |||
| |---- login |string|用户login| | |||
| |---- name |string|用户姓名| | |||
| |---- image_url |string|用户头像| | |||
| |-- timestamp |int|commit的unix时间戳| | |||
| |-- time_from_now|string|commit’s 提交时间距当前时间的时间值| | |||
| |-- message |string|commit说明信息| | |||
| |-- sha |string|commit’s sha值| | |||
| 返回值 | |||
| ```json | |||
| { | |||
| "commits_count": 1, | |||
| "commits": [ | |||
| { | |||
| "author": { | |||
| "id": 36480, | |||
| "login": "jasder", | |||
| "name": "段甲生", | |||
| "image_url": "avatars/User/b" | |||
| }, | |||
| "committer": { | |||
| "id": 36480, | |||
| "login": "jasder", | |||
| "name": "段甲生", | |||
| "image_url": "avatars/User/b" | |||
| }, | |||
| "timestamp": 1604382982, | |||
| "time_from_now": "3小时前", | |||
| "message": "add some file\n* Add the tag list page to the release page\n* Apply suggestions from code review\n* Add the tags list view\n* Add the delete tag way on ui\n* Not delete tag and clear message when delete a release\n", | |||
| "sha": "8f5faee0d3b3be1b8063e84da0c79dd75327b968" | |||
| } | |||
| ] | |||
| } | |||
| ``` | |||
| --- | |||
| ### compare two commits | |||
| ``` | |||
| GET /api/:owner/:repo/compare/{base}...{head}.json | |||
| ``` | |||
| *示例* | |||
| ``` | |||
| curl -X GET \ | |||
| http://localhost:3003/api/v1/repos/Jason/test-txt/compare/master...develop | jq | |||
| curl -X GET \ | |||
| http://localhost:3003/api/v1/repos/jasder/test-txt/compare/master...Jason/test-txt:develop | |||
| ``` | |||
| *请求参数说明:* | |||
| |参数名|必选|类型|说明| | |||
| |-|-|-|-| | |||
| |owner |是|string |用户登录名 | | |||
| |repo |是|string |project's identifier | | |||
| |base |是|string |pull request's id | | |||
| |head |是|string |pull request's id | | |||
| *返回参数说明:* | |||
| |参数名|类型|说明| | |||
| |-|-|-| | |||
| |commits_count |int|commits总数量| | |||
| |commits |array|| | |||
| |-- author |object|项目作者| | |||
| |---- login |string|用户login| | |||
| |---- name |string|用户姓名| | |||
| |---- image_url |string|用户头像| | |||
| |-- committer |object|commit提交用户| | |||
| |---- login |string|用户login| | |||
| |---- name |string|用户姓名| | |||
| |---- image_url |string|用户头像| | |||
| |-- timestamp |int|commit的unix时间戳| | |||
| |-- time_from_now|string|commit’s 提交时间距当前时间的时间值| | |||
| |-- message |string|commit说明信息| | |||
| |-- sha |string|commit’s sha值| | |||
| |diff |array|| | |||
| |-- files_count |int|文件更改的总数量| | |||
| |-- total_addition |int|添加代码总行数| | |||
| |-- total_deletion |int|删除代码总行数| | |||
| |-- name |string|当前文件名| | |||
| |-- old_name |string| 修改之前的文件名称,与name相同的话,说明文件名未更改| | |||
| |-- addition |int|文件添加的行数| | |||
| |-- deletion |int|文件删除的行数| | |||
| |-- type |int|文件类型, 1: 表示该文件只添加了内容,2: 表示该文件内容有修改, 3: 表示文件被删除或者改文件只删除了内容| | |||
| |-- isCreated |boolean|当前文件是否为新增文件, true: 是, false: 否| | |||
| |-- isDeleted |boolean|当前文件是否被删除, true: 是,false: 否| | |||
| |-- isBin |boolean|当前文件是否为二进制文件,true: 是,false: 否| | |||
| |-- isLFSFile |boolean|当前文件是否为LFS文件,true: 是,false: 否| | |||
| |-- isRenamed |boolean|当前文件是否被重命名,true: 是,false: 否| | |||
| |-- sections |array|| | |||
| |---- fileName |string|文件名称| | |||
| |---- lines |array|| | |||
| |------ leftIdx |string|文件变动之前所在行数| | |||
| |------ rightIdx |string|文件更改后所在行数| | |||
| |------ type |string|文件变更类型,1: 新增,2: 修改, 3: 删除, 4: diff统计信息| | |||
| |------ content |string|文件变更的内容| | |||
| |------ sectionInfo |object|| | |||
| |-------- path |string|文件相对仓库的路径| | |||
| |-------- lastLeftIdx |int|| | |||
| |-------- lastRightIdx |int|| | |||
| |-------- leftHunkSize |int|文件变更之前的行数| | |||
| |-------- rightHunkSize |int|文件变更之后的行数(及当前页面编辑器显示的总行数)| | |||
| |-------- leftIdx |int|文件变更之前所在行数| | |||
| |-------- rightIdx |int|文件变更之后所在行数(即:页面编辑器开始显示的行数)| | |||
| 返回值 | |||
| ```json | |||
| { | |||
| "commits_count": 1, | |||
| "commits": [ | |||
| { | |||
| "author": { | |||
| "id": 36480, | |||
| "login": "jasder", | |||
| "name": "段甲生", | |||
| "image_url": "avatars/User/b" | |||
| }, | |||
| "committer": { | |||
| "id": 36480, | |||
| "login": "jasder", | |||
| "name": "段甲生", | |||
| "image_url": "avatars/User/b" | |||
| }, | |||
| "timestamp": 1604382982, | |||
| "time_from_now": "4小时前", | |||
| "message": "add some file\n* Add the tag list page to the release page\n* Apply suggestions from code review\n* Add the tags list view\n* Add the delete tag way on ui\n* Not delete tag and clear message when delete a release\n", | |||
| "sha": "8f5faee0d3b3be1b8063e84da0c79dd75327b968" | |||
| } | |||
| ], | |||
| "diff": { | |||
| "files_count": 6, | |||
| "total_addition": 447, | |||
| "total_deletion": 0, | |||
| "files": [ | |||
| { | |||
| "name": "build.go", | |||
| "old_name": "build.go", | |||
| "index": 1, | |||
| "addition": 33, | |||
| "deletion": 0, | |||
| "type": 1, | |||
| "isCreated": true, | |||
| "isDeleted": false, | |||
| "isBin": false, | |||
| "isLFSFile": false, | |||
| "isRenamed": false, | |||
| "isSubmodule": false, | |||
| "sections": [ | |||
| { | |||
| "fileName": "build.go", | |||
| "name": "", | |||
| "lines": [ | |||
| { | |||
| "leftIdx": 0, | |||
| "rightIdx": 0, | |||
| "type": 4, | |||
| "content": "@@ -0,0 +1,33 @@", | |||
| "sectionInfo": { | |||
| "path": "build.go", | |||
| "lastLeftIdx": 0, | |||
| "lastRightIdx": 0, | |||
| "leftIdx": 0, | |||
| "rightIdx": 1, | |||
| "leftHunkSize": 0, | |||
| "rightHunkSize": 33 | |||
| } | |||
| }, | |||
| { | |||
| "leftIdx": 0, | |||
| "rightIdx": 1, | |||
| "type": 2, | |||
| "content": "+// Copyright 2020 The Gitea Authors. All rights reserved.", | |||
| "sectionInfo": null | |||
| } | |||
| ] | |||
| } | |||
| ] | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| ``` | |||
| --- | |||
| ### DevOps相关api | |||
| @@ -759,7 +759,7 @@ class ApplicationController < ActionController::Base | |||
| end | |||
| def load_repository | |||
| @repository ||= load_project.repository | |||
| @repository ||= load_project&.repository | |||
| end | |||
| private | |||
| @@ -0,0 +1,15 @@ | |||
| class CompareController < ApplicationController | |||
| # skip_before_action :require_login | |||
| before_action :load_repository | |||
| def index | |||
| end | |||
| def show | |||
| base_ref = Addressable::URI.unescape(params[:base]) | |||
| @ref = head_ref = Addressable::URI.unescape(params[:head]) | |||
| @compare_result = Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base_ref, head_ref) | |||
| # render json: @compare_result | |||
| end | |||
| end | |||
| @@ -1,9 +1,8 @@ | |||
| class PullRequestsController < ApplicationController | |||
| before_action :require_login, except: [:index, :show] | |||
| before_action :require_login, except: [:index, :show, :files, :commits] | |||
| before_action :load_repository | |||
| before_action :set_user, only: [:new, :get_branches] | |||
| before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos] | |||
| # before_action :get_relatived, only: [:edit] | |||
| before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits] | |||
| before_action :load_pull_request, only: [:files, :commits] | |||
| include TagChosenHelper | |||
| include ApplicationHelper | |||
| @@ -24,11 +23,11 @@ class PullRequestsController < ApplicationController | |||
| end | |||
| def new | |||
| @all_branches = PullRequests::BranchesService.new(@user, @project).call | |||
| @all_branches = PullRequests::BranchesService.new(@owner, @project).call | |||
| @is_fork = @project.forked_from_project_id.present? | |||
| @projects_names = [{ | |||
| project_user_login: @user.try(:login), | |||
| project_name: "#{@user.try(:show_real_name)}/#{@repository.try(:identifier)}", | |||
| project_user_login: @owner.try(:login), | |||
| project_name: "#{@owner.try(:show_real_name)}/#{@repository.try(:identifier)}", | |||
| project_id: @project.identifier, | |||
| id: @project.id | |||
| }] | |||
| @@ -45,7 +44,7 @@ class PullRequestsController < ApplicationController | |||
| end | |||
| def get_branches | |||
| branch_result = PullRequests::BranchesService.new(@user, @project).call | |||
| branch_result = PullRequests::BranchesService.new(@owner, @project).call | |||
| render json: branch_result | |||
| # return json: branch_result | |||
| end | |||
| @@ -235,16 +234,19 @@ class PullRequestsController < ApplicationController | |||
| end | |||
| private | |||
| def set_user | |||
| @user = @project.owner | |||
| def files | |||
| @files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gpid) | |||
| # render json: @files_result | |||
| end | |||
| def commits | |||
| @commits_result = Gitea::PullRequest::CommitsService.call(@owner.login, @project.identifier, @pull_request.gpid) | |||
| # render json: @commits_result | |||
| end | |||
| def set_repository | |||
| @repository = @project.repository | |||
| @user = @project.owner | |||
| normal_status(-1, "仓库不存在") unless @repository.present? | |||
| normal_status(-1, "用户不存在") unless @user.present? | |||
| private | |||
| def load_pull_request | |||
| @pull_request = PullRequest.find params[:id] | |||
| end | |||
| def find_pull_request | |||
| @@ -0,0 +1,2 @@ | |||
| module CompareHelper | |||
| end | |||
| @@ -0,0 +1,40 @@ | |||
| # List commits on a pull request | |||
| class Gitea::PullRequest::CommitsService < Gitea::ClientService | |||
| attr_reader :owner, :repo, :pull_number, :token | |||
| # GET /repos/{owner}/{repo}/pulls/{pull_number}/commits | |||
| # owner: 用户 | |||
| # repo: 仓库名称/标识 | |||
| # pull_number: pull request主键id | |||
| # eg: | |||
| # Gitea::PullRequest::FilesService.call('jasder', 'repo_identifier', 1) | |||
| def initialize(owner, repo, pull_number, token=nil) | |||
| @owner = owner | |||
| @repo = repo | |||
| @token = token | |||
| @pull_number = pull_number | |||
| end | |||
| def call | |||
| response = get(url, params) | |||
| render_result(response) | |||
| end | |||
| private | |||
| def params | |||
| Hash.new.merge(token: owner) | |||
| end | |||
| def url | |||
| "/repos/#{owner}/#{repo}/pulls/#{pull_number}/commits".freeze | |||
| end | |||
| def render_result(response) | |||
| case response.status | |||
| when 200 | |||
| JSON.parse(response.body) | |||
| else | |||
| nil | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,40 @@ | |||
| # List pull requests files | |||
| class Gitea::PullRequest::FilesService < Gitea::ClientService | |||
| attr_reader :owner, :repo, :pull_number, :token | |||
| # GET /repos/{owner}/{repo}/pulls/{pull_number}/files | |||
| # owner: 用户 | |||
| # repo: 仓库名称/标识 | |||
| # pull_number: pull request主键id | |||
| # eg: | |||
| # Gitea::PullRequest::FilesService.call('jasder', 'repo_identifier', 1) | |||
| def initialize(owner, repo, pull_number, token=nil) | |||
| @owner = owner | |||
| @repo = repo | |||
| @token = token | |||
| @pull_number = pull_number | |||
| end | |||
| def call | |||
| response = get(url, params) | |||
| render_result(response) | |||
| end | |||
| private | |||
| def params | |||
| Hash.new.merge(token: token) | |||
| end | |||
| def url | |||
| "/repos/#{owner}/#{repo}/pulls/#{pull_number}/files".freeze | |||
| end | |||
| def render_result(response) | |||
| case response.status | |||
| when 200 | |||
| JSON.parse(response.body) | |||
| else | |||
| nil | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,38 @@ | |||
| # Compare two commits | |||
| class Gitea::Repository::Commits::CompareService < Gitea::ClientService | |||
| attr_reader :owner, :repo, :base, :head, :token | |||
| # sha: the commit hash | |||
| # ex: | |||
| # Gitea::Repository::Commits::CompareService.call('owner', 'repo_identifier', 'master', 'jasder/repo_identifier:develop') | |||
| def initialize(owner, repo, base, head, token=nil) | |||
| @token = token | |||
| @owner = owner | |||
| @base = base | |||
| @repo = repo | |||
| @head = head | |||
| end | |||
| def call | |||
| response = get(url, params) | |||
| render_result(response) | |||
| end | |||
| private | |||
| def params | |||
| Hash.new.merge(token: token) | |||
| end | |||
| def url | |||
| "/repos/#{owner}/#{repo}/compare/#{base}...#{head}".freeze | |||
| end | |||
| def render_result(response) | |||
| case response.status | |||
| when 200 | |||
| JSON.parse(response.body) | |||
| else | |||
| {status: -1, message: "#{body['message']}"} | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,9 @@ | |||
| json.commits_count @compare_result['Commits']&.size | |||
| json.commits @compare_result['Commits'], partial: 'pull_requests/commit', as: :commit | |||
| json.diff do | |||
| json.files_count @compare_result['Diff']['NumFiles'] | |||
| json.total_addition @compare_result['Diff']['TotalAddition'] | |||
| json.total_deletion @compare_result['Diff']['TotalDeletion'] | |||
| json.files @compare_result['Diff']['Files'], partial: 'pull_requests/diff_file', as: :file | |||
| end | |||
| @@ -0,0 +1,13 @@ | |||
| json.author do | |||
| author = User.find_by(login: commit['Author']['Name']) | |||
| json.partial! 'repositories/commit_author', locals: { user: author } | |||
| end | |||
| json.committer do | |||
| author = User.find_by(login: commit['Committer']['Name']) | |||
| json.partial! 'repositories/commit_author', locals: { user: author } | |||
| end | |||
| json.timestamp render_unix_time(commit['Committer']['When']) | |||
| json.time_from_now time_from_now(commit['Committer']['When']) | |||
| json.message commit['CommitMessage'] | |||
| json.sha commit['Sha'] | |||
| @@ -0,0 +1,40 @@ | |||
| json.name file['Name'] | |||
| json.old_name file['OldName'] | |||
| json.index file['Index'] | |||
| json.addition file['Addition'] | |||
| json.deletion file['Deletion'] | |||
| json.type file['Type'] | |||
| json.isCreated file['IsCreated'] | |||
| json.isDeleted file['IsDeleted'] | |||
| json.isBin file['IsBin'] | |||
| json.isLFSFile file['IsLFSFile'] | |||
| json.isRenamed file['IsRenamed'] | |||
| json.isSubmodule file['IsSubmodule'] | |||
| json.isLFSFile file['IsLFSFile'] | |||
| json.sections do | |||
| json.array! file['Sections'] do |section| | |||
| json.fileName section['FileName'] | |||
| json.name section['Name'] | |||
| json.lines do | |||
| json.array! section['Lines'] do |line| | |||
| json.leftIdx line['LeftIdx'] | |||
| json.rightIdx line['RightIdx'] | |||
| json.type line['Type'] | |||
| json.content line['Content'] | |||
| json.sectionInfo do | |||
| if line['SectionInfo'].blank? | |||
| json.nil! | |||
| else | |||
| json.path line['SectionInfo']['Path'] | |||
| json.lastLeftIdx line['SectionInfo']['LastLeftIdx'] | |||
| json.lastRightIdx line['SectionInfo']['LastRightIdx'] | |||
| json.leftIdx line['SectionInfo']['LeftIdx'] | |||
| json.rightIdx line['SectionInfo']['RightIdx'] | |||
| json.leftHunkSize line['SectionInfo']['LeftHunkSize'] | |||
| json.rightHunkSize line['SectionInfo']['RightHunkSize'] | |||
| end | |||
| end | |||
| end | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,2 @@ | |||
| json.commits_count @commits_result.size | |||
| json.commits @commits_result, partial: 'commit', as: :commit | |||
| @@ -0,0 +1,4 @@ | |||
| json.files_count @files_result['NumFiles'] | |||
| json.total_addition @files_result['TotalAddition'] | |||
| json.total_deletion @files_result['TotalDeletion'] | |||
| json.files @files_result['Files'], partial: 'diff_file', as: :file | |||
| @@ -1,5 +1,5 @@ | |||
| Rails.application.routes.draw do | |||
| require 'sidekiq/web' | |||
| require 'admin_constraint' | |||
| @@ -337,11 +337,18 @@ Rails.application.routes.draw do | |||
| end | |||
| end | |||
| # compare | |||
| resources :compare, only: [:index, :create] | |||
| get '/compare/:base...:head' => 'compare#show', :as => 'compare', | |||
| :constraints => { base: /.+/, head: /.+/ } | |||
| resources :pull_requests, :path => :pulls, except: [:destroy] do | |||
| member do | |||
| post :pr_merge | |||
| # post :check_merge | |||
| post :refuse_merge | |||
| get :files | |||
| get :commits | |||
| end | |||
| collection do | |||
| post :check_can_merge | |||