🎄and factory.inc Advent Calendar 2024 18日目の記事です🎄
はじめに
この記事では、Swiftプロジェクトのテンプレート生成ツールをGenerambaからGenesisへ移行する方法について解説します。私が担当するプロジェクトではこれまでGenerambaを使用していましたが、Generambaとfastlaneが依存しているライブラリのバージョンコンフリクトが発生し、運用が難しくなってしまいました。
そこで、代替手段としてGenesisを導入することにしました。本記事では、Genesisの基本的な導入手順や使用例を紹介し、移行をスムーズに進めるための手助けとなる内容をお届けします。
Generambaが使えなくなって困っている方や、テンプレート生成ツールの選定で迷っている方にとって、少しでも参考になれば幸いです。
背景
これまでテンプレート生成ツールとしてGenerambaを使用してきましたが、長期間メンテナンスが行われておらず、他のライブラリとの依存関係でバージョンのコンフリクトが発生してしまいました。この問題により、別のテンプレート生成ツールに移行する必要が出てきました。
いくつかあるテンプレート生成ツールの中から、社内の他プロジェクトで導入実績があり、必要な機能を備えていたGenesisを選択しました。
Genesisの概要
Genesisは、Swiftプロジェクトでテンプレートを生成するためのCLIツールです。シンプルな設計ながら、テンプレート管理や作成に必要な機能が揃っています。
主な特徴として以下が挙げられます。
•YAMLまたはJSON形式で書かれたテンプレートマニュフェスト
•Stencilテンプレート言語を使用してテンプレートファイルを作成
Genesisの導入手順
環境
- OS: macOS Sonoma 14.5
- Xcode: 16.0.0
- Swift: 6.0.0
- Mint: 0.17.5
インストール
今回は、Mintを使ってインストールしていきます。Mintをまだインストールしていない方はこちらの記事を参考にMintをインストールしてください。
Mintfile
yonaskolb/genesis@0.9.0
Mintを使ってGenesisをインストール
$ mint install genesis
マニフェストファイルの作成
私が担当するプロジェクトでは、MVP+Clean Architectureを採用しています。今回テンプレートを生成する対象は、新規画面を作成する際にPresentation層で必要になるファイル群になります。
Genesisを利用するために、プロジェクトにマニフェストファイルを追加します。このファイルには、テンプレートの設定や生成されるファイルの情報を記述します。ここでは、YAML形式での例を紹介します。
files:
- template: Templates/ViewController.swift
path: "{{ target }}/Presentation/{{ module }}/View/{{ module }}ViewController.swift"
- template: Templates/Presenter.swift
path: "{{ target }}/Presentation/{{ module }}/Presenter/{{ module }}Presenter.swift"
- template: Templates/Builder.swift
path: "{{ target }}/Presentation/{{ module }}/Builder/{{ module }}Builder.swift"
- template: Templates/Wireframe.swift
path: "{{ target }}/Presentation/{{ module }}/Wireframe/{{ module }}Wireframe.swift"
ここで使用しているtarget
やmodule
は、Genesisを実行するときにオプション引数として値を渡します。
また、Genesisはマニフェストファイルにoptionsを設定することで、Genesis実行時に対話形式でオプションの値を渡すこともできます。その場合は、マニフェストファイルは以下のようになります。
詳しい書き方はREADMEを参考にしてください
#options:
- name: target
description: "テンプレートを追加するターゲット"
question: "テンプレートを追加するターゲットを入力してください"
required: true
type: string
- name: module
description: "モジュール名"
question: "モジュール名を入力してください"
required: true
type: string
# ... その他必要なオプション
files:
- template: Templates/ViewController.swift
path: "{{ target }}/Presentation/{{ module }}/View/{{ module }}ViewController.swift"
- template: Templates/Presenter.swift
path: "{{ target }}/Presentation/{{ module }}/Presenter/{{ module }}Presenter.swift"
- template: Templates/Builder.swift
path: "{{ target }}/Presentation/{{ module }}/Builder/{{ module }}Builder.swift"
- template: Templates/Wireframe.swift
path: "{{ target }}/Presentation/{{ module }}/Wireframe/{{ module }}Wireframe.swift"
テンプレートファイルの作成
Genesisでは、テンプレートファイルをStencilテンプレート言語を使用して作成します。これにより、動的な変数や条件分岐を取り入れた柔軟なテンプレートを作成できます。
今回はViewControllerのテンプレートファイルの例を紹介します。
//
// {{ module }}ViewController.swift
// {{ target }}
//
// Created by {{ developerName }} on {{ date }}
// Copyright © {{ year }}年 {{ developerCompany }}. All rights reserved.
//
import UIKit
@MainActor
protocol {{ module }}View {
var presenter: (any {{ module }}Presenter)! { get set }
}
final class {{ module }}ViewController: UIViewController {
var presenter: {{ module }}Presenter!
override func viewDidLoad() {
super.viewDidLoad()
}
}
// MARK: - {{ module }}View
extension {{ module }}ViewController: {{ module }}View {}
{{ target }} や {{ module }} など、Genesisに渡したoptionの値を使用してクラス名などを動的に変更しながらファイルを生成します。
今回使用していませんがStencilでは、制御フローやmacroの使用などいろいろな機能が提供されているので、詳しくは公式ドキュメントを参照してください。
ファイル生成
マニフェストファイルとテンプレートファイルの準備ができたので、Genesisを実行してファイルを生成していきます。
Genesisを実行するには以下のコマンドで実行します
genesis generate template.yml -o "option1: value 2, option2: value 2"
ただ、毎回コマンドを入力するのは面倒なので、makeコマンドとscriptを使用して手軽に実行できるようにしていきます。
Genesis実行用script
今回のテンプレートでは、コメント部分にファイルの生成日時や開発者名などを設定するので、各値を用意してからgenesisコマンドを実行してファイルを生成するようにします。
#!/usr/bin/env sh
today=`date "+%Y/%m/%d"`
current_year=`date "+%Y"`
echo $today
echo $current_year
developer_company="Company Name"
target="Target"
read -p "new screen name to generate. (e.g. Home): " screen_name
read -p "developer name for header comment. (e.g. Taro Yamada): " developer_name
mint run genesis generate Genesis/Screen/template.yml -o "target: $target, module: $screen_name, date: $today, year: $current_year, developerName: $developer_name, developerCompany: $developer_company"
Makefileの作成
Makefileに先ほど作成したscriptを実行するコマンドを追加し、makeコマンドでファイル生成が行えるようにします。
.PHONY: generate-screen
generate-screen: ## Generate Screen Module Templates
sh generate_screen_module.sh
makeコマンドからGenesisを実行
上記で作成したmakeコマンドを実行してファイルを生成します。
$ make generate-screen
出力結果
コマンドを実行した結果、テンプレートファイルに従って、以下のようなファイルが生成されました。
おわりに
今回は、GenerambaからGenesisへの移行理由とGenesisの概要について紹介しました。Genesisは、シンプルな設定で必要なテンプレートを効率よく生成できるツールです。
テンプレート生成ツールを探している方や、Generambaの運用に困っている方にとって、少しでも参考になれば嬉しいです。