Timers Tech Blog

カップル専用アプリ「Pairy」, 子育て夫婦アプリ「Famm」を運営している Timers inc. の公式Tech Blogです。

iOSアプリのプロジェクトのSwiftとObjective-Cのコード量の割合をターミナルで出力するスクリプトを組んでみた

こんにちは!iOSエンジニアのすーです!
8月もあと少しで終わってしまいますね。
今回は、たまにはスクリプトも書いてみたいなと思って

iOSアプリのプロジェクトのSwiftとObjective-Cのコード量の割合をターミナルで出力するスクリプト

を書いてみました。

最初からPure Swiftで立ち上げたプロジェクトなら不要なのですが、Objective-Cで立ち上げたプロジェクトで、徐々にSwiftに移行させている... なんていうときには、
どれだけ移行できたのか? 気になりますよね。
一応、Githubで管理しているプロジェクトなら、Github上で言語別の割合が見れますが、

  • 他の細かい設定(.ymlとか.json)ファイルとかもHitしてしまう
  • もし、CarthageやPods以下のファイル群もGithubで管理しているとそれも割合に 含まれてしまう

といった問題が出てきます。Fammも、後者の方が関係してきて、プロジェクト内のSwiftとObjective-Cの正しい割合が出せません。

なので、それを解決すべく、ターミナル上で確認できるようにするためのスクリプトを書きました。

必要なもの

  • cloc コマンド (後述します)
  • 適当なエディタ
  • 適当なターミナル

clocコマンドについて

cloc コマンドは、あるディレクトリ内に配置されているファイル群から、どの言語がどれだけ遣われているか、その言語で書かれた行数が何行か、等を出力してくれるコマンドラインツールになっています。
実行するとこんな感じで出力してくれます。

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Swift                           11             66             93            173
JSON                             7              0              0            169
YAML                             1              7             20             22
-------------------------------------------------------------------------------
SUM:                            19             73            113            364
-------------------------------------------------------------------------------

自力でgrepコマンドであれこれやるより遥かに楽なので、今回はこれを使います。 brewでインストールするのをおすすめします。

$ brew install cloc

ちなみに、clocのバージョンは1.70を使います。

$ cloc --version
# 1.70

参考

スクリプトを用意する

先に入れた cloc コマンドを使ってSwiftとObjective-Cのコード量の割合を出すスクリプトを準備します。

流れとしては、

  • clocコマンドでSwiftObjective-Cだけに絞って、 files, blank, comment, codeを出力する
    • その時、Pods/Carthage/以下のファイルは含まないようにする
  • 出力された結果から不要なものをそぎ落として、それぞれの言語のコード量と合計を取得する
  • 割合を計算して、最終的な結果を出力する

となります。 使うコマンドは、sedawkbc コマンドあたりをうまく使っていきます。

clocコマンドでSwift, Objective-Cのみの結果を出力する

出力する言語を絞る場合は、 cloc コマンドの --include-lang オプションを使います。

$ cloc --include-lang=Swift,Objective\ C ./
# Swift, Objective-Cのみの出力結果になる

Objective-Cの場合、-(ハイフン)ではなく、半角スペースになっているため、 \ (バックスラッシュ+半角スペース)にする必要があります。

Pods/ , Carthage/ ディレクトリ以下を除外する

特定のディレクトリを除外するには、 cloc コマンドの --exclude-dir を使います。

$ cloc --exclude-dir=Pods,Carthage
# Pods/, Carthage/ 以下のファイルを除外した出力結果になる

上記の --include-lang と組み合わせることで、
「Swift, Objective-Cのみ且つ、Pods/, Carthge/ 以下を含めないで出力する」ことができます。

cloc --exclude-dir=Pods,Carthage --include-lang=Swift,Objective\ C ./

clocの出力結果から余計なものを削ぎ落とす

上記の出力結果には、最初の5行ほど不要な出力があったり、 code の項目以外のものや、点線が不要になるので、これを sed, awk コマンド等を使ってそぎ落としていきます。

