原則
このページでは、Tuist の設計と開発の基盤となる原則について説明します。これらの原則はプロジェクトの進化に合わせて更新され、プロジェクトの基盤と整合性の取れた持続可能な成長を実現することを目的としています。
規約をデフォルトとする#
Tuist が存在する理由の一つは、Xcode が規約に弱く、その結果としてスケールや保守が難しい複雑なプロジェクトになりがちな点にあります。そのため、Tuist はシンプルかつ入念に設計された規約をデフォルトとするアプローチを採用しています。開発者は規約から外れることもできますが、それは自然ではない意識的な選択となります。
例えば、提供される公開インターフェースを使用してターゲット間の依存関係を定義するという規約があります。これにより、Tuist はリンクが正しく動作するための適切な設定でプロジェクトを生成することを保証します。開発者はビルド設定を通じて依存関係を定義することもできますが、それは暗黙的に行われるため、特定の規約に従うことを前提とした tuist graph や tuist cache といった Tuist の機能が壊れてしまいます。
規約をデフォルトとする理由は、開発者に代わってより多くの決定を下せるほど、彼らがアプリの機能構築に集中できるからです。多くのプロジェクトで見られるように規約がない状態では、他の決定と一貫性のない判断を下すことになり、その結果として管理が難しい偶発的な複雑さが生じます。
マニフェストを信頼できる唯一の情報源とする#
多数の設定レイヤーとその間の契約が存在すると、理解や保守が難しいプロジェクト構成になってしまいます。一般的なプロジェクトを少し考えてみてください。プロジェクトの定義は .xcodeproj ディレクトリに、CLI はスクリプト(例:Fastfiles)に、CI のロジックはパイプラインに存在します。これらは維持すべき契約を持つ3つのレイヤーです。プロジェクトで何かを変更した後、数週間後にリリーススクリプトが壊れていることに気づいた経験はどれくらいありますか?
これを簡素化するには、マニフェストファイルを信頼できる唯一の情報源とします。これらのファイルは、開発者がファイルを編集するために使用する Xcode プロジェクトを生成するために必要な情報を Tuist に提供します。さらに、ローカル環境または CI 環境からプロジェクトをビルドするための標準的なコマンドを使用できるようになります。
Tuist は複雑さを内部で処理し、プロジェクトを可能な限り明示的に記述するためのシンプルで安全、かつ使いやすいインターフェースを提供すべきです。
暗黙的なものを明示化する#
Xcode は暗黙的な設定をサポートしています。その良い例が、暗黙的に定義された依存関係の推論です。暗黙性は設定が単純な小規模プロジェクトでは問題ありませんが、プロジェクトが大きくなるにつれて低速化や奇妙な動作を引き起こす可能性があります。
Tuist は、暗黙的な Xcode の動作に対して明示的な API を提供すべきです。また、Xcode の暗黙性を定義することもサポートすべきですが、その実装は開発者が明示的なアプローチを選択するように促すものであるべきです。Xcode の暗黙性や複雑さをサポートすることは Tuist の導入を促進し、その後チームは暗黙性を取り除くための時間を取ることができます。
依存関係の定義はその良い例です。開発者はビルド設定やフェーズを通じて依存関係を定義できますが、Tuist はその採用を促す優れた API を提供しています。
API を明示的に設計することで、Tuist は otherwise 不可能だったプロジェクトのチェックや最適化を実行できます。 さらに、依存関係グラフの表現をエクスポートする tuist graph や、すべてのターゲットをバイナリとしてキャッシュする tuist cache などの機能を有効にします。
Xcode から機能を移植する各リクエストを、シンプルで明示的な API で概念を簡素化する機会として捉えるべきです。
シンプルさを保つ#
Xcode プロジェクトをスケールさせる際の主な課題の一つは、Xcode がユーザーに多くの複雑さを露呈しているという事実から来ています。そのため、チームのバス係数が高くなり、プロジェクトやビルドシステムが出力するエラーを理解できる人がチーム内に少数しかいません。チームが少数の人員に依存することになるため、これは望ましくない状況です。
Xcode は優れたツールですが、長年の改善、新しいプラットフォーム、プログラミング言語の追加が表面に反映され、シンプルさを保つことが難しくなっています。
Tuist は物事をシンプルに保つ機会を活用すべきです。シンプルなもので作業することは楽しく、やる気を高めてくれます。コンパイルプロセスの最後に発生するエラーのデバッグに時間を費やしたり、デバイスでアプリを実行できない理由を理解しようとする人は誰もいません。Xcode はタスクを基盤となるビルドシステムに委譲しますが、場合によってはエラーを実行可能な項目に変換するのが非常に下手です。“framework X not found” というエラーが出て、どうすればよいかわからなかった経験はありませんか?バグの潜在的な根本原因の一覧が表示されたらどうでしょうか。
開発者の体験から始める#
Xcode 周辺でイノベーションが不足している理由、つまり他のプログラミング環境ほど革新が進んでいない理由の一部は、既存のソリューションから問題分析を始めることが多いためです。その結果、現在見つかる解決策の多くは同じアイデアやワークフローを中心としています。既存のソリューションを検討材料に入れることは有益ですが、それらが私たちの創造性を制約しないようにすべきです。
私たちは Tom Preston が このポッドキャスト で語っているように考えることを好みます:「ほとんどのことは達成可能です。頭の中にあるアイデアは、宇宙の制約内で可能であれば、コードで実現できるでしょう」。理想的な開発者体験を想像するなら、それを実現するのは時間の問題です。開発者体験から問題分析を始めることで、ユーザーが愛用したくなるソリューションへと導く独自の視点が得られます。
誰もがやっていることに従いたくなる誘惑に駆られることがあるかもしれませんが、それが皆が不満を漏らし続けている不便さを我慢することにつながるとしても、そうすべきではありません。アプリのアーカイブをどのように想像していますか?コード署名をどのようにあるべきだと考えていますか?Tuist でどのプロセスを効率化できますか?例えば、Fastlane のサポートを追加することは、まず理解すべき問題に対する解決策です。「なぜ」と問いかけることで、問題の根本原因にたどり着くことができます。動機の出所を特定したら、Tuist がどのように最善の支援を提供できるかを考えます。解決策が Fastlane との統合である可能性もありますが、トレードオフを検討する前に検討できる他の同等に有効な解決策を無視しないことが重要です。
エラーは発生しうる#
私たち開発者は、エラーが発生しうることを軽視してしまう固有的な誘惑を抱えています。その結果、理想的なシナリオのみを考慮してソフトウェアを設計・テストしてしまいます。
Swift、その型システム、そして適切に設計されたコードは、一部のエラーを防ぐのに役立ちますが、すべてを防げるわけではありません。制御できない要因もあるからです。ユーザーが常にインターネット接続を持っていると想定したり、システムコマンドが常に成功すると想定することはできません。Tuist が実行される環境は、私たちが制御するサンドボックスではないため、それらがどのように変化し、Tuist に影響を与えるかを理解する努力が必要です。
エラー処理が不十分だとユーザー体験が悪化し、プロジェクトへの信頼を失う可能性があります。私たちは、ユーザーが Tuist のあらゆる部分、さらにはエラーの提示方法さえも楽しめるようにしたいと考えています。
ユーザーの立場に立ち、エラーから何を伝えられるべきかを想像すべきです。プログラミング言語がエラーを伝達する通信チャネルであり、ユーザーがエラーの受け手であるなら、エラーメッセージは対象(ユーザー)が話す同じ言語で記述されるべきです。何が起こったかを把握するのに十分な情報を含め、関連性の低い情報は隠すべきです。また、回復のために取れる手順を示すことで、実行可能なものにするべきです。
最後に、テストケースは失敗するシナリオも考慮すべきです。これにより、想定通りにエラーを処理していることを保証できるだけでなく、将来の開発者がそのロジックを壊すのを防ぎます。