diff --git a/app/controllers/api/v1/projects/commits_controller.rb b/app/controllers/api/v1/projects/commits_controller.rb new file mode 100644 index 00000000..1e6c17be --- /dev/null +++ b/app/controllers/api/v1/projects/commits_controller.rb @@ -0,0 +1,8 @@ +class Api::V1::Projects::CommitsController < Api::V1::BaseController + before_action :require_public_and_member_above, only: [:diff] + + def diff + @result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token) + puts @result_object + end +end \ No newline at end of file diff --git a/app/docs/slate/source/includes/_repositories.md b/app/docs/slate/source/includes/_repositories.md index 7da740ef..afd09932 100644 --- a/app/docs/slate/source/includes/_repositories.md +++ b/app/docs/slate/source/includes/_repositories.md @@ -1413,72 +1413,170 @@ await octokit.request('GET /api/v1/yystopf/csfjkkj/git/blobs/80dd40214a586223123 Success Data. -## 获取仓库贡献者 -获取仓库贡献者 +## 获取单个提交的blame信息 +根据commit ID获取blame信息 > 示例: ```shell -curl -X GET \ --d "ref=master" \ --d "filepath=lib" \ -http://localhost:3000/api/yystopf/csfjkkj/contributors.json +curl -X GET http://localhost:3000/api/v1/yystopf/csfjkkj/commits/80dd40214a58622312393b2ae693756a4781fab2/diff.json ``` ```javascript -await octokit.request('GET /api/yystopf/csfjkkj/contributors.json') +await octokit.request('GET /api/v1/yystopf/csfjkkj/commits/80dd40214a58622312393b2ae693756a4781fab2/diff.json') ``` ### HTTP 请求 -`GET /api/:owner/:repo/contributors.json` +`GET /api/v1/:owner/:repo/commits/:sha/diff.json` ### 请求参数: 参数 | 必选 | 默认 | 类型 | 字段说明 --------- | ------- | ------- | -------- | ---------- -|owner |是| |string |用户登录名 | -|repo |是| |string |项目标识identifier | -|ref |否| | string |分支名称、tag名称或是提交记录id,默认为整个仓库 | -|filepath |否| | string |子目录名称,默认为空 | - +|owner|是| | string |用户登录名 | +|repo |是| | string |项目标识identifier | +|sha |是| | string |提交记录id | ### 返回字段说明: 参数 | 类型 | 字段说明 --------- | ----------- | ----------- -|total_count |integer|贡献者数量| -|contributions |integer|贡献数量| -|login |string |用户登录名 | -|type |string|用户类型 | -|name |string|用户昵称| -|image_url |string|用户头像| +|file_nums|int|文件数量| +|total_addition|int|新增行数| +|total_deletion|int|删除行数| +|files.name|string|文件名称| +|files.oldname|string|文件修改前名称| +|files.addition|int|文件新增行数| +|files.deletion|int|文件删除行数| +|files.type|int|文件类型 1: 新增 2: 更改 3: 删除 4: 重命名 5: 复制| +|files.is_created|bool|是否为新建文件| +|files.is_deleted|bool|是否为删除文件| +|files.is_bin|bool|是否为二进制文件| +|files.is_lfs_file|bool|| +|files.is_renamed|bool|是否重命名| +|files.is_ambiguous|bool|| +|files.is_submodule|bool|是否为子模块| +|files.sections.file_name|string|文件名称| +|files.sections.name|string|| +|files.sections.lines.left_index|int|| +|files.sections.lines.right_index|int|| +|files.sections.lines.match|int|| +|files.sections.lines.type|int|| +|files.sections.lines.content|string|| +|files.sections.lines.section_path|string|| +|files.sections.lines.section_last_left_index|int|| +|files.sections.lines.section_last_right_index|int|| +|files.sections.lines.section_left_index|int|| +|files.sections.lines.section_right_index|int|| +|files.sections.lines.section_left_hunk_size|int|| +|files.sections.lines.section_right_hunk_size|int|| + > 返回的JSON示例: ```json { - "contributors": [ + "file_nums": 2, + "total_addition": 2, + "total_deletion": 2, + "files": [ { - "contributions": 5, - "login": "testforge2", - "type": "User", - "name": "testforge2", - "image_url": "system/lets/letter_avatars/2/T/236_177_85/120.png" + "name": "xinzeng3", + "oldname": "xinzeng3", + "addition": 1, + "deletion": 0, + "type": 1, + "is_created": true, + "is_deleted": false, + "is_bin": false, + "is_lfs_file": false, + "is_renamed": false, + "is_ambiguous": false, + "is_submodule": false, + "sections": [ + { + "file_name": "xinzeng3", + "name": "", + "lines": [ + { + "left_index": 0, + "right_index": 0, + "match": 0, + "type": 4, + "content": "@@ -0,0 +1 @@", + "section_path": "xinzeng3", + "section_last_left_index": 0, + "section_last_right_index": 0, + "section_left_index": 0, + "section_right_index": 1, + "section_left_hunk_size": 0, + "section_right_hunk_size": 0 + }, + { + "left_index": 0, + "right_index": 1, + "match": -1, + "type": 2, + "content": "+1111122222" + } + ] + } + ], + "is_incomplete": false, + "is_incomplete_line_too_long": false, + "is_protected": false }, { - "contributions": 79, - "login": "yystopf", - "type": "User", - "name": "yystopf", - "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png" + "name": "xinzeng4", + "oldname": "xinzeng4", + "addition": 1, + "deletion": 0, + "type": 1, + "is_created": true, + "is_deleted": false, + "is_bin": false, + "is_lfs_file": false, + "is_renamed": false, + "is_ambiguous": false, + "is_submodule": false, + "sections": [ + { + "file_name": "xinzeng4", + "name": "", + "lines": [ + { + "left_index": 0, + "right_index": 0, + "match": 0, + "type": 4, + "content": "@@ -0,0 +1 @@", + "section_path": "xinzeng4", + "section_last_left_index": 0, + "section_last_right_index": 0, + "section_left_index": 0, + "section_right_index": 1, + "section_left_hunk_size": 0, + "section_right_hunk_size": 0 + }, + { + "left_index": 0, + "right_index": 1, + "match": -1, + "type": 2, + "content": "+111112222" + } + ] + } + ], + "is_incomplete": false, + "is_incomplete_line_too_long": false, + "is_protected": false } - ], - "total_count": 2 + ] } ``` - ## 获取仓库webhooks列表 获取仓库webhooks列表 diff --git a/app/services/api/v1/projects/commits/diff_service.rb b/app/services/api/v1/projects/commits/diff_service.rb new file mode 100644 index 00000000..8b12fc31 --- /dev/null +++ b/app/services/api/v1/projects/commits/diff_service.rb @@ -0,0 +1,31 @@ +class Api::V1::Projects::Commits::DiffService < ApplicationService + attr_accessor :project, :sha, :token, :owner, :repo + attr_accessor :gitea_data + + def initialize(project, sha, token = nil) + @project = project + @sha = sha + @owner = project&.owner.login + @repo = project&.identifier + @token = token + end + + def call + load_gitea_data + + gitea_data + end + + private + def request_params + { + access_token: token + } + end + + def load_gitea_data + @gitea_data = $gitea_client.get_repos_commits_diff_by_owner_repo_sha(owner, repo, sha, {query: request_params}) + raise Error, '获取提交对比失败!' unless @gitea_data.is_a?(Hash) + end + +end \ No newline at end of file diff --git a/app/views/api/v1/projects/commits/diff.json.jbuilder b/app/views/api/v1/projects/commits/diff.json.jbuilder new file mode 100644 index 00000000..e0237369 --- /dev/null +++ b/app/views/api/v1/projects/commits/diff.json.jbuilder @@ -0,0 +1,40 @@ +json.file_nums @result_object['NumFiles'] +json.total_addition @result_object['TotalAddition'] +json.total_deletion @result_object['TotalAddition'] +json.files @result_object['Files'].each do |file| + json.name file['Name'] + json.oldname file['OldName'] + json.addition file['Addition'] + json.deletion file['Deletion'] + json.type file['Type'] + json.is_created file['IsCreated'] + json.is_deleted file['IsDeleted'] + json.is_bin file['IsBin'] + json.is_lfs_file file['IsLFSFile'] + json.is_renamed file['IsRenamed'] + json.is_ambiguous file['IsAmbiguous'] + json.is_submodule file['IsSubmodule'] + json.sections file['Sections'] do |section| + json.file_name section['FileName'] + json.name section['Name'] + json.lines section['Lines'] do |line| + json.left_index line['LeftIdx'] + json.right_index line['RightIdx'] + json.match line['Match'] + json.type line['Type'] + json.content line['Content'] + unless line['SectionInfo'].blank? + json.section_path line['SectionInfo']['Path'] + json.section_last_left_index line['SectionInfo']['LastLeftIdx'] + json.section_last_right_index line['SectionInfo']['LastRightIdx'] + json.section_left_index line['SectionInfo']['LeftIdx'] + json.section_right_index line['SectionInfo']['RightIdx'] + json.section_left_hunk_size line['SectionInfo']['LeftHunkSize'] + json.section_right_hunk_size line['SectionInfo']['RightHunkSize'] + end + end + end + json.is_incomplete file['IsIncomplete'] + json.is_incomplete_line_too_long file['IsIncompleteLineTooLong'] + json.is_protected file['IsProtected'] +end \ No newline at end of file diff --git a/config/routes/api.rb b/config/routes/api.rb index 99684e6d..78901696 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -28,6 +28,8 @@ defaults format: :json do get :all end end + + get '/commits/:sha/diff', to: 'commits#diff' get '/git/blobs/:sha', to: 'git#blobs' get '/git/trees/:sha', to: 'git#trees' end diff --git a/public/docs/api.html b/public/docs/api.html index 12875ff3..3302e2e2 100644 --- a/public/docs/api.html +++ b/public/docs/api.html @@ -554,7 +554,7 @@ 获取仓库blobs内容
  • - 获取仓库贡献者 + 获取单个提交的blame信息
  • 获取仓库webhooks列表 @@ -9682,19 +9682,16 @@ http://localhost:3000/api/v1/yystopf/csfjkkj/git/trees/80dd40214a58622312393b2ae -

    获取仓库贡献者

    -

    获取仓库贡献者

    +

    获取单个提交的blame信息

    +

    根据commit ID获取blame信息

    示例:

    -
    curl -X GET \
    --d "ref=master" \
    --d "filepath=lib" \
    -http://localhost:3000/api/yystopf/csfjkkj/contributors.json
    -
    await octokit.request('GET /api/yystopf/csfjkkj/contributors.json')
    +
    curl -X GET http://localhost:3000/api/v1/yystopf/csfjkkj/commits/80dd40214a58622312393b2ae693756a4781fab2/diff.json
    +
    await octokit.request('GET /api/v1/yystopf/csfjkkj/commits/80dd40214a58622312393b2ae693756a4781fab2/diff.json')
     

    HTTP 请求

    -

    GET /api/:owner/:repo/contributors.json

    +

    GET /api/v1/:owner/:repo/commits/:sha/diff.json

    请求参数:

    @@ -9720,18 +9717,11 @@ http://localhost:3000/api/yystopf/csfjkkj/contributors.json - - + + - - - - - - - - +
    项目标识identifier
    refsha string分支名称、tag名称或是提交记录id,默认为整个仓库
    filepathstring子目录名称,默认为空提交记录id

    返回字段说明:

    @@ -9743,34 +9733,149 @@ http://localhost:3000/api/yystopf/csfjkkj/contributors.json -total_count -integer -贡献者数量 +file_nums +int +文件数量 -contributions -integer -贡献数量 +total_addition +int +新增行数 -login +total_deletion +int +删除行数 + + +files.name string -用户登录名 +文件名称 -type +files.oldname string -用户类型 +文件修改前名称 -name -string -用户昵称 +files.addition +int +文件新增行数 -image_url +files.deletion +int +文件删除行数 + + +files.type +int +文件类型 1: 新增 2: 更改 3: 删除 4: 重命名 5: 复制 + + +files.is_created +bool +是否为新建文件 + + +files.is_deleted +bool +是否为删除文件 + + +files.is_bin +bool +是否为二进制文件 + + +files.is_lfs_file +bool + + + +files.is_renamed +bool +是否重命名 + + +files.is_ambiguous +bool + + + +files.is_submodule +bool +是否为子模块 + + +files.sections.file_name string -用户头像 +文件名称 + + +files.sections.name +string + + + +files.sections.lines.left_index +int + + + +files.sections.lines.right_index +int + + + +files.sections.lines.match +int + + + +files.sections.lines.type +int + + + +files.sections.lines.content +string + + + +files.sections.lines.section_path +string + + + +files.sections.lines.section_last_left_index +int + + + +files.sections.lines.section_last_right_index +int + + + +files.sections.lines.section_left_index +int + + + +files.sections.lines.section_right_index +int + + + +files.sections.lines.section_left_hunk_size +int + + + +files.sections.lines.section_right_hunk_size +int + @@ -9778,23 +9883,103 @@ http://localhost:3000/api/yystopf/csfjkkj/contributors.json

    返回的JSON示例:

    {
    -    "contributors": [
    +    "file_nums": 2,
    +    "total_addition": 2,
    +    "total_deletion": 2,
    +    "files": [
             {
    -            "contributions": 5,
    -            "login": "testforge2",
    -            "type": "User",
    -            "name": "testforge2",
    -            "image_url": "system/lets/letter_avatars/2/T/236_177_85/120.png"
    +            "name": "xinzeng3",
    +            "oldname": "xinzeng3",
    +            "addition": 1,
    +            "deletion": 0,
    +            "type": 1,
    +            "is_created": true,
    +            "is_deleted": false,
    +            "is_bin": false,
    +            "is_lfs_file": false,
    +            "is_renamed": false,
    +            "is_ambiguous": false,
    +            "is_submodule": false,
    +            "sections": [
    +                {
    +                    "file_name": "xinzeng3",
    +                    "name": "",
    +                    "lines": [
    +                        {
    +                            "left_index": 0,
    +                            "right_index": 0,
    +                            "match": 0,
    +                            "type": 4,
    +                            "content": "@@ -0,0 +1 @@",
    +                            "section_path": "xinzeng3",
    +                            "section_last_left_index": 0,
    +                            "section_last_right_index": 0,
    +                            "section_left_index": 0,
    +                            "section_right_index": 1,
    +                            "section_left_hunk_size": 0,
    +                            "section_right_hunk_size": 0
    +                        },
    +                        {
    +                            "left_index": 0,
    +                            "right_index": 1,
    +                            "match": -1,
    +                            "type": 2,
    +                            "content": "+1111122222"
    +                        }
    +                    ]
    +                }
    +            ],
    +            "is_incomplete": false,
    +            "is_incomplete_line_too_long": false,
    +            "is_protected": false
             },
             {
    -            "contributions": 79,
    -            "login": "yystopf",
    -            "type": "User",
    -            "name": "yystopf",
    -            "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
    +            "name": "xinzeng4",
    +            "oldname": "xinzeng4",
    +            "addition": 1,
    +            "deletion": 0,
    +            "type": 1,
    +            "is_created": true,
    +            "is_deleted": false,
    +            "is_bin": false,
    +            "is_lfs_file": false,
    +            "is_renamed": false,
    +            "is_ambiguous": false,
    +            "is_submodule": false,
    +            "sections": [
    +                {
    +                    "file_name": "xinzeng4",
    +                    "name": "",
    +                    "lines": [
    +                        {
    +                            "left_index": 0,
    +                            "right_index": 0,
    +                            "match": 0,
    +                            "type": 4,
    +                            "content": "@@ -0,0 +1 @@",
    +                            "section_path": "xinzeng4",
    +                            "section_last_left_index": 0,
    +                            "section_last_right_index": 0,
    +                            "section_left_index": 0,
    +                            "section_right_index": 1,
    +                            "section_left_hunk_size": 0,
    +                            "section_right_hunk_size": 0
    +                        },
    +                        {
    +                            "left_index": 0,
    +                            "right_index": 1,
    +                            "match": -1,
    +                            "type": 2,
    +                            "content": "+111112222"
    +                        }
    +                    ]
    +                }
    +            ],
    +            "is_incomplete": false,
    +            "is_incomplete_line_too_long": false,
    +            "is_protected": false
             }
    -    ],
    -    "total_count": 2
    +    ]
     }