$ (clocでの出力結果) | sed -e '1,5d' | sed 's/-//g' | sed 's/Objective C/ObjectiveC/g' | awk '{print $5}' | grep -v -e 'code' -e '^S*$'`

処理はパイプを使って繋げて処理していきます。ここでは、

  • 最初の5行分の出力を削ぎ落とす
  • 点線を削ぎ落とす
  • "Objective C" と、 空白スペースがあると次の awk で誤作動するので、一旦ObjecitveCに置換
  • code 列の文字を抜き出す
  • 不要な文字("code" と空白) を削ぎ落とす

を行います。これで、Swiftのコード量、Objective-Cのコード量、コード量の合計を得ることができます。

得られた結果を配列に格納する

ただ、このままだと扱いづらいので、一度配列に格納します。 格納すると、indexにそれぞれ、
0 : Swiftのコード量の数値
1: Objective-Cのコード量の数値
2: コード量の合計値
が入ってきます。

arr=($(cloc --exclude-dir=Pods,Carthage --include-lang=Swift,Objective\ C ./ | sed -e '1,5d' | sed 's/Objective C/ObjectiveC/g' | sed 's/-//g' | sed 's/Objective C/ObjectiveC/g' | awk '{print $5}' | grep -v -e 'code' -e '^S*$'))
swift_files=${arr[0]} # swiftのコード量
objc_files=${arr[1]} # Objective-Cのコード量
sum=${arr[2]} # コード量の合計値

bcコマンドを使って、割合計算を行う

最後に、 Swiftのコード量 / コード量の合計値 Objective-Cのコード量 / コード量の合計値 の除算を行って、割合を算出します。 小数点以下も考慮したいため、 bc コマンドを使用します。
更に、四捨五入を適切に行うため、下記の記事を参考にさせて頂いて四捨五入の処理を awk で書いています。

calc_percentage() {
  echo "$1/$2*100" | bc -l | awk '{s=($0<0)?-1:1;print int($0*s*100+0.5)/100/s;}'
}
swift_percent=$(calc_percentage $swift_files $sum) # Swiftの割合
objc_percent=$(calc_percentage $objc_files $sum) # Objective-Cの割合

これで割合が算出できたので

echo "Swift: $swift_percent%, Objective-C: $objc_percent%"

こんな感じで echo してあげれば、結果を出力することができます!

ここまでをまとめる

ここまでをまとめてみます。

#!/bin/bash

calc_percentage() {
  echo "$1/$2*100" | bc -l | awk '{s=($0<0)?-1:1;print int($0*s*100+0.5)/100/s;}'
}

arr=($(cloc --exclude-dir=Pods,Carthage --include-lang=Swift,Objective\ C ./ | sed -e '1,5d' | sed 's/Objective C/ObjectiveC/g' | sed 's/-//g' | sed 's/Objective C/ObjectiveC/g' | awk '{print $5}' | grep -v -e 'code' -e '^S*$'))
swift_files=${arr[0]}
objc_files=${arr[1]}
sum=${arr[2]}
swift_percent=$(calc_percentage $swift_files $sum)
objc_percent=$(calc_percentage $objc_files $sum)
echo "Swift: $swift_percent%, Objective-C: $objc_percent%"

これを適当な .sh ファイルに貼り付けて、実行権限を与えてあげれば、スクリプトとして呼び出すことが出来ます。

Gistもあげておきました。

まとめ

ここまでやらなくても...と思いつつも、リポジトリの都合によっては正確に割合が出せないこともあるので、正確に割合を知りたい場合は是非使ってみてください! cloc コマンド自体もかなり優秀だと思います。 ちなみに弊社のFamm は、
Swift : 59.76%
Objective-C: 40.24%
と、ついにSwiftの割合が半分を超えました!新規開発は基本的にSwiftなので、じわりじわりと割合が増加している感じです。

積極採用中!

子育て家族アプリFamm、カップル専用アプリPairyを運営するTimers inc. では、現在エンジニアを積極採用中! 急成長中のサービスの技術の話を少しでも聞いてみたい方、スタートアップで働きたい方など、是非お気軽にご連絡ください! 採用HP : http://timers-inc.com/engineerings