Rubyでライセンスページを自動生成するスクリプトを書いた話

お仕事で担当しているiOSアプリでの話。

背景

アプリで使っているライブラリのライセンス情報をSettings.bundleではなくローカルにある「ライセンスページ.html (ファイル名は仮名)」 をWebView上でわざわざ表示させているのですが、そのページ管理を今まで温かみのある手作業で管理しつづけていたので、ライブラリを追加・更新するたびにいちいちこのhtmlファイルに手入れないといけない運用が怠すぎた。

下手すると古いライセンス情報を表示しつづけてしまうリスクもあったので、かなりヤバい運用方法であることを知っていながらも、タスクが忙しい、書くモチベーションがない等、言い訳しながら放置。。。😨

でもここ最近タスクが落ち着いてきてそれなりに余裕も出てきたので、今回重い腰を上げて書くことにしました。

Rubyを選んだ理由

実行環境のセットアップが不要で簡単に書けそうなスクリプト言語がないか考えていた時に 最初はシェルで書こうか悩んだのですが、RubyならMacデフォルトで環境入ってるしCocoaPodsもRubyで出来てるから親和性高そうだしこれでいいんじゃね?ってなったのでRubyにしました。

考えた生成方法

RDocを使ってAcknowledgements.markdownをhtmlに変換してライセンスページ.htmlを生成

Acknowledgements.markdownを元にRDocを使ってhtmlに変換すれば楽に書けそうだなと思い使ってみたものの

  • html変換すると勝手にヘッダー部にリンク(ページトップ、ヘッダー移動)が付与されてしまう。
  • RDoc::Optionsを使えば変換ルールを変更できるっぽい?(ここがイマイチわかってない)が実装方法がわからない
  • Ruby未経験すぎて、ドキュメント見てもチンプンカンプン。
  • RDocの情報が少ない

ということがあり、Ruby初心者にはかなりハードだったためRDocを諦めました。 また自分の手で変換処理を書こうにも、markdown構文解析処理を実装するハードルが高すぎたため、この方法を断念して次の方法を考えることにしました。

Acknowledgements.plistからjsonに変換後、必要な要素を取り出してライセンスページ.htmlを生成

Macにデフォルトでplutilというコマンドが用意されている。 これはplistファイルをCUI上で操作するためのコマンドで、フィールドの編集やplistファイルから別の拡張子ファイルに変換することもできます。

OSXの固有コマンド - MacWiki

このコマンドでjsonファイルにも変換できるので、変換されたjsonファイルをスクリプト側で呼び出してパース すればいい感じにできそうだったので、このコマンドを使って実現することにしました

ライセンスページ.htmlのテンプレートを用意

body以外の要素は使い回せるので、テンプレート.htmlを用意し、その中身をスクリプト側でライセンス情報を書き込むようにします。

自動生成スクリプトを用意

jsonファイルから必要な要素を取得してhtml要素を付けたあとにテンプレートに書き込みます。 (Ruby初心者なのでガバガバコードになってるかもしれません。)

generate_licence_page.rb

require "json"
require "fileutils"

....

# JSONファイル読み込み
json_data = File.open(JSON_RESOURCE_PATH + "Acknowledgements.json") do |i|
    JSON.load(i)
end

json = json_data["PreferenceSpecifiers"]
markup_context = ""

# Acknowledgementsヘッダーフッターを削除 (必要であれば削除しなくてよい)
json.shift()
json.pop()

# JSONデータから「FooterText」「Title」を抽出してHTMLタグを付与 (付与するタグはお好みで)
for license in json do
    title = license["Title"]
    footerText = license["FooterText"]
    headerTitle = "<h2>" + title + "</h2>"
    context = "<pre>" + footerText + "</pre>"
    markup_context = markup_context + "\n" + headerTitle + "\n" + context
end

# テンプレートをコピー
FileUtils.cp(TEMPLATE_PATH, TEMPLATE_COPY_PATH)

# コピーしたテンプレートにライセンス情報を書き込む
File.open(TEMPLATE_COPY_PATH, mode = "a") { |f|
    f.write(markup_context)
    f.write("\n</body></html>")
}

# 書き込んだファイルをライセンスページ.htmlにする
File.rename(TEMPLATE_COPY_PATH, LICENSE_PAGE_PATH)

plutilと自動生成スクリプトをpod installにフックさせる

Podfileに以下を記述。plistファイル変換先のjsonファイル名は任意でOK。

post_install do |pi|
        system('plutil -convert json Pods/Target\ Support\ Files/Pods-Project/Pods-Project-acknowledgements.plist -r -o {出力先のパス}/Acknowledgements.json')
        system('ruby {スクリプトが置いてあるファイルパス}/generate_licence_page.rb')
end

これで準備完了。あとはpod installして確認。

無事ライセンスページが自動生成されるようになり、ライブラリを追加・削除しても差分が反映されたので、これで温かみのある手作業から無事開放となりました。😇

まとめ

  • RDocで躓きはしたが、Rubyが思った以上に書きやすかった。
  • plutilが優秀だった。
  • (当たり前の話だが)コードで解決できる手作業はコードで解決すべき。なるはやで。