Githubで今年作ったリポジトリの一覧を出力する
毎年この方法を調べている気がするが、今年はGithub CLIがGraphQL APIの呼び出しをサポートしたようなので、コレを使って出力してみることにする1。GraphQL自体を試したい場合には、 https://docs.github.com/en/free-pro-team@latest/graphql/overview/explorer のあたりを参考にして試行錯誤してみれば良い。
利用例は以下のような形。 --paginate
をつけると、いい感じに100件以上になったときもページネーションして取ってきてくれる。必要なら引数を渡せる。
$ gh api graphql --paginate -f query=' query($endCursor: String) { viewer { repositories(first: 100, after: $endCursor) { nodes { nameWithOwner } pageInfo { hasNextPage endCursor } } } } '
このサンプルの例をベースに作ってみる。
createdAtが2020以降のもの
個人的には以下の様なものが欲しい
以下の様なMakefileを作る。フィルタリングは自作のコマンドでやっているが、慣れている人はjqなどでやっても良い。
# query 00: gh api graphql --paginate -f query='$(shell cat list-repository.query)' | jq . | tee repositories.json # filtered 01: jqfpy --squash -c '[h.pick("nameWithOwner", "createdAt", d=row) for row in get("data/viewer/repositories/nodes") if not row["isFork"] and not row["isPrivate"] and row["createdAt"].startswith("2020-")]' repositories.json | tee 2020-repositories.json # setup setup: port install gh # or https://github.com/cli/cli pip install jqfpy
list-repositories.queryは以下のようなもの。
query($endCursor: String) { viewer { repositories(first: 100, after: $endCursor) { nodes { nameWithOwner createdAt updatedAt isPrivate isFork } pageInfo { hasNextPage endCursor } } } }
ちなみに、これはMakefile故の問題ではあるのだけれど、オプションに渡すqueryを'
ではなく"
でクォートしようとしてしまうと$endCursor
などが展開されてしまいParseErrorになってしまう。コレでしばらくハマってしまっていた2。
今年作られたリポジトリ
そんなわけで今年作ったリポジトリは以下の様なものらしい。それぞれの雑感については別の記事で触れるかもしれない。この記事では触れない。
{"nameWithOwner": "podhmo/cliauth", "createdAt": "2020-01-08T14:08:56Z"} {"nameWithOwner": "podhmo/minitask", "createdAt": "2020-01-26T08:09:01Z"} {"nameWithOwner": "podhmo/snatch", "createdAt": "2020-02-01T06:28:14Z"} {"nameWithOwner": "podhmo/scoop-buckets", "createdAt": "2020-03-13T14:50:54Z"} {"nameWithOwner": "podhmo/baku", "createdAt": "2020-03-23T16:19:22Z"} {"nameWithOwner": "podhmo/egoist", "createdAt": "2020-04-21T20:34:34Z"} {"nameWithOwner": "podhmo/maperr", "createdAt": "2020-05-03T06:47:54Z"} {"nameWithOwner": "podhmo/typoless", "createdAt": "2020-05-29T21:48:10Z"} {"nameWithOwner": "podhmo/sheetconf", "createdAt": "2020-07-04T08:22:49Z"} {"nameWithOwner": "podhmo/startevent", "createdAt": "2020-09-22T14:11:50Z"} {"nameWithOwner": "podhmo/tenuki", "createdAt": "2020-09-26T23:12:42Z"} {"nameWithOwner": "podhmo/reflect-openapi", "createdAt": "2020-10-03T05:50:01Z"} {"nameWithOwner": "podhmo/starlette-dataframe-response", "createdAt": "2020-10-30T16:17:07Z"} {"nameWithOwner": "podhmo/inflexible", "createdAt": "2020-11-28T21:09:31Z"}
createdAtの他にupdatedAtもあるので、更新日でみたい人はそちらを使えば良い。更新日だとさすがに長くなる。
{"nameWithOwner": "podhmo/emacs-sandbox", "updatedAt": "2020-12-09T07:26:20Z"} {"nameWithOwner": "podhmo/alchemyjsonschema", "updatedAt": "2020-08-17T13:42:55Z"} {"nameWithOwner": "podhmo/python-semver", "updatedAt": "2020-11-05T17:19:18Z"} {"nameWithOwner": "podhmo/miniconfig", "updatedAt": "2020-07-09T19:24:53Z"} {"nameWithOwner": "podhmo/prestring", "updatedAt": "2020-11-29T20:08:08Z"} {"nameWithOwner": "podhmo/handofcats", "updatedAt": "2020-07-09T19:18:58Z"} {"nameWithOwner": "podhmo/individual-sandbox", "updatedAt": "2020-12-26T16:55:55Z"} {"nameWithOwner": "podhmo/selfish", "updatedAt": "2020-05-30T10:46:06Z"} {"nameWithOwner": "podhmo/magicalimport", "updatedAt": "2020-02-06T00:48:25Z"} {"nameWithOwner": "podhmo/dictknife", "updatedAt": "2020-10-05T01:57:29Z"} {"nameWithOwner": "podhmo/swagger-marshmallow-codegen", "updatedAt": "2020-12-20T21:46:40Z"} {"nameWithOwner": "podhmo/kamidana", "updatedAt": "2020-03-17T12:41:41Z"} {"nameWithOwner": "podhmo/moduleknife", "updatedAt": "2020-05-23T15:22:48Z"} {"nameWithOwner": "podhmo/jqfpy", "updatedAt": "2020-12-29T22:36:40Z"} {"nameWithOwner": "podhmo/commithistory", "updatedAt": "2020-04-29T09:35:17Z"} {"nameWithOwner": "podhmo/go-twitter-notififer", "updatedAt": "2020-04-29T08:59:35Z"} {"nameWithOwner": "podhmo/go-traceable", "updatedAt": "2020-08-27T03:23:49Z"} {"nameWithOwner": "podhmo/pyinspect", "updatedAt": "2020-02-06T06:29:52Z"} {"nameWithOwner": "podhmo/shosai", "updatedAt": "2020-01-17T13:15:27Z"} {"nameWithOwner": "podhmo/pycomment", "updatedAt": "2020-07-04T16:54:44Z"} {"nameWithOwner": "podhmo/go-webtest", "updatedAt": "2020-12-12T04:06:44Z"} {"nameWithOwner": "podhmo/lsp-spec-to-openapi-doc", "updatedAt": "2020-08-12T05:03:04Z"} {"nameWithOwner": "podhmo/pypackage", "updatedAt": "2020-10-31T14:20:45Z"} {"nameWithOwner": "podhmo/metashape", "updatedAt": "2020-12-26T12:21:52Z"} {"nameWithOwner": "podhmo/monogusa", "updatedAt": "2020-02-29T15:17:08Z"} {"nameWithOwner": "podhmo/cliauth", "updatedAt": "2020-01-08T14:09:11Z"} {"nameWithOwner": "podhmo/minitask", "updatedAt": "2020-02-26T15:26:11Z"} {"nameWithOwner": "podhmo/snatch", "updatedAt": "2020-02-01T07:07:36Z"} {"nameWithOwner": "podhmo/scoop-buckets", "updatedAt": "2020-03-13T15:07:18Z"} {"nameWithOwner": "podhmo/baku", "updatedAt": "2020-03-23T17:07:24Z"} {"nameWithOwner": "podhmo/egoist", "updatedAt": "2020-10-31T14:44:25Z"} {"nameWithOwner": "podhmo/maperr", "updatedAt": "2020-05-09T10:11:39Z"} {"nameWithOwner": "podhmo/typoless", "updatedAt": "2020-05-30T08:34:52Z"} {"nameWithOwner": "podhmo/sheetconf", "updatedAt": "2020-07-05T20:49:17Z"} {"nameWithOwner": "podhmo/startevent", "updatedAt": "2020-09-22T15:57:50Z"} {"nameWithOwner": "podhmo/tenuki", "updatedAt": "2020-09-29T19:24:23Z"} {"nameWithOwner": "podhmo/reflect-openapi", "updatedAt": "2020-12-26T14:57:03Z"} {"nameWithOwner": "podhmo/starlette-dataframe-response", "updatedAt": "2020-10-31T14:19:26Z"} {"nameWithOwner": "podhmo/inflexible", "updatedAt": "2020-12-12T15:03:52Z"}
雑感
こういう取得・整形(フィルタリング)の処理を1ファイルでまとめてしまいたいと言う気持ちもあるし、収集と整形は処理を分けたいと言う気持ちもある。Makefile1つでやってやれないことはないのだけれど、ちょっと複雑になるので結局分けた。