Corredor

ウェブ、プログラミングの勉強メモ。

GitHub リポジトリのサイズを取得する curl + jq ワンライナーとブックマークレット

GitHub リポジトリをダウンロードした時、どのくらいのファイルサイズになるのか事前に確認したい時がある。

GitHub API を使うと、リポジトリのサイズが KB 単位で取得できるので、コレを利用する。

curl + jq で取得するワンライナー

まずは最もシンプルに、次のようなワンライナーを書けばサイズが取得できることを確認する。

$ curl -sS https://api.github.com/repos/Homebrew/homebrew-core | jq -r '(.size|tostring) + "KB : " + ((.size / 1000)|floor|tostring) + "MB"'
291169KB : 291MB

取得できる値は KB 単位なので、1000 で割って MB 単位も出力しておく。

次にコレを関数化してみる。

function get-repo-size() {
  curl -sS "https://api.github.com/repos/$1" | jq -r '(.size|tostring) + "KB : " + ((.size / 1000)|floor|tostring) + "MB"'
}

$ get-repo-size 'Homebrew/homebrew-core'
291169KB : 291MB

こんな風に、ユーザ名/リポジトリ名 を引数に渡すだけでリポジトリのファイルサイズを取得できるようになった。

ブックマークレットにしてみる

続いて、GitHub リポジトリを閲覧中に、そのリポジトリのファイルサイズを取得するワンライナーを作ってみた。

  • 普通に組んでみた
(() => {
  const getText = (query) => {
    const elem = document.querySelector(query);
    return elem ? elem.innerText : null;
  };
  const owner = getText('.author');
  const repo  = getText('.mr-2>a');
  if(!owner || !repo) return;
  const xhr = new XMLHttpRequest();
  xhr.timeout = 5000;
  xhr.addEventListener('load', () => {
    try {
      const size = JSON.parse(xhr.response).size;
      alert(`${size}KB\n${Math.floor(size/1000)}MB`);
    } catch(e) {}
  });
  xhr.open('GET', `https://api.github.com/repos/${owner}/${repo}`);
  xhr.send();
})();

ページ中の .author 要素や、.mr-2 > a 要素から、ユーザ名やリポジトリ名を取得して、XMLHttpRequest を使って GitHub API をコールしている。

コレを1行にすればとりあえず動くが、もう少しコードを短くしてみる。

((getText, xhr, owner, repo, size) => {
  owner = getText('.author');
  repo  = getText('.mr-2>a');
  if(!owner || !repo) return;
  xhr.open('GET', 'https://api.github.com/repos/' + owner + '/' + repo, false);
  xhr.send();
  size = JSON.parse(xhr.response).size;
  alert(size + 'KB\n' + Math.floor(size / 1000) + 'MB');
})(
  (query, elem) => {
    elem = document.querySelector(query);
    return elem ? elem.innerText : null;
  },
  new XMLHttpRequest()
);

XMLHttpRequest を同期処理にし、try / catch を外した。GitHub 以外のページで実行した場合は、まず getText() 関数の結果が空になるはずなので、Ajax も実行されないかと踏んで省略した。あとテンプレートリテラルよりも + での文字列結合の方が、Uglify した時に2文字短くできたのでコチラにした。

コレを1行のブックマークレットにすると次のとおり。

javascript:((g,x,o,r,s)=>{o=g('.author'),r=g('.mr-2>a'),o&&r&&(x.open('GET','https://api.github.com/repos/'+o+'/'+r,!1),x.send(),s=JSON.parse(x.response).size,alert(s+'KB\n'+Math.floor(s/1e3)+'MB'))})((q,e)=>(e=document.querySelector(q))?e.innerText:null,new XMLHttpRequest);

コレを実行すると、

291169KB
291MB

といった情報が alert() で表示される。


必要十分~。