せっかくの連休なので、さっくりと、Mastodonの改造をやってみたいと思います。こっちには連休無いけどな!この記事では、macOSでざっくりと開発環境を整え、Mastodonのコードを取得してmacOSで走らせられるようにして、特にフロントエンドに改造を加えて、GitHubにプルリクエストを送ってみます。macOSでビルドの難しいライブラリへの依存を取り除くことで、依存しない部分の改造を簡単にできるようにします。
この記事は、Mastodon Golden Week Calendarの4月30日の記事です。平成最後の日だ!昨日は、にし さんによる「おかげさまで、まちトドンは2周年」、明日は、ライスには塩を さんによる「ちいさなMastodonサーバの素人管理人が考える、いくつかのこと」です。
この記事の内容は2019年4月下旬にmacOS 10.13.6 High Sierraで確認しました。
開発環境の準備
Mastodonのビルドと稼働に必要なパッケージ類を用意しておきます。手元の使い込んだ環境で執筆していますので、この項には書いていないけれども必要なものもあるかもしれません。足りないものに気づいた方はお知らせいただけるとうれしいです。
Mastodonに必要なサービスとしてPostgreSQLとRedisがあります。ローカルに入れちゃいましょう。手元では、Postgresp.app 2.1.6でPostgreSQL 10.7が走っています。RedisはHomebrewで入れたredis-server 5.0.4が走っています。
Mastodonのビルドと稼働に必要なパッケージはHomebrewで入れてしまいます。
$ brew install git rbenv yarn redis
rbenvのために下記の行を~/.bash_profile
に追加しておきます。
$ cat <<_END >> ~/.bash_profile
PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
_END
必要なRubyのバージョンはMastodonの.ruby-version
ファイルに書いてありますので、コードをcloneしてきてからインストールします。
コードの準備
個人的には、アップストリームのレポジトリをGitHubでforkしてきて自分のレポジトリからクローンしてくるのが好みです。自分のforkのmasterはアップストリームのmasterをおっかけ、ブランチで自分用の改造をします。
GitHubにログインして https://github.com/tootsuite/mastodon から右上のForkボタンを押し、自分のレポジトリとしてforkして、自分のforkからClone or downloadボタンを押してSSHあるいはHTTPSのURLをコピーしてきてcloneします。さらに、アップストリームをupstream
リモートとして設定しておくと後々便利です。fetch
してリリース版のタグも手元に置いておきます。
$ git clone git@github.com:GitHubユーザー名/mastodon.git
$ cd mastodon
$ git remote add upstream https://github.com/tootsuite/mastodon.git
$ git fetch upstream
次に、macOS上でMastodonを起動できるようにするため、ファイルを書き換えます。ブランチを作成して作業を進めましょう。ここではmaster
あるいはリリースタグからlocal-devel-macos
というブランチを作成します。ブランチ名は好みで決めちゃってください。リリース版から改造を始めたい場合には、タグをチェックアウトしてからブランチを作成します。
(Masterから改造をする場合)
$ git checkout -b local-devel-macos
(リリース版をもとに改造をする場合)
$ git checkout v2.8.0
$ git checkout -b local-devel-macos
今回はdevelopment
環境で作業を進めます。環境変数を設定するファイルを作っておきます。ここではcommitしていませんが、commitしておいて別の環境にクローンして使い回すのも良いかもしれません。
$ cat <<_END > .env.dev
RAILS_ENV=development
NODE_ENV=development
_END
cld3
gemはprotobuf-compiler
パッケージを必要として、macOSではビルドが面倒です。今回はトゥートの言語の自動検出はあきらめて、利用しないようにします。
https://github.com/mastodon/mastodon/pull/17478 でcld3
gemへの依存が取り除かれました。これ以降のMastodonでは下記のパッチは必要なくなりそうです。
$ patch -p1 << _END
diff --git a/Gemfile b/Gemfile
index a2d851491..f7dd259ff 100644
--- a/Gemfile
+++ b/Gemfile
@@ -34,7 +34,6 @@ gem 'browser'
gem 'charlock_holmes', '~> 0.7.7'
gem 'iso-639'
gem 'chewy', '~> 5.1'
-gem 'cld3', '~> 3.2.6'
gem 'devise', '~> 4.7'
gem 'devise-two-factor', '~> 3.1'
_END
$ patch -p1 << _END
diff --git a/Gemfile.lock b/Gemfile.lock
index cdb6fa48c..0b88803de 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -160,8 +160,6 @@ GEM
elasticsearch (>= 2.0.0)
elasticsearch-dsl
chunky_png (1.3.11)
- cld3 (3.2.6)
- ffi (>= 1.1.0, < 1.12.0)
climate_control (0.2.0)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
@@ -683,7 +681,6 @@ DEPENDENCIES
capybara (~> 3.30)
charlock_holmes (~> 0.7.7)
chewy (~> 5.1)
- cld3 (~> 3.2.6)
climate_control (~> 0.2)
concurrent-ruby
connection_pool
_END
$ patch -p1 << _END
diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb
index 302072bcc..14e31a93e 100644
--- a/app/lib/language_detector.rb
+++ b/app/lib/language_detector.rb
@@ -6,10 +6,6 @@ class LanguageDetector
WORDS_THRESHOLD = 4
RELIABLE_CHARACTERS_RE = /[\p{Hebrew}\p{Arabic}\p{Syriac}\p{Thaana}\p{Nko}\p{Han}\p{Katakana}\p{Hiragana}\p{Hangul}]+/m
- def initialize
- @identifier = CLD3::NNetLanguageIdentifier.new(1, 2048)
- end
-
def detect(text, account)
input_text = prepare_text(text)
@@ -19,7 +15,7 @@ class LanguageDetector
end
def language_names
- @language_names = CLD3::TaskContextParams::LANGUAGE_NAMES.map { |name| iso6391(name.to_s).to_sym }.uniq
+ []
end
private
@@ -51,9 +47,7 @@ class LanguageDetector
end
def detect_language_code(text)
- return if unreliable_input?(text)
- result = @identifier.find_language(text)
- iso6391(result.language.to_s).to_sym if result.reliable?
+ return nil
end
def iso6391(bcp47)
_END
$ git commit -am 'Remove dependency to cld3'
idn-ruby
gemはlibidn11
パッケージを必要とします。開発時には国際化ドメイン名の取り扱いは不要ですので、利用しないようにします。
$ patch -p1 <<_END
diff --git a/Gemfile b/Gemfile
index f7dd259ff..d5c879aca 100644
--- a/Gemfile
+++ b/Gemfile
@@ -59,7 +59,6 @@ gem 'http', '~> 4.3'
gem 'http_accept_language', '~> 2.1'
gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2', submodules: true
gem 'httplog', '~> 1.3'
-gem 'idn-ruby', require: 'idn'
gem 'kaminari', '~> 1.1'
gem 'link_header', '~> 0.0'
gem 'mime-types', '~> 3.3.1', require: 'mime/types/columnar'
diff --git a/Gemfile.lock b/Gemfile.lock
index 0b88803de..26bc5b16a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -295,7 +295,6 @@ GEM
rails-i18n
rainbow (>= 2.2.2, < 4.0)
terminal-table (>= 1.5.1)
- idn-ruby (0.1.0)
ipaddress (0.8.3)
iso-639 (0.2.8)
jaro_winkler (1.5.4)
@@ -708,7 +707,6 @@ DEPENDENCIES
http_parser.rb (~> 0.6)!
httplog (~> 1.3)
i18n-tasks (~> 0.9)
- idn-ruby
iso-639
json-ld
json-ld-preloaded (~> 3.0)
_END
$ git commit -am 'Remove dependency to idn-ruby'
アプリケーションのビルド
Mastodonで利用するバージョンのRubyを用意します。
$ rbenv install $(cat .ruby-version)
$ gem install bundler
foreman
Gemがあるとアプリケーションの起動が楽です。
$ gem install foreman
$ bundle rehash
RAILS_ENV
とNODE_ENV
環境変数を設定しておいて、gemsとnodeモジュールをインストールします。
$ source .env.dev
$ bundle install --path=vendor/bundle --with=development
$ yarn install --pure-lockfile
Postgres.appでPostgreSQLが起動しているのを確かめたら、データベースを初期化してアセットを用意します。
$ bundle exec rails db:setup
$ bundle exec rails assets:precompile
赤いMastodonの起動
PostgreSQLが起動しているのを確認したらRedisも起動して、
$ redis-server
他の端末でMastodonを起動します。
$ foreman start -e .env.dev -f Procfile.dev
http://localhost:3000/ からMastodonにアクセスします。development
環境のMastodonはfaviconが赤いんですよ!
この状態で、すでにadminとしてログインできるようになっています。メールアドレスは、admin@localhost:3000
、パスワードは、db/seeds.rb
ファイルから探してみてください。
$ grep password db/seeds/04_admin.rb
改造してみる
このようにしてforeman start
で起動したwebpack-dev-server
が、Reacut/Reduxの変更については、ファイルの更新とともにブラウザがリロードして表示に反映してくれます。便利な時代だねえ!リロードしてくれないような変更は、foreman
をCtrl-C
で停止して再起動、そして、ブラウザでリロードするなどして確かめます。
あとは心の赴くままにコードを触って遊びましょう!例えば下記のような変更を施すと団子をクリックして絵文字を選択できるようになります。
$ patch -p1 <<_END
diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dr
opdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dro
pdown.js
index c1429c756..1ab1df137 100644
--- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.
js
+++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.
js
@@ -357,8 +357,8 @@ class EmojiPickerDropdown extends React.PureComponent {
<div ref={this.setTargetRef} className='emoji-button' title={title} ari
a-label={title} aria-expanded={active} role='button' onClick={this.onToggle} onKeyDown={this.onToggle} tabIndex={0}>
<img
className={classNames('emojione', { 'pulse-loading': active && loading })}
- alt='🙂'
- src={`${assetHost}/emoji/1f602.svg`}
+ alt='🍡'
+ src={`${assetHost}/emoji/1f361.svg`}
/>
</div>
_END
$ git commit -am 'Use dango for emoji picker button'
Happy Hacking!
プルリクエストを送る
改造がうまくいったら、アップストリームに反映してみんなに使ってもらえるようにするのもうれしいです。でも、今回の改造では、うれしいのは筆者だけなのでプルリクエスト先は自分のレポジトリにしておきますね。
ローカルのMastodonはCtrl-C
で停止しておきます。
筆者のぼっちインスタンスはzunda-ninja-master-on-heroku
というブランチで動いています。今回はこのブランチにマージできるようにレポジトリを準備していきます。
まず開発に使っていたブランチからプルリクエスト用の新しいブランチを作ります。
$ git checkout -b use-dango-for-emoji-picker
ブランチの分岐元をマージ先に変更します。エディタが起動するので、macOSで起動できるようにするなどプルリクエストに不要なコミットはdrop
し、必要なコミットはsquash
してまとめてしまうのが良いでしょう。
$ git rebase -i zunda-ninja-master-on-heroku
今回は下記のようになりました。
drop c8786e988 Remove dependency to cld3
drop 3a6a65a8a Remove dependency to idn-ruby
pick 63e4d15af Use dango for emoji picker button
GitHubにpushしたらプルリクエストを作成できます。
$ git push -u origin use-dango-for-emoji-picker
GitHubでの操作は直感的ですが、プルリクエストを送る先を間違えないように注意します。Compare & pull requestボタンを押して、
マージ先のレポジトリを選択し、
マージ先のブランチを選択し、
プルリクエストの内容を書いてCreate pull requestボタンを押します。
これで、プルリクエストのできあがり!マージしてデプロイすれば、いつものMastodonにも今回の改造が反映されます。楽しいな♪
なお、特にバックエンドの改造の場合には、テストを走らせて通るのを確認しておくのも大事かもしれません。
以上、せっかくの連休なのでMastodonを改造したくなった方はご参考まで!