可以使用以下方式检索拉取请求、问题和提交的评论bitbucket 的 REST API https://developer.atlassian.com/bitbucket/api/2/reference/resource/.
然而,似乎没有办法在一个地方列出所有这些,因此获取它们的唯一方法是查询存储库的每个 PR、问题或提交的 API。
请注意,这需要很长时间,因为 bitbucket 似乎对通过 API 访问存储库数据的次数设置了限制:我得到已超出该资源的速率限制在检索大约一千个结果后出现错误,那么我只能检索自上次速率限制错误发生以来每秒大约只有一个条目。
查找存储库的 API URL
第一步是找到存储库的 URL。对于私有存储库,需要通过提供用户名和密码来进行身份验证(使用curl的-u
转变)。 URL 的形式为:
https://api.bitbucket.org/2.0/repositories/{repoOwnerName}/{repoName}
Running git remote -v
来自本地 git 存储库的应该提供缺失的值。检查伪造的URL(以下简称$url
)通过验证存储库信息是否正确检索为 JSON 数据:curl -u username $url
.
获取提交的评论
提交的评论可以访问$url/commit/{commitHash}/comments
.
生成的 JSON 数据可以通过脚本进行处理。请注意,结果是分页的 https://developer.atlassian.com/bitbucket/api/2/reference/meta/pagination.
下面我简单提取每次提交的评论数。由会员的价值来表示size
检索到的 JSON 对象;我还请求一个部分反应 https://developer.atlassian.com/bitbucket/api/2/reference/meta/partial-response通过添加 GET 参数fields=size
.
我的剧本getNComments.sh
:
#!/bin/sh
pw=$1
id=$2
json=$(curl -s -u username:"$pw" \
https://api.bitbucket.org/2.0/repositories/{repoOwnerName}/{repoName}/commit/$id/comments'?fields=size')
printf '%s' "$json" | grep -q '"type": "error"' \
&& printf "ERROR $id\n" && exit 0
nComments=$(printf '%s' "$json" | grep -o '"size": [0-9]*' | cut -d' ' -f2)
: ${nComments:=EMPTY}
checkNumeric=$(printf '%s' "$nComments" | tr -dc 0-9)
[ "$nComments" != "$checkNumeric" ] \
&& printf >&2 "!ERROR! $id:\n%s\n" "$json" && exit 1
printf "$nComments $id\n"
使用它时,要考虑到出现上述错误的可能性:
A) 准备输入数据。从本地存储库中,根据需要生成提交列表(运行git fetch -a
如果需要的话,在更新本地 git 存储库之前);查看git help rev-list
了解如何定制它。
git rev-list --all | sort > sorted-all.id
cp sorted-all.id remaining.id
B) 运行脚本。请注意,密码在此处作为参数传递 - 因此首先使用以下方法将其安全地分配给变量stty -echo; IFS= read -r passwd; stty echo
,排成一行;另请参阅下面的安全注意事项。此处使用选项将处理并行到 15 个进程-P
.
< remaining.id xargs -P 15 -L 1 ./getNComments.sh "$passwd" > commits.temp
C) 当达到速率限制时,即当getNComments.sh
prints !ERROR!,然后杀死上面的命令(Ctrl-C
),并执行以下命令来更新输入和输出文件。等待一段时间,直到请求限制增加,然后重新执行上述一条命令,重复执行,直到处理完所有数据(即当wc -l remaining.id
回报0
).
cat commits.temp >> commits.result
cut -d' ' -f2 commits.result | sort | comm -13 - sorted-all.id > remaining.id
D)最后,您可以通过以下方式获取收到评论的提交:
grep '^[1-9]' commits.result
获取拉取请求和问题的评论
该过程与获取提交评论相同,但有以下两个调整:
编辑脚本以替换 URL 中的内容commit
by pullrequests
or by issues
, 作为适当的;
Let $n
是要搜索的问题/PR 的数量。这git rev-list
上面的命令变成:seq 1 $n > sorted-all.id
存储库中 PR 的总数可以通过以下方式获得:
curl -su username $url/pullrequests'?state=&fields=size'
并且,如果设置了问题跟踪器,则会显示以下问题的数量:
curl -su username $url/issues'?fields=size'
希望存储库中的 PR 和问题足够少,以便可以一次性获取所有数据。
查看评论
可以通过其提交/PR/问题页面上的网络界面正常查看它们:
https://bitbucket.org/{repoOwnerName}/{repoName}/commits/{commitHash}
https://bitbucket.org/{repoOwnerName}/{repoName}/pull-requests/{prId}
https://bitbucket.org/{repoOwnerName}/{repoName}/issues/{issueId}
例如,要在 firefox 中打开所有带有评论的 PR:
awk '/^[1-9]/{print "https://bitbucket.org/{repoOwnerName}/{repoName}/pull-requests/"$2}' PRs.result | xargs firefox
安全考虑
系统的所有用户都可以看到命令行上传递的参数,通过ps ax
(or /proc/$PID/cmdline
)。因此,bitbucket 密码将被暴露,如果系统由多个用户共享,这可能会成为一个问题。
从命令行获取密码的命令有三个:xargs、脚本和curl。
看起来,curl 试图通过覆盖其内存来隐藏密码,但它不能保证有效,即使有效,它也会在进程启动后的一段(非常短的)时间内保持可见。在我的系统上,curl 的参数没有隐藏。
更好的选择可能是通过环境变量传递敏感信息。它们应该仅对当前用户和 root 可见ps axe
(or /proc/$PID/environ
);尽管似乎有些系统可以让所有用户访问此信息(执行ls -l /proc/*/environ
检查环境文件的权限)。
在脚本中只需替换以下行pw=$1 id=$2
with id=$1
,然后通过pw="$passwd"
before xargs
在命令行调用中。它将使环境变量pw
可见于xargs
及其所有后代进程,即脚本及其子进程(curl
, grep
, cut
等),它可能会也可能不会读取变量。 curl 不会从环境中读取密码,但如果上面提到的密码隐藏技巧有效,那么它可能就足够了。
有多种方法可以避免通过命令行将密码传递给curl,特别是使用选项通过标准输入-K -
。在脚本中,替换curl -s -u username:"$pw"
with printf -- '-s\n-u "%s"\n' "$authinfo" | curl -K -
并定义变量authinfo
包含格式为用户名:密码的数据。注意该方法需要printf
为了安全起见,内置外壳(检查type printf
),否则密码将显示在其进程参数中。如果它不是内置的,请尝试使用print
or echo
反而。
环境变量的一个简单替代方案不会出现在ps
任何情况下的输出都是通过文件。创建一个文件,其读/写权限仅限于当前用户(chmod 600
),然后编辑它,使其包含 username:password 作为第一行。在脚本中,替换pw=$1
with IFS= read -r authinfo < "$1"
,然后编辑它以使用curl的-K选项,如上段所示。在命令行中调用替换$passwd
与文件名。
文件方法的缺点是密码将被写入磁盘(请注意,文件位于/proc
不在磁盘上)。如果这也是不可取的,可以传递命名管道而不是常规文件:
mkfifo pipe
chmod 600 pipe
# make sure printf is a builtin, or use an equivalent instead
(while :; do printf -- '%s\n' "username:$passwd"; done) > pipe&
pid=$!
exec 3<pipe
然后调用脚本传递pipe
而不是文件。最后,要清理,请执行以下操作:
kill $pid
exec 3<&-
这将确保身份验证信息直接从 shell 传递到脚本(通过内核),不会写入磁盘,也不会通过以下方式暴露给其他用户ps
.