Bitbucketをちょっとだけ便利にする。 #augj

このエントリはAtlassian Advent Calendar 2012 #augjの4日目のエントリです。 前日は id:kyon_mm さんの SourceTreeで楽々git-flow, hg-flow #augj - うさぎ組 です。 明日は @mtgto さんです。

今回はBitbucketをちょっとだけ便利に使う方法を紹介しようと思います。

リポジトリのREADMEやWikiの表示をシャキッとさせる

先々月デザインリニューアルがおこわなれて、Bitbucketはかなりかっこよくなったと思います(以前がダメすぎだという話も)。

すごく良いのですが、READMEやWikiの表示の部分には手が入ってないらしく、リニューアル前ののっぺりした感じのままです。

なので、シャキッとさせるために次のCSSを追加しています。(ChromeFirefoxでStylishを使っています)

.readme.file {
  border: 1px solid #DDD;
  border-radius: 5px;
  margin-top: 20px;
  padding: 15px 20px;
  overflow: auto;
}

#repo-overview .readme.file {
  margin-top: 0px;
}

#readme h1 { border-bottom: 1px solid #DDD; }
#readme h2 { border-bottom: 1px solid #DDD; }
#readme h3 { border-bottom: 1px solid #DDD; }
#readme h4 { border-bottom: 1px solid #DDD; }

#issue-title     { border-bottom: 1px solid #DDD; }
#wiki-content h1 { border-bottom: 1px solid #DDD; }
#wiki-content h2 { border-bottom: 1px solid #DDD; }
#wiki-content h3 { border-bottom: 1px solid #DDD; }
#wiki-content h4 { border-bottom: 1px solid #DDD; }

適用例はこんな感じ。かなりシャキッとします。

f:id:troter:20121204221111p:plain

ただ、plaintextの場合はちょっと残念な表示になります。

f:id:troter:20121204221332p:plain

Pull Requestされた変更を即座に手元に取り込む。

仕事でBitbucketを使ってますか?Pull Requestしてますか? Pull Requestを開発フローに入れると、

  • ケアレスミスを事前に防いでみんなに迷惑をかけることが減ったり、
  • 認識違いを指摘出来たり、
  • 知らなかったテクニックの共有ができたり

と、いろいろ便利ですよね!

で、Pull Requestはレビューにとても便利なのですが、「Pull Requestを手元に取り込んで動かして確認したい!」と思うとちょっと面倒です。

特に工夫をしないと次の手順で取り込むと思います。

  1. Pull Requestを出したリポジトリのURLをコピー
  2. 必要があればブランチ名をコピー
  3. 必要があればリビジョンをコピー
  4. 集めた情報から次のようなコマンドを組み立てて、実行
hg pull {URL} -r {ブランチ名 or リビジョン}

面倒くさい。。。

と、いうことで。次のようなUserScriptをでっちあげました。 実行するとPull Requestされた変更を取り込むためのコマンドが表示されます。 (僕はChromeのTempermonkyで動かしてます)

// ==UserScript==
// @name         bitbucket hg pull command
// @namespace    http://use.i.E.your.homepage/
// @version      0.1
// @description  enter something useful
// @match        https://bitbucket.org/*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js
// @copyright    2012+, Takumi IINO
// ==/UserScript==
$(function() {
  var parse_branchlink = function(branchlink) {
    var _ = branchlink.attr('href').split('/');
    return {
      branch_name: branchlink.attr('title'),
      branch_rev: decodeURIComponent(_[6]),
      user: _[1],
      repo: _[2],
    };
  };
  var parse_hashlink = function(hashlink) {
    var _ = hashlink.attr('href').split('/');
    return {
      hash_short_rev: hashlink.text(),
      hash_rev: _[4],
      user: _[1],
      repo: _[2],
    };
  };
  $('#pull-from dd[class="branch unabridged"]').each(function() {
    var branchlink = parse_branchlink($(this).find('a:first-child'))
    var hashlink = null;
    if ($(this).find('a[class="hash"]').length > 0) {
      hashlink = parse_hashlink($(this).find('a[class="hash"]'));
    }
    var current_user = $('#user-dropdown-trigger').attr('title') || '';
    var repo_user = branchlink.user;
    var repo_name = branchlink.repo;
    var rev = branchlink.branch_rev;
    if (hashlink != null) {
      rev = hashlink.hash_rev;
    }
    var https_pull_command = 'hg pull https://' + current_user + '@bitbucket.org/'  + repo_user + '/' + repo_name + ' -r ' + "'" + rev + "'";
    var ssh_pull_command = 'hg pull ssh://hg@bitbucket.org/'  + repo_user + '/' + repo_name + ' -r ' + "'" + rev + "'";
    $('#pull-request-header').after([
      '<div style="margin: 0 0 20px;">',
      '<p><input id="https-pull-command" type="text" size="100" readonly="readonly" value=""></p>',
      '<p><input id="ssh-pull-command" type="text" size="100" readonly="readonly" value=""></p>',
      '</div>'].join(''));
    $('#https-pull-command').attr('value', https_pull_command);
    $('#ssh-pull-command').attr('value', ssh_pull_command);
  });
});

実行結果は、こんな感じや f:id:troter:20121204220729p:plain

こんな感じ。

f:id:troter:20121204220831p:plain

表示はダサいけど、これでコピペだけで簡単にPull Requestを取り込めます。

デフォルトのリポジトリのアイコンをイカ娘にする

疲れたときは、次のUserScriptをつかって癒されましょう。

// ==UserScript==
// @name       bitbucket ika-musume
// @namespace  http://use.i.E.your.homepage/
// @version    0.1
// @description  enter something useful
// @match      https://bitbucket.org/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js
// @copyright  2012+
// ==/UserScript==
var $ = unsafeWindow.jQuery;
$(function() {
  $("img[class='repo-avatar size16']").each(function() {
    if ($(this).attr("src").match(/.*default_16.png/)) {
      $(this).attr({
        src: "https://twimg0-a.akamaihd.net/profile_images/1093514809/t_icon_reasonably_small.gif",
        width: "16px",
        height: "16px",
      });
    }
  });
  $("span[class='repo-avatar-container size32'] > img").each(function() {
    if ($(this).attr("src").match(/.*default_32.png/)) {
      $(this).attr({
        src: "https://twimg0-a.akamaihd.net/profile_images/1093514809/t_icon_reasonably_small.gif",
        width: "32px",
        height: "32px",
      });
    }
  });
  $("span[class='repo-avatar-container size64'] > img").each(function() {
    if ($(this).attr("src").match(/.*default_64.png/)) {
      $(this).attr({
        src: "https://twimg0-a.akamaihd.net/profile_images/1093514809/t_icon_reasonably_small.gif",
        width: "64px",
        height: "64px",
      });
    }
  });
});

表示例はこんな感じ。いい感じですね。

f:id:troter:20121204222058p:plain

まとめ

Bitbucket さん、取り込むコマンド表示してくだしあ><