web-dev-qa-db-ja.com

GithubAPIを介してGithubリポジトリからすべてのファイル名を取得します

GitHub APIを使用してリポジトリからすべてのファイル名を取得することは可能ですか?

私は現在、 PyGithub を使用してこれをいじくり回そうとしていますが、それが機能する限り、手動でリクエストを実行してもまったく問題ありません。

これまでの私のアルゴリズムは次のとおりです。

  1. ユーザーリポジトリ名を取得する
  2. 特定の説明に一致するユーザーリポジトリを取得します
  3. ???リポジトリファイル名を取得しますか?
16
Anton Antonov

一部のファイルは一部のコミットに存在し、他のコミットには存在しない可能性があるため、これは特定のコミットに関連している必要があります。したがって、ファイルを確認する前に、 List commitsonのようなものを使用する必要があります。リポジトリ

GET /repos/:owner/:repo/commits

ブランチでの最新のコミットに関心がある場合は、shaパラメーターをブランチ名に設定できます。

shastring SHAまたはブランチからコミットのリストを開始します。

コミットハッシュを取得したら、そのコミットを 検査できます

GET /repos/:owner/:repo/git/commits/:sha

これは次のようなものを返すはずです(GitHubのドキュメントから切り捨てられました):

{
  "sha": "...",
  "...",
  "tree": {
    "url": "https://api.github.com/repos/octocat/Hello-World/git/trees/691272480426f78a0138979dd3ce63b77f706feb",
    "sha": "691272480426f78a0138979dd3ce63b77f706feb"
  },
  "...": "..."
}

そのツリーのハッシュを見てください。これは本質的にそのディレクトリの内容です。この場合、 691272480426f78a0138979dd3ce63b77f706feb。これで、最終的に そのツリーの内容を要求できます

GET /repos/:owner/:repo/git/trees/:sha

GitHubの例からの出力は次のとおりです。

{
  "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312",
  "url": "https://api.github.com/repos/octocat/Hello-World/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312",
  "tree": [
    {
      "path": "file.rb",
      "mode": "100644",
      "type": "blob",
      "size": 30,
      "sha": "44b4fc6d56897b048c772eb4087f854f46256132",
      "url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132"
    },
    {
      "path": "subdir",
      "mode": "040000",
      "type": "tree",
      "sha": "f484d249c660418515fb01c2b9662073663c242e",
      "url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/f484d249c660418515fb01c2b9662073663c242e"
    },
    {
      "path": "exec_file",
      "mode": "100755",
      "type": "blob",
      "size": 75,
      "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
      "url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057"
    }
  ]
}

ご覧のとおり、ファイルに対応するいくつかのblobsと、サブディレクトリに対応するいくつかの追加のツリーがあります。これを再帰的に 実行することをお勧めします

25
Chris

Graphql apiを使用すると、はるかに簡単になり、1つのクエリですべてを取得できます。

最初にリポジトリを取得します。

query {
  repository(name: "MyRepo" owner: "mylogin"){

  }
}

次に、defaultBranchRefを取得して、作業を簡単にします

    defaultBranchRef{

    }

これで、すべてのブランチrefは実際にはコミットへのポインターにすぎず、graphqlは強く型付けされているため(refは異なるものになる可能性があります)、コミットであることを通知する必要があります。

   target{
      ...on Commit {

      }
   }

したがって、ターゲットは参照が指しているものであり、「コミットの場合はこれを実行する」と言います。

そしてそれは何をすべきですか?最新のコミットを取得する必要があります(リポジトリに最新のファイルがあるため)

そのために、履歴を照会します

        history(first: 1 until: "2019-10-08T00:00:00"){
            nodes{

            }
        }

nodesの内部になり、コミットの内部になり、ファイルを確認できるようになりました。コミットポインタ内のファイルは、実際にはツリーへのポインタにすぎず、ツリーにはエントリがあり、次のオブジェクトになります。 Treeと入力するか、blobと入力します

ファイルを表すエントリはblobと呼ばれますが、ファイルには何もせずに名前をリストするため、それを知る必要はありません。

ただし、ツリーはエントリでもあることを知っておくことが重要です。したがって、ツリーを見つけた場合は、さらに深く掘り下げる必要がありますが、事前に定義されたレベルの深さまでしか移動できません。

       tree{
           entries {
             name
             object {
               ...on Tree{
                 entries{
                   name
                   object {
                      ...on Tree{
                        entries{
                          name
                        }
                      }
                   }
                 }
               }
             }
           } 
       }

今それをすべてまとめるために:

query{
  repository(owner: "MyLogin", name: "MyRepo") {
    defaultBranchRef {
      target {
        ... on Commit {
          history(first: 1 until: "2019-10-08T00:00:00") {
            nodes {
              tree {
                entries {
                  name
                  object {
                    ... on Tree {
                      entries {
                        name
                        object{
                          ...on Tree{
                            entries{
                              name
                              object{
                                ...on Tree{
                                  entries{
                                    name
                                  }                                  
                                }
                              }
                            }   
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
3
Kyle Roux