エクステンション Codestart
このガイドでは、エクステンションのために Quarkus Codestart を作成および設定する方法について説明します。
説明
"Extension Codestarts" is the name we give to our Quarkus extension "getting started" code generation system. It aims to provide a personalized getting started experience with Quarkus. A Quarkus extension is able to provide one or more well-defined codestarts which will contain the resources and code required/recommended to start using that particular extension.
エクステンション Codestart は、Quarkus ツールを使用するときにデフォルトで適用されます (選択したエクステンションに含まれている場合)。
-
code.quarkus.io([code]とタグ付けされたエクステンションを探す)
-
Quarkus Maven プラグイン:
mvn io.quarkus.platform:quarkus-maven-plugin:create
-
Quarkus CLI
quarkus create app
動作原理
プロジェクトを開始する際には、言語、ビルドツール、フレームワークを選択し、Dockerfile、CI、依存関係、コードを追加していきます。
Codestart は、プロジェクトの生成に貢献する際に同じように働き、2つのカテゴリーに分けられます。
"ベース" のコードスタート(この組み合わせを選択):
-
project: プロジェクトの骨組(例:Quarkusプロジェクト)
-
buildtool: ビルドツール(例:Maven、Gradle、Gradle with Kotlin DSL)
-
language: コーディング言語(例:Java、Kotlin、Scala)
-
config: 設定の種類(例:yaml、properties)
追加の Codestart (必要に応じて、基本コードの上に追加):
-
tooling:プロジェクトを改善するために追加できるもの(例: Dockerfiles、GitHub Actions など)
-
code: どのQuarkusエクステンションもスターターコードを提供可能です。ユーザーはそれを有効にするかどうかを決めることができます。
各 Codestart は以下から構成されています:
-
Codestartのユニークな名前、つまり
my-codestart
-
Codestartファイルを置くディレクトリ、つまり
my-codestart/
-
codestart.yml
ファイル -
共通の構造と命名規則に従ったいくつかのテンプレート(オプション)
ベース Codestart
ベース Codestart には、プロジェクト、ビルドツール、言語、設定、ツールファイルを作成するためのテンプレートが含まれています。
さらに、Quarkusには、コードスタートで新しいエクステンションプロジェクトを初期化する次のような方法も用意されています。
エクステンション Codestart の作成
以下は、エクステンション Codestart を作成するためのステップバイステップのガイドです。 Quarkus Insight #99 のライブコーディングセッションもご覧ください。
前述したように、プロジェクトの基本ファイル (pom.xml、Dockerfile など) は、Quarkus コアが提供するベース Codestart ですでに生成されています。このおかげで、エクステンションのスターターコードにのみ集中することができます。
エクステンション GAV の例として io.quarkiverse.aloha:quarkus-aloha
を見てみましょう (このエクステンションは存在しませんので探さないでください)。
コード
Codestart は、新しいプロジェクトの足場を作るためのテンプレートです。
このチュートリアルでは、Quarkus プロジェクトから Codestart プロジェクトを作成し、必要なテンプレートを追加します。
したがって、 code.quarkus.io に移動し、aloha エクステンションとグループとして org.acme
を使用して新しいプロジェクトを作成します (つまり、 パッケージ名の org.acme
プレースホルダー )。素敵なスターターを用意してください。ビジネスロジックを含める必要はありません。代わりに、コンパイルしてエクステンションの使用方法の概要を示すスタブデータ/Hello World を含める必要があります。このアイデアは、エクステンションの最も一般的な開始点となるコードを提供することにあります。
コードに満足していますか? そこから Codestart を作成しましょう。
Codestart (Quarkiverse またはスタンドアロンエクステンション)
エクステンションの中で:
-
runtime/src/main/codestarts/quarkus/aloha-codestart
ディレクトリーを作成します -
src/main/java
を、生成されたプロジェクトからruntime/src/main/codestarts/quarkus/aloha-codestart/java/src/main/java
に移動します -
(オプション) この規約でコンフィグを移動します: アプリケーション設定 application.yml
-
codestart.yml
runtime/src/main/codestarts/quarkus/aloha-codestart
でのファイルの作成:name: aloha-codestart ref: aloha type: code tags: extension-codestart metadata: title: Aloha description: Start to code with the Aloha extension. related-guide-section: https://quarkiverse.github.io/quarkiverse-docs/quarkus-aloha/dev/ path: /aloha # (optional) for web extensions providing HTTP resources
-
Maven ビルドプラグイン設定を
runtime/pom.xml
に追加します (Codestart アーティファクトを生成するには:/target/quarkus-aloha-VERSION-codestarts.jar
):<plugin> <artifactId>maven-jar-plugin</artifactId> <executions> <execution> <id>generate-codestart-jar</id> <phase>generate-resources</phase> <goals> <goal>jar</goal> </goals> <configuration> <classesDirectory>${project.basedir}/src/main</classesDirectory> <includes> <include>codestarts/**</include> </includes> <classifier>codestarts</classifier> <skipIfEmpty>true</skipIfEmpty> </configuration> </execution> </executions> </plugin>
-
エクステンションメタデータ
runtime/src/main/resources/META-INF/quarkus-extension.yaml
に Codestart バインディングを追加します。 これがないと、エクステンションが選択されたときに Codestart が追加されません :name: ... description: ... metadata: ... codestart: name: "aloha" languages: - "java" artifact: "io.quarkiverse.aloha:quarkus-aloha:codestarts:jar:${project.version}"
-
README.md
base/README.tpl.qute.md
のセクションテンプレートに readme を追加します:{#include readme-header /}
-
エクステンションのルート (または単に
runtime
) でmvn clean install
を実行します。 -
これで、エクステンションを使用するプロジェクトを作成して、Codestart が実際に機能することを確認できます (スナップショットのバージョンが正しいことを確認してください)。
quarkus create app aloha-app -x=io.quarkiverse.aloha:quarkus-aloha:999-SNAPSHOT ... applying codestarts... 📚 java 🔨 maven 📦 quarkus 📝 config-properties 🔧 dockerfiles 🔧 maven-wrapper 🚀 aloha-codestart <<<<<<<<<<<<<<<< ...
テスト
-
この依存関係を
integration-tests
に追加します。<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-devtools-testing</artifactId> <scope>test</scope> </dependency>
-
integration-tests
にAlohaCodestartTest
を作成します。public class AlohaCodestartTest { @RegisterExtension public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest.builder() .languages(Language.JAVA) .setupStandaloneExtensionTest("io.quarkiverse.aloha:quarkus-aloha") .build(); @Test void testContent() throws Throwable { codestartTest.checkGeneratedSource("org.acme.AlohaResource"); } @Test void buildAllProjects() throws Throwable { codestartTest.buildAllProjects(); } }
さらに詳しく
-
エクステンションが Web リソースを提供する場合は、
base/src/main/resources/META-INF/resources/index.entry.qute.html
テンプレート (index.htmlとWebエクステンションの Codestart) を追加します。 -
別の言語を追加します (Java と Kotlin を提供することをお勧めします)。
-
他のリソースを追加することもできます (言語固有でない場合は、
./base
ディレクトリーに)。
Quarkus Coreのエクステンション Codestart
-
Codestart はすべて 特定のモジュール のグループにあります。
-
追加の Maven 設定は必要ありません。
-
エクステンションメタデータ は、すべてのコア・コードスタートを含むアーティファクトを参照します。
-
また、テストは グループ化 されています。ビルドのテストは、それ専用のグループ化された テスト があるので、必要ありません。例えば
public class ConfigYamlCodestartTest { @RegisterExtension public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest.builder() .codestarts("config-yaml") .languages(JAVA, KOTLIN) .build(); @Test void testContent() throws Throwable { codestartTest.checkGeneratedSource("org.acme.GreetingConfig"); codestartTest.assertThatGeneratedFileMatchSnapshot(JAVA, "src/main/resources/application.yml"); } @Test @EnabledIfSystemProperty(named = "build-projects", matches = "true") void buildAllProjectsForLocalUse() throws Throwable { codestartTest.buildAllProjects(); } }
具体的なトピック
パッケージ名の org.acme
プレースホルダー
エクステンションの Codestart のソースでは、パッケージ名として org.acme
を使用する必要があります。生成されたプロジェクトでは、ユーザーが指定したパッケージが使用されます (そして、 org.acme
を自動的に置き換えます)。
パッケージは、すべてのソースファイル (.java、.kt、.scala) で自動的に置換されます。パッケージのディレクトリーも自動的に調整されます。もし、何らかの理由で、他のタイプのファイルがユーザーパッケージ名を必要とする場合、そのファイルおよび {project.package-name}
データプレースホルダー (grpc proto ファイルにおけるサンプル). に テンプレート(Qute) を使用すべきです。
codestart.yml
# codestart unique name
name: resteasy-example
# codestart reference, use the extension id
ref: resteasy
# use 'code' (other types are for base codestarts)
type: code
# use 'extension-codestart'
tags: extension-codestart
# public metadata for this example (accessible as data in the templates e.g. {title})
metadata:
title: RESTEasy Jakarta REST example
description: Rest is easy peasy with this Hello World RESTEasy resource.
related-guide-section: https://quarkus.io/guides/getting-started#the-jax-rs-resources
# (optional) use this in web extensions with a specific path (and also add the index page)
path: /some-path
ディレクトリ構造
codestart.yml は唯一の必須ファイルです。
|
-
codestart.yml
は Codestart のルートに配置される必要があります。 -
./base
には、指定された言語とは無関係に処理されるすべてのファイルが含まれます -
./[java/kotlin/scala]
は、指定された言語が選択されている場合にのみ処理されるすべてのファイルを含みます(baseをオーバーライドします)
Codestart の動的設定キー
gen-info.time = generation time (in milliseconds)
input.selected-extensions[].name|description|guide = list of selected extensions with info
input.selected-extensions-ga = Set of Strings containing the list of extensions groupId:artifactId, useful for dynamic codestarts depending on selected extensions
input.provided-code[].name|tags|title|description|related-guide: list of selected codestarts with info
Codestart の静的設定キー
quarkus.platform.group-id = BOM groupId
quarkus.platform.artifact-id = BOM artifactId
quarkus.platform.version = BOM version
project.group-id = Project groupId
project.artifact-id = Project artifactId
project.version = Project version
project.name = Project name (if specified)
project.description = Project description (if specified)
project.package-name = Project package name
quarkus.maven-plugin.group-id = Quarkus Maven plugin groupId
quarkus.maven-plugin.artifact-id = Quarkus Maven plugin artifactId
quarkus.maven-plugin.version = Quarkus Maven plugin version
quarkus.gradle-plugin.id = Quarkus Gradle pluginId
quarkus.gradle-plugin.version = Quarkus Gradle plugin version
quarkus.version = Quarkus version
java.version = Java version
kotlin.version = Kotlin version
scala.version = Scala version
scala-maven-plugin.version = Scala Maven plugin version
maven-compiler-plugin.version = Maven compiler plugin version
maven-surefire-plugin.version = Maven Surefire plugin version
ファイルの命名規則
-
.tpl.qute
は、Quteで処理され、データを使用することができます(出力ファイル名から.tpl.qute
が削除されます)。 -
readme.md
,src/main/resources/application.yml
,src/main/resources/META-INF/resources/index.html
などの特定の共通ファイルは、プロジェクトに対して選択された Codestart で見つかった収集済みフラグメントから生成されます。 -
他のファイルはコピーされます。
テンプレート(Qute)
Codestartは、ダイナミックレンダリングのために Qute テンプレート MyClass.tpl.qute.java
を使用することができます。
これらのテンプレートは、以下を含むデータを使用することができます:
-
生成するCodestartの
data
(および公開metadata
)(codestart.yml
で指定されている) -
プロジェクトの生成に使用されたすべてのCodestartから
shared-data
をマージしたもの -
ユーザー入力
-
いくつかの動的に生成されたデータ(例:
dependencies
やtest-dependencies
)
README.md
base
ディレクトリに README.md
や README.tpl.qute.md
を追加することが出来ます。他のものに追加されます。つまり、エクステンション codestart に関連する情報を追加するだけです。
base/README.tpl.qute.md
{#include readme-header /}
[Optionally, Here you may add information about how to use the example, settings, ...]
{#include readme-header /} は、Quarkus プロジェクトの Codestart にある、 codestart.yml メタデータから標準的な情報を表示するテンプレートを使用することになります。
|
アプリケーション設定 application.yml
慣習として、Quarkusの設定は常にyamlファイル( base/src/main/resources/application.yml
)として提供する必要があります。
次のようになります:
-
他のエクステンション Codestart の設定とマージされます
-
選択されたエクステンションに応じて、生成時に選択された設定タイプ(yamlまたはproperties)に自動的に変換されます
index.htmlとWebエクステンションの Codestart
エクステンションの Codestart では、このファイルを追加することで、生成されるindex.htmlにスニペットを提供することができます。
base/src/main/resources/META-INF/resources/index.entry.qute.html:
{#include index-entry /}
{#include index-entry /} は、Quarkus プロジェクトの Codestart にある、 codestart.yml メタデータから標準的な情報を表示するテンプレートを使用することになります。
|
統合テスト
エクステンションの Codestart をテストするためのエクステンション QuarkusCodestartTest
が利用可能です。
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devtools-testing</artifactId>
<scope>test</scope>
</dependency>
以下をテストする方法を提供します。
-
スナップショットテストを用いて、生成されたプロジェクトコンテンツ(不変のモックデータを含む)
-
生成されたプロジェクトのビルド/実行(実データを使用)、およびビルドを実行するためのヘルパー
すべてのテストの前に、このエクステンションは、指定された言語で、指定されたCodestartで、モックされたデータと実際のデータを使ってQuarkusプロジェクトを生成します。生成されたプロジェクトは、 target/quarkus-codestart-test ディレクトリにあります。 real-data のプロジェクトは IDE で開くことができますし、ターミナルで操作することもできます。 実データは、エクステンションCodestartの開発を繰り返し行う最も簡単な方法です。
|
このエクステンションは、プロジェクトのビルド buildAllProjects
や、特定の言語のプロジェクト buildProject (Language language)
をテストするヘルパーを提供します。また、 スナップショットテスト でコンテンツをテストするヘルパーも提供しています。
ConfigYamlCodestartTestは、Quarkus coreにおける良い例です。
スナップショットテスト
スナップショット テストとは、テストによって生成されるコンテンツが、あるリビジョンから別のリビジョン、つまりコミット間で変更されないようにする方法です。つまり、コミットごとに生成されるコンテンツは、不変であり、決定性がある必要があります(これが、モックされたデータを使用する理由です)。このようなチェックを行うために、生成されたコンテンツのスナップショットを自動生成し、後続のテスト実行時に期待される出力の参照先としてコミットします。テンプレートが変更された場合は、生成されたスナップショットの変更もコミットします。このようにして、レビューの際には、適用されたコードの変更が、生成された出力に対して期待される効果を持つことを確認することができます。
エクステンションは、コンテンツをチェックするためのヘルパーを提供します:
-
checkGeneratedSource()
は、すべての言語(または特定の言語)のスナップショットに対してクラスを検証します。 -
checkGeneratedTestSource()
は、すべての言語(または特定の言語)のスナップショットに対してテストクラスを検証します。 -
assertThatGeneratedFileMatchSnapshot()
は、プロジェクトファイルをスナップショットと照合します。 -
上記のメソッドの戻り値に
AbstractPathAssert.satisfies(checkContains("some content"))
または任意の Path アサートを使用して、ファイルに特定のコンテンツが含まれているかどうかを確認することもできます。 -
assertThatGeneratedTreeMatchSnapshots()
では、特定の言語のプロジェクトのファイル構造(ツリー)を、そのスナップショットと比較することができます。
ローカルファイルシステム上の既存のスナップショットファイルを最初に生成または更新するためには、Codestartの開発中にローカルでテストを実行する際に、 -Dsnap を追加する必要があります。これらはコミットの一部として追加する必要があり、そうしないとCI上でテストが通過しません。
|
作成のコツ
-
あなたのエクステンションCodestartは、buildtoolやdockerfilesから独立していなければなりません/しなければなりません。
-
エクステンションCodestartは、互いに干渉することなく(組み合わせて)一緒に使えるべきです。
-
クラス名がすべてのエクステンションのCodestartでユニークであることを担保してください。
-
パッケージ名には
org.acme
のみを使用してください。 -
RESTのパスには、ユニークなパス
/[unique]
を使用してください。 -
設定は
src/main/resources/application.yml
ymlに記述してください。これは、他の Codestart のコンフィグとマージされ、選択された設定タイプ (yaml または properties) に自動的に変換されます。
-
javaから始めて、後で別のPRでkotlinを追加することもできます(忘れないようにissueを作成してください)。
-
質問がある場合は、 https://quarkusio.zulipchat.com/ で @ia3andy に ping してください。