-
-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-organize the naming convention of module, type, product, and file to have consistent project structure #450
Conversation
await Carton.main() | ||
} | ||
func main() async { | ||
await CartonFrontendCommand.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
async版の main を呼び出すために async context の中で main
を呼ぶ必要があったため、 main 関数に包んでいます。
元のような Main
型は不要な型であり、
他の場所でも生じうるとややこしくなるので、
型を作らないほうが見やすいと思います。
少しだけ行数も少ないし。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
あーだめだこれ、ステータスコードが引き継げていない
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
いやいいのか exitしてるか
public static let configuration = CommandConfiguration( | ||
commandName: "carton-frontend", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
型名から自動設定されるコマンド名がうまくいかないので、手動設定します。サブコマンド3つについても同様です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no opinion here, so let's move forward
テストが通ったので確認お願いします。 テストが落ちていたのは、swift-argument-parserがコマンド名を型名から自動設定するためでした。 swift-argument-parser的には、コマンド名と同じ型名を使うのが推奨かもしれませんが、 |
背景
#420 で Carton のプロダクトには SwiftPM プラグインが追加されました。
従来の
carton
コマンドの実装は、エンドユーザから利用される
carton
コマンドとプラグインと、
プラグインから利用される CartonFrontend コマンドの
3層に分割されました。
この3層にはそれぞれ、 bundle, dev, test の機能のロジックが実装されています。
つまり、プロジェクトはおよそ 9個のコード群として実装されています。
課題
これら 9個のコード群について、
ソースコードの実装パターン、ファイル名、型名などに一貫した規則がないため、
プロジェクト全体のコードを読んで回るのが難しいと感じています。
Cartonには多くのOSSコントリビュータが協力することが期待されているため、
初めてソースツリーに触れる人が歩きやすい構造にしておくことが重要です。
特に、3層の構造は一般的に見られない実装パターンであるし、
ただのシンボル参照ではなく IPC が多用されているため、
コード同士の参照関係をIDEだけで追跡することができず、読解しづらいです。
そのため、ファイルツリーのコンベンションで構造のヒントを与えることが有効でしょう。
例
わかりづらいポイントの具体例を挙げます。
例えば
Dev.swift
というソースファイルを見かけたとして、これが 3層のどれに関与するものなのかファイル名からわかりません。
例えば
CartonCLI
というディレクトリ名、つまりモジュール名を見たとして、これも 3層との関係が不明です。
2つのコマンドだけではなく、プラグインも command plugin であり、つまり CLI です。
3つのプラグインは
Plugin.swift
と同じ名前が与えられており、こちらについては逆にディレクトリ名を見ると 3機能 のいずれであるかがわかるようになっています。
Carton
という型名が存在しますが、これは一見
carton
エンドユーザコマンドに関係しているように見えて、フロントエンドです。CartonFrontend
というコマンド名は、ライブラリのように見えますが、実行可能ファイルです。
実行可能ファイルのエントリポイントも、
main.swift
,Main.swift
などがありますが、中身はトップレベルコードだったり、@main
型だったりします。後者については、ファイルに含まれる型がファイル名から予測できないので、
ファイルツリーからナビゲートしにくいです。
提案
以下のような原則を設けます。
実行可能ファイルは
kebab-case
にするこれは一般的な慣習です。
トップレベルコードでのエントリポイントは
main.swift
にするこれは、このファイルの中身にはトップレベルタイプが存在しないからです。
そのファイルが代表的な型を一つ含む場合は、ファイル名と型名を一致させる
こうすることによって、型名からファイルに辿り着きやすくなります。
@main
付きの型を含むファイルは、型名のファイル名にする上記のルールのもとで、こうなります。
コマンドの実装のモジュール名は、コマンド名の
PascalCase
にするこうすることによって、
command-name
実行可能ファイルの実装が、CommandName
モジュールによって提供されているという関係がわかりやすくなります。コマンド型には
Command
suffix をつけるコマンド型とは
AsyncParsableCommand
に準拠する型と、CommandPlugin
に準拠する型の事です。こうすることによって、その型がコマンドであることがわかりやすくなります。
機能名で型名サーチした時、名前からそれがコマンドなのか、ライブラリなのかわかりやすくなり、
目的のコードに辿り着きやすくなります。
プラグインモジュールには
Plugin
suffix をつけるこうすることによって、モジュールやディレクトリがプラグインを実装していることがわかりやすくなります。
コマンドプラグイン型には、
CommandPlugin
suffixをつけるこうすることによって、
ある型がプラグインコマンドを提供していることがわかりやすくなります。
また
Command
をつけるもう一つの理由として、プラグインモジュールと型名を異らせるためです。
これが同じだと Swift言語仕様上の不都合が生じます。
フロントエンドのコマンド型には
Frontend
をつけるコマンドは3層あるので、どの層なのかすぐわかることが重要です。
実際にはエンドユーザ層は main に書き下されているので2層しか実装はないのですが、
その暗黙の知識がなくとも名前でわかれば便利です。
変更
以上の原則に基づいて、以下のように変更します。
CartonFrontend
モジュールこのモジュールは実行可能ファイルです。
モジュール名を
carton-frontend
に変更します。CLIのコマンド名も
carton-frontend
に変わります。Main.swift
→main.swift
にリネームします。CartonCLI
モジュールCartonFrontend
にリネームします。型名を以下のように変更します。
Carton
→CartonFrontendCommand
Bundle
→CartonFrontendBundleCommand
Dev
→CartonFrontendDevCommand
Test
→CartonFrontendTestCommand
また、それぞれのファイル名も同様に変更します。
CartonBundle
モジュールこのモジュールはプラグインです。
モジュール名を
CartonBundlePlugin
に変更します。CartonBundlePlugin
型はCartonBundlePluginCommand
型にリネームします。また、それを含むファイルの
Plugin.swift
はCartonBundlePluginCommand.swift
にリネームします。CartonDev
,CartonTest
モジュールCartonBundle
プラグインモジュールと同様の変更をします。carton-release
モジュールこれには
Main.swift
が含まれていますが、中身は
@main
のついたCartonReleaseCommand
型だけが含まれているので、CartonReleaseCommand.swift
にリネームします。チートシート
変更内容を整理した手元のメモも貼っておきます。
内容は同じですがこちらの方が一覧しやすいかもしれません。