shell 如何提取github仓库的提交页面总数

62lalag4  于 2023-08-07  发布在  Shell
关注(0)|答案(3)|浏览(99)

我正在设置一个脚本,用于导出所有提交和pull请求,以获得更大的github存储库列表(大约4000个)。
在脚本的基本思想工作之后,我需要一种方法来循环通过存储库的所有提交页面。
我发现我可以导出每页100个提交。对于一些repos有一些更多的提交(如8000),所以这将是80页,我需要循环通过。
我找不到从github API中提取页面数量的方法。
到目前为止,我所做的是设置脚本,它循环所有提交并将它们导出到txt / csv文件。
我需要做的是在开始循环一个repo的提交之前知道总页数。
这里给了我一个我不能使用它的方式的页数。

curl -u "user:password" -I https://api.github.com/repos/0chain/rocksdb/commits?per_page=100

字符串
结果:
友情链接:https://api.github.com/repositories/152923130/commits?per_page=100&page=2; rel=“next”,https://api.github.com/repositories/152923130/commits?per_page=100&page=75 ; rel=“last”
我需要将值75(或其他存储库中的任何其他值)用作循环中的变量。
像这样:

repolist=`cat repolist.txt`
repolistarray=($(echo $repolist))
repolength=$(echo "${#repolistarray[@]}")

for (( i = 0; i <= $repolength; i++ )); do
    #here i need to extract the pagenumber
    pagenumber=$(curl -u "user:password" -I https://api.github.com/repos/$(echo "${repolistarray[i]}")/commits?per_page=100)

    for (( n = 1; n <= $pagenumber; n++ )); do
        curl -u "user:password" -s https://api.github.com/repos/$(echo "${repolistarray[i]}")/commits?per_page=100&page$(echo "$n") >committest.txt
    done
done

done


我怎样才能得到“75”或任何其他结果了这一点
友情链接:https://api.github.com/repositories/152923130/commits?per_page=100&page=2; rel=“next”,https://api.github.com/repositories/152923130/commits?per_page=100&page=75 ; rel=“last”
被用作n

balp4ylt

balp4ylt1#

以下是@Poshi评论的内容:循环无限期地请求下一个页面,直到遇到空页面,然后跳出内部循环,继续下一个repo。

# this is the contents of a page past the last real page:
emptypage='[

]'

# here's a simpler way to iterate over each repo than using a bash array
cat repolist.txt | while read -d' ' repo; do

  # loop indefinitely
  page=0
  while true; do
    page=$((page + 1))

    # minor improvement: use a variable, not a file.
    # also, you don't need to echo variables, just use them
    result=$(curl -u "user:password" -s \ 
      "https://api.github.com/repos/$repo/commits?per_page=100&page=$n")

    # if the result is empty, break out of the inner loop
    [ "$result" = "$emptypage" ] && break

    echo "$result" > committest.txt
    # note that > overwrites (whereas >> appends),
    # so committest.txt will be overwritten with each new page.
    #
    # in the final version, you probably want to process the results here,
    # and then
    #
    #       echo "$processed_results"
    #     done > repo1.txt
    #   done
    #
    # to ouput once per repo, or
    #
    #       echo "$processed_results"
    #     done
    #   done > all_results.txt
    #
    # to output all results to a single file

  done
done

字符串

7gs2gvoe

7gs2gvoe2#

好吧,你要求的方法不是最常见的方法,通常它是通过获取页面直到没有更多的数据可用。但要回答您的具体问题,我们必须解析包含信息的行。一个快速而肮脏的方法可以做到这一点:

response="Link: https://api.github.com/repositories/152923130/commits?per_page=100&page=2; rel=\"next\", https://api.github.com/repositories/152923130/commits?per_page=100&page=75; rel=\"last\""

<<< "$response" cut -f2- -d: | # First, get the contents of "Link": everything after the first colon
tr "," $'\n' |      # Separate the different parts in different lines
grep 'rel="last"' | # Select the line with last page information
cut -f1 -d';' |     # Keep only the URL
tr "?&" $'\n' |     # Split URL and its parameters, one per line
grep -e "^page" |   # Select the "page" parameter
cut -f2 -d=         # Finally, extract the number we are interested in

字符串
还有一些其他的方法可以做到这一点,用更少的命令,也许更简单,但这一个允许我一步一步地解释。这些其他方式之一可以是:

<<< "$response" sed 's/.*&page=\(.*\); rel="last".*/\1/'


这一个做了一些假设,比如page总是最后一个参数。

gcxthw6b

gcxthw6b3#

官方的GitHub CLI(gh)支持--paginate标志,它可以为您完成繁重的工作。结合jq,您可以得到您正在寻找的答案。
这更简单,而且应该比之前发布的其他Bash解决方案更健壮。

示例

过去90天内的提交总数:

gh api --paginate \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/sindresorhus/awesome/commits?since=$(date -I -v-90d)&per_page=100" |
jq length

字符串
过去6个月的提交数量,按月细分,以CSV格式显示:

gh api --paginate \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/sindresorhus/awesome/commits?since=$(date -I -v-6m)&per_page=100" |
jq -r 'map(. + {month: (.commit.committer.date[:7])}) |
group_by(.month)[] | [(.[0].month), length] | @csv'


输出量:

"2023-01",1
"2023-02",6
"2023-03",3
"2023-04",5
"2023-05",3
"2023-06",11

相关问题