#Swift fastlaneの次に来る? Sourcery🔮でメタプログラミングする
Sourcery
Sourcery scans your source code, applies your personal templates and generates Swift code for you, allowing you to use meta-programming techniques to save time and decrease potential mistakes.
テンプレートからSwift
のコードを生成するツール
Benefit
- ボイラープレートコードが減り、DRY(Don't repeat yourself)原則を守りやすい
- リファクタリング時のヒューマンエラーを減らす
- テンプレートを書くと、リアルタイムにFeedbackが行われる
など、良さそうです
Installing
方法は以下の4通り
- Binary form
- Via CocoaPods
- Via Swift Package Manager
- From Source
今回はCocoaPodsでインストールします!
と思ったらpod install
でエラーが出た
LoadError - cannot load such file -- nanaimo
/Library/Ruby/Gems/2.0.0/gems/xcodeproj-1.4.1/lib/xcodeproj/plist.rb:23:in `read_from_path'
/Library/Ruby/Gems/2.0.0/gems/xcodeproj-1.4.1/lib/xcodeproj/project.rb:200:in `initialize_from_file'
/Library/Ruby/Gems/2.0.0/gems/xcodeproj-1.4.1/lib/xcodeproj/project.rb:102:in `open'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer/analyzer.rb:851:in `block (2 levels) in inspect_targets_to_integrate'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer/analyzer.rb:850:in `each'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer/analyzer.rb:850:in `block in inspect_targets_to_integrate'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/user_interface.rb:64:in `section'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer/analyzer.rb:845:in `inspect_targets_to_integrate'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer/analyzer.rb:66:in `analyze'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer.rb:236:in `analyze'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer.rb:150:in `block in resolve_dependencies'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/user_interface.rb:64:in `section'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer.rb:149:in `resolve_dependencies'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/installer.rb:110:in `install!'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/command/install.rb:37:in `run'
/Library/Ruby/Gems/2.0.0/gems/claide-1.0.1/lib/claide/command.rb:334:in `run'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/lib/cocoapods/command.rb:52:in `run'
/Library/Ruby/Gems/2.0.0/gems/cocoapods-1.2.0/bin/pod:55:in `<top (required)>'
/usr/local/bin/pod:23:in `load'
/usr/local/bin/pod:23:in `<main>'
解決
gem list | grep nanaimo // print nanaimo (0.2.3, 0.2.2)
gem uninstall nanaimo -v 0.2.2
テンプレート用・生成コード用のフォルダを作成
なんでも良さそうですが、公式サンプルと同じ名前にします
- Templates - テンプレート用フォルダ
- CodeGenerated - 生成コード用フォルダ
プロジェクトにScriptを追加
Build Phases > Run Scriptに以下を追加
$PODS_ROOT/Sourcery/bin/sourcery {source} {templates} {output}
今回、プロジェクト名は SourcerySample にしたので、以下のScriptを追加しました
"${PODS_ROOT}/Sourcery/bin/sourcery" "${SRCROOT}/SourcerySample" "${SRCROOT}/Templates" "${SRCROOT}/CodeGenerated"
Usage
.stencil
ファイルにテンプレートを定義
Stencil
とは
.stencil
ファイルにテンプレートを定義Stencil
とはStencil is a simple and powerful template language for Swift. It provides a syntax similar to Django and Mustache. If you're familiar with these, you will feel right at home with Stencil.
syntaxがDjango、Mustacheに似た、Swift
のためのテンプレート言語
Stencil
のテンプレート
今回はプロジェクト内の列挙型にcount
を返すextensionを定義します
Stencil
ファイル名は、Enum+Count
にします
{% for enum in types.enums %}
extension {{ enum.name| }} {
static var count: Int { return {{ enum.cases.count }} }
}
{% endfor %}
検証用に、以下のSwift
の列挙型を用意しました
enum Planets {
case mecury
case venus
case earth
case mars
case jupiter
case saturn
case uranus
case neptune
}
コマンドを実行
$ ./sourcery . templates output --watch
- source -
Swift
ファイルのpath - templates - テンプレートのディレクトリのpath
- output - 生成したコードのディレクトリのpath
- --watch - このflagにより、Templateファイルの変更を受けてリアルタイムにコード反映を行う
生成されました
Finder
このSwift
ファイルをXcodeのプロジェクトに追加します
コード
検証用の列挙型のcount
を定義したExtension
が生成されています
extension Planets {
static var count: Int { return 8 }
}
リアルタイムにコードを更新
一度コマンドを実行すると、停止するまでwatch
が継続されます
その間、Stencil
ファイルやテンプレート定義に該当するファイルを変更すると、
⌘ + S
で生成コードがリアルタイムに更新されます
今までのテンプレートから少し変更して、extension
にコメントを付与してみます
{% for enum in types.enums %}
// {{ enum.name }}のcount定義をするExtension ← 新たに追加したコメント
extension {{ enum.name }} {
static var count: Int { return {{ enum.cases.count }} }
}
{% endfor %}
⌘ + S
で保存すると、ジェネレートされたファイルに反映されています
// Planetsのcount定義をするExtension
extension Planets {
static var count: Int { return 8 }
}
列挙型の宣言を増やしてもバッチリです
// Planetsのcount定義をするExtension
extension Planets {
static var count: Int { return 8 }
}
// Zodiac.Signのcount定義をするExtension
extension Zodiac.Sign {
static var count: Int { return 12 }
}
Sample Code
- cloneする
pod install
-
$ ./sourcery . templates output --watch
のpathを書き換えて実行
リアルタイムで、コードジェネレートを試すことができます
テンプレートの書き方
その他のテンプレートの書き方は公式Readmeにまとまっています
krzysztofzablocki/Sourcery#writing-templates
参考
ありがとうございました!
まとめ
- 4通りのインストール方法がある
- テンプレートとジェネレート用のディレクトリが必要
-
--watch
の間は、リアルタイム反映ができる
-
⌘ + S
でジェネレートするコードを更新
投稿のタイトルについて
--watch
の間は、リアルタイム反映ができる⌘ + S
でジェネレートするコードを更新参考にさせていただいた#292: Metaprogramming with Sourcery 🔮に
In modern times, things like Fastlane, CocoaPods, and Carthage come to mind. Slightly more seasoned folks may remember the emergence of Pull to Refresh, or BWToolkit.
Sourcery from Krzysztof Zabłocki is the latest addition to this set.
と書いてあったので、タイトルにしてみました
以上です
今回は参考リンクで勉強させていただきました
もっといろいろ触って学びたいです
読んでいただき、ありがとうございました
Author And Source
この問題について(#Swift fastlaneの次に来る? Sourcery🔮でメタプログラミングする), 我々は、より多くの情報をここで見つけました https://qiita.com/mesummery/items/31df8444982ce25e8e55著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .