8
5

More than 3 years have passed since last update.

GitHubリポジトリのスター数でOSSランキングを作成する

Last updated at Posted at 2019-01-05

GitHubリポジトリのスター数順にOSSをソートしランキング化する方法を紹介します。

成果物

検索スクリプト

以下にスクリプトを公開していますのでご活用ください。

後述するpageパラメタをインクリメントしながら検索しますので便利です。

ランキング

本記事で紹介している方法で作成したGo言語のWebフレームワークランキングです。

ランキング作成方法

リポジトリをスター数順に検索&ソートする

GitHub REST API v3Search APIを利用します。

APIエンドポイント
https://api.github.com/search/repositories
APIパラメタ

詳細はsearch/#parametersをご参照下さい。

パラメタ 設定値 設定例
q 以下を含むクエリ
検索キーワード(要URIエンコード)
in
language
stars
web+framework
in 検索対象
name : リポジトリ名
description : 概要
readme : README.md
name,description,readme
language 言語 go
stars スター数の条件 >=1000
sort ソートする項目 start
order ソート順序 desc
per_page 1ページあたりのitem数 10
page ページ番号(1始まり) 1

per_pagepageについてはPaginationをご参照下さい。
pageパラメタを適宜インクリメントしながら複数回検索する必要があります。

検索コマンド

スター数1000以上のGo言語のリポジトリを対象にweb frameworkをキーワードに検索するコマンドの例です。

LANGUAGE=go
KEYWORD=web+framework
STAR=1000
USER=your_username
PASS=your_password
page=1
curl -u ${USER}:${PASS} "https://api.github.com/search/repositories?q=${KEYWORD}+in:name,description,readme+language:${LANGUAGE}+stars:>=${STAR}&sort=stars&order=desc&per_page=10&page=${page}"

認証は必須ではありませんが制限(rate limit)にひっかかりにくいので実施してます。
上記例はBASIC認証ですがOAuth2認証にしたい方は以下記事を参照下さい。
GitHub API を 叩く

検索結果

total_countは全リポジトリ数です。
itemsはリポジトリの配列で要素数は最大でper_pageです。
stargazers_countがスター数で降順にソートされています。

{
  "total_count": 61,
  "incomplete_results": false,
  "items": [
    {
      "id": 21540759,
      "node_id": "MDEwOlJlcG9zaXRvcnkyMTU0MDc1OQ==",
      "name": "awesome-go",
      "full_name": "avelino/awesome-go",
      "private": false,
      "owner": {
        "login": "avelino",
        "id": 31996,
        "node_id": "MDQ6VXNlcjMxOTk2",
        "avatar_url": "https://avatars2.githubusercontent.com/u/31996?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/avelino",
        "html_url": "https://github.com/avelino",
        "followers_url": "https://api.github.com/users/avelino/followers",
        "following_url": "https://api.github.com/users/avelino/following{/other_user}",
        "gists_url": "https://api.github.com/users/avelino/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/avelino/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/avelino/subscriptions",
        "organizations_url": "https://api.github.com/users/avelino/orgs",
        "repos_url": "https://api.github.com/users/avelino/repos",
        "events_url": "https://api.github.com/users/avelino/events{/privacy}",
        "received_events_url": "https://api.github.com/users/avelino/received_events",
        "type": "User",
        "site_admin": false
      },
      "html_url": "https://github.com/avelino/awesome-go",
      "description": "A curated list of awesome Go frameworks, libraries and software",
      "fork": false,
      "url": "https://api.github.com/repos/avelino/awesome-go",
      "forks_url": "https://api.github.com/repos/avelino/awesome-go/forks",
      "keys_url": "https://api.github.com/repos/avelino/awesome-go/keys{/key_id}",
      "collaborators_url": "https://api.github.com/repos/avelino/awesome-go/collaborators{/collaborator}",
      "teams_url": "https://api.github.com/repos/avelino/awesome-go/teams",
      "hooks_url": "https://api.github.com/repos/avelino/awesome-go/hooks",
      "issue_events_url": "https://api.github.com/repos/avelino/awesome-go/issues/events{/number}",
      "events_url": "https://api.github.com/repos/avelino/awesome-go/events",
      "assignees_url": "https://api.github.com/repos/avelino/awesome-go/assignees{/user}",
      "branches_url": "https://api.github.com/repos/avelino/awesome-go/branches{/branch}",
      "tags_url": "https://api.github.com/repos/avelino/awesome-go/tags",
      "blobs_url": "https://api.github.com/repos/avelino/awesome-go/git/blobs{/sha}",
      "git_tags_url": "https://api.github.com/repos/avelino/awesome-go/git/tags{/sha}",
      "git_refs_url": "https://api.github.com/repos/avelino/awesome-go/git/refs{/sha}",
      "trees_url": "https://api.github.com/repos/avelino/awesome-go/git/trees{/sha}",
      "statuses_url": "https://api.github.com/repos/avelino/awesome-go/statuses/{sha}",
      "languages_url": "https://api.github.com/repos/avelino/awesome-go/languages",
      "stargazers_url": "https://api.github.com/repos/avelino/awesome-go/stargazers",
      "contributors_url": "https://api.github.com/repos/avelino/awesome-go/contributors",
      "subscribers_url": "https://api.github.com/repos/avelino/awesome-go/subscribers",
      "subscription_url": "https://api.github.com/repos/avelino/awesome-go/subscription",
      "commits_url": "https://api.github.com/repos/avelino/awesome-go/commits{/sha}",
      "git_commits_url": "https://api.github.com/repos/avelino/awesome-go/git/commits{/sha}",
      "comments_url": "https://api.github.com/repos/avelino/awesome-go/comments{/number}",
      "issue_comment_url": "https://api.github.com/repos/avelino/awesome-go/issues/comments{/number}",
      "contents_url": "https://api.github.com/repos/avelino/awesome-go/contents/{+path}",
      "compare_url": "https://api.github.com/repos/avelino/awesome-go/compare/{base}...{head}",
      "merges_url": "https://api.github.com/repos/avelino/awesome-go/merges",
      "archive_url": "https://api.github.com/repos/avelino/awesome-go/{archive_format}{/ref}",
      "downloads_url": "https://api.github.com/repos/avelino/awesome-go/downloads",
      "issues_url": "https://api.github.com/repos/avelino/awesome-go/issues{/number}",
      "pulls_url": "https://api.github.com/repos/avelino/awesome-go/pulls{/number}",
      "milestones_url": "https://api.github.com/repos/avelino/awesome-go/milestones{/number}",
      "notifications_url": "https://api.github.com/repos/avelino/awesome-go/notifications{?since,all,participating}",
      "labels_url": "https://api.github.com/repos/avelino/awesome-go/labels{/name}",
      "releases_url": "https://api.github.com/repos/avelino/awesome-go/releases{/id}",
      "deployments_url": "https://api.github.com/repos/avelino/awesome-go/deployments",
      "created_at": "2014-07-06T13:42:15Z",
      "updated_at": "2019-01-05T14:58:22Z",
      "pushed_at": "2019-01-05T09:41:48Z",
      "git_url": "git://github.com/avelino/awesome-go.git",
      "ssh_url": "git@github.com:avelino/awesome-go.git",
      "clone_url": "https://github.com/avelino/awesome-go.git",
      "svn_url": "https://github.com/avelino/awesome-go",
      "homepage": "https://awesome-go.com/",
      "size": 4851,
      "stargazers_count": 38695,
      "watchers_count": 38695,
      "language": "Go",
      "has_issues": true,
      "has_projects": false,
      "has_downloads": true,
      "has_wiki": false,
      "has_pages": true,
      "forks_count": 5035,
      "mirror_url": null,
      "archived": false,
      "open_issues_count": 31,
      "license": {
        "key": "mit",
        "name": "MIT License",
        "spdx_id": "MIT",
        "url": "https://api.github.com/licenses/mit",
        "node_id": "MDc6TGljZW5zZTEz"
      },
      "forks": 5035,
      "open_issues": 31,
      "watchers": 38695,
      "default_branch": "master",
      "permissions": {
        "admin": false,
        "push": false,
        "pull": true
      },
      "score": 94.155464
    },
        (   )
    {
        (   )
    }
  ]
}

検索結果を整形

ランキングとして表示するには項目が多すぎますので見やすいフォーマットに加工します。

CSV ( or Json ) にする

以下項目を抽出します。

リポジトリ名,スター数,リポジトリURL,概要

jqコマンドでCSV形式に加工する例です。
なお、| @csvを削除するとjson形式になります。

curl -u ${USER}:${PASS} "https://api.github.com/search/repositories?q=${KEYWORD}+in:name,description,readme+language:${LANGUAGE}+stars:>=${STAR}&sort=stars&order=desc&per_page=10&page=${page}" | jq -r ".items[] | [.full_name , .stargazers_count, .html_url, .description] | @csv"
整形結果

1行1リポジトリとなりすっきりしました。

"avelino/awesome-go",38695,"https://github.com/avelino/awesome-go","A curated list of awesome Go frameworks, libraries and software"
"gin-gonic/gin",23408,"https://github.com/gin-gonic/gin","Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin."
"astaxie/beego",18465,"https://github.com/astaxie/beego","beego is an open-source, high-performance web framework for the Go programming language."
"kataras/iris",13285,"https://github.com/kataras/iris","The fastest backend community-driven web framework on (THIS) Earth. HTTP/2, MVC and more. Can your favourite web framework do that? 👉 http://bit.ly/iriscandothat1 or even http://bit.ly/iriscandothat2"
"openfaas/faas",12576,"https://github.com/openfaas/faas","OpenFaaS - Serverless Functions Made Simple"
"labstack/echo",12566,"https://github.com/labstack/echo","High performance, minimalist Go web framework"
"go-kit/kit",12312,"https://github.com/go-kit/kit","A standard library for microservices."
"revel/revel",10638,"https://github.com/revel/revel","A high productivity, full-stack web framework for the Go language."
"go-martini/martini",10411,"https://github.com/go-martini/martini","Classy web framework for Go"
"boltdb/bolt",9314,"https://github.com/boltdb/bolt","An embedded key/value database for Go."
ノイズの除去

最終的なランキングデータとするには、ノイズ(検索キーワードは含まれているが目的に沿わない検索結果)の除去が必要です。
ノイズかどうか判断するにはdescriptionREADME.md(特に序章の紹介文)を読むのが良いです。
やはり最終的には人力が必要になりますが、ここまでの作業でスター数が多い順に絞り込まれていますので、
上から順に精査しノイズを除去していくと後戻りなくランキングトップXX(トップ10など)が出揃います。

Markdownにする

CSV To Markdown Table GeneratorのようなサイトでCSVをMarkdownのテーブルに変換できます。
Qiita等に投稿するのに便利です。

まとめ

GitHubリポジトリのスター数順にOSSをランキングする方法と成果物を紹介しました。
スター数以外にもコミュニティの活発度、機能性や性能など、OSSを選定するための基準はたくさんあります。
開発に適したOSSを選定するための指標の1つとして本記事のランキング作成方法が手助けになりましたら幸いです。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5