From 0de12f17a7b67a5d5d97f0455616b687ec79bd83 Mon Sep 17 00:00:00 2001 From: Andy Damevin Date: Fri, 8 Jul 2022 10:36:46 +0200 Subject: [PATCH] Refresh codestart guide --- .../main/asciidoc/extension-codestart.adoc | 270 ++++++++++++------ 1 file changed, 181 insertions(+), 89 deletions(-) diff --git a/docs/src/main/asciidoc/extension-codestart.adoc b/docs/src/main/asciidoc/extension-codestart.adoc index 259b534dc92018..6a9071277b16d1 100644 --- a/docs/src/main/asciidoc/extension-codestart.adoc +++ b/docs/src/main/asciidoc/extension-codestart.adoc @@ -71,69 +71,189 @@ The https://github.com/quarkusio/quarkus/tree/main/independent-projects/tools/ba As was mentioned previously, the base project files (pom.xml, dockerfiles, ...) are already generated by base codestarts provided by the Quarkus core. Thanks to this, we can only focus on the important - the starter code for the extension. -The codestart should not include any business logic, instead, it should contain some stub data/hello world to compile. The idea is to bring code that is the starting point to everyone using the extension. +Let's take `io.quarkiverse.aloha:quarkus-aloha` as the example extension gav (don't search, it doesn't exist). -== Writing an Extension Codestart in Quarkus Core +=== The code -- Copy one of the existing https://github.com/quarkusio/quarkus/tree/main/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts[Quarkus core extension codestarts, window="_blank"]. If the code needs to expose a web resource, `resteasy-qute-codestart` could be a good base Otherwise, `config-yaml-codestart` could be a better starting point. More info on the <>. +Go to https://code.quarkus.io[code.quarkus.io, window="_blank"], create a new project with the aloha extension and `org.acme` as Group (i.e <>). Prepare a nice starter. It should not include any business logic, instead, it should contain some stub data/hello world to compile. The idea is to bring code that is the most common starting point for the extension. -- Edit the <>: +Happy with the code? Let's make a Codestart out of it. -- Create the extension binding in the extension metadata (https://github.com/quarkusio/quarkus/blob/main/extensions/config-yaml/runtime/src/main/resources/META-INF/quarkus-extension.yaml#L12-L17[example, window="_blank"]). *Thanks to this, the codestart is added when the user selects the extension* +=== The Codestart (Quarkiverse or Standalone extensions) -- Add the readme <> section template. +* Create `runtime/src/main/codestarts/quarkus/aloha-codestart` -- Add the code in the language folder (it is recommended to at least provide java and kotlin). *You have to use `org.acme` as the package name: <>*. It is possible to use <> if needed. +* Move `src/main/java` to `runtime/src/main/codestarts/quarkus/aloha-codestart/java/src/main/java` -- Optionally, Add the `index.html` section template (<>). +* (Optional) Move the config using this convention: <>. -- Optionally, add some resources (`./base` directory if they are non language specific) - -- Optionally, add the <>. +* Create a <> file in `runtime/src/main/codestarts/quarkus/aloha-codestart`: ++ +[source,yaml] +---- +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 +---- -- Create an <>. +* Add the Maven build plugin configuration in `runtime/pom.xml` (to generate the codestart artifact: `/target/quarkus-aloha-VERSION-codestarts.jar`): ++ +[source,xml] +---- + + maven-jar-plugin + + + generate-codestart-jar + generate-resources + + jar + + + ${project.basedir}/src/main + + codestarts/** + + codestarts + true + + + + +---- -- <> +* Add the codestart binding in the extension metadata `runtime/src/main/resources/META-INF/quarkus-extension.yaml`. *Without this, your codestart won't be added when your extension is picked*: ++ +[source,yaml] +---- +name: ... +description: ... +metadata: + ... + codestart: + name: "aloha" + languages: + - "java" + artifact: "io.quarkiverse.aloha:quarkus-aloha:codestarts:jar:${project.version}" +---- -== Writing an Extension Codestart in the Quarkiverse or standalone +* Add the readme <> section template in `base/readme.tpl.qute.md`: ++ +[source,html] +---- +{#include readme-header /} +---- -For extensions hosted outside the Quarkus core[https://github.com/quarkusio/quarkus] repository, codestarts will typically be located in the runtime module (with special instruction in the `pom.xml` to generate a separate codestart artifact). https://github.com/ia3andy/aloha-code/[Here, window="_blank"] is an example extension with a codestart and its tests. +* Run `mvn clean install` in the extension root (or just `runtime`). +* Tell me it works? ++ +[source,bash] +---- +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 <<<<<<<<<<<<<<<< +... +---- -[#generating] -== Generating your Extension Codestart +=== Testing -**You need to build your codestart with Maven to make it available in the tooling:** +* Add this dependency to the `integration-tests`: ++ +[source,xml] +---- + + io.quarkus + quarkus-devtools-testing + +---- -- First add the codestart and update the relevant extension's metadata yml file, and build it all (the codestart and the extension if in core). +* Create a `AlohaCodestartTest` in the `integration-tests`: ++ +[source,java] +---- -- In Quarkus core, you also have to rebuild the `devtools/bom-descriptor-json` module to bind the codestart with the extension in the platform descriptor. +public class AlohaCodestartTest { -=== With the tests + @RegisterExtension + public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest.builder() + .languages(Language.JAVA) + .setupStandaloneExtensionTest("io.quarkiverse.aloha:quarkus-aloha") + .build(); -You can use the <> to help develop your codestart with `buildAllProjects` (In Quarkus core we added `@EnabledIfSystemProperty(named = "build-projects", matches = "true")` because codestarts are already built together in another test from `QuarkusCodestartBuildIT`). + @Test + void testContent() throws Throwable { + codestartTest.checkGeneratedSource("org.acme.AlohaResource"); + } -Use `-Dbuild-projects=true` when running this test to generate the real project with your codestart. Open it with your IDE, then change the code and copy it back to the codestart (and iterate until you are happy with the result). + @Test + void buildAllProjects() throws Throwable { + codestartTest.buildAllProjects(); + } +} +---- -=== With the Quarkus tooling +=== Nearly there -NOTE: Using the tooling to generate your local extension codestart during dev is not yet available Quarkiverse/Standalone extension (Until then, you may use the tests and follow https://github.com/quarkusio/quarkus/issues/21165[#21165, window="_blank"] for updates). +* If the extension provide some web resources, add the `base/src/main/resources/META-INF/resources/index.entry.qute.html` template (<>). -Using the CLI or Maven plugin to generate a project with your codestart: +* Add another language (it is recommended to provide java and kotlin). -- If using the CLI, you'll probably need to add `-P=io.quarkus:quarkus-bom:999-SNAPSHOT` to the CLI's arguments to use your snapshot of the platform +* You may some other resources (`./base` directory if they are non language specific). -- Example CLI command: `quarkus create app -x smallrye-health --code --java -P=io.quarkus:quarkus-bom:999-SNAPSHOT` +=== Extensions codestarts in Quarkus Core -- Equivalent for the Maven plugin: `mvn io.quarkus:quarkus-maven-plugin:2.3.0.Final:create -Dextensions=smallrye-health -DplatformVersion=999-SNAPSHOT` +* The codestarts are all grouped in a https://github.com/quarkusio/quarkus/tree/main/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts[specific module, window="_blank"]. +* No extra Maven configuration is need needed. +* The https://github.com/quarkusio/quarkus/blob/main/extensions/resteasy-reactive/quarkus-resteasy-reactive-qute/runtime/src/main/resources/META-INF/quarkus-extension.yaml#L18[extension metadata, window="_blank"] reference the artifact containing all the core codestarts. +* The tests are also https://github.com/quarkusio/quarkus/tree/main/integration-tests/devtools/src/test/java/io/quarkus/devtools/codestarts/quarkus[grouped, window="_blank"]. You don't need to test the build as there is a specific grouped https://github.com/quarkusio/quarkus/blob/main/integration-tests/devtools/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartBuildIT.java[test, window="_blank"] for it. e.g.: ++ +[source,java] +---- +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(); + } + +} +---- == Specific topics [#org-acme-package] -=== Dynamic package name generation from org.acme +=== "org.acme" placeholder for package name -You have to use `org.acme` as the package name in your extension codestart sources. In the generated project, the user specified package will be used (and auto-replace `org.acme`). +You have to use `org.acme` as the package name in your extension codestart sources. In the generated project, the user specified package (or Group) will be used (and auto-replace `org.acme`). It will be auto-replaced in all the source files (.java, .kt, .scala). The package directory will also be automatically adjusted. If for some reason, another type of file needs the user package name then you should use a <> for it and `{project.package-name}` data placeholder (https://github.com/quarkusio/quarkus/blob/main/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts/grpc-codestart/base/src/main/proto/hello.tpl.qute.proto#L4[find an example in the grpc proto file, window="_blank"]). @@ -142,27 +262,21 @@ It will be auto-replaced in all the source files (.java, .kt, .scala). The packa [source,yaml] ---- -# the codestart unique name +# codestart unique name name: resteasy-example -# the codestart reference (the name is used if not set) +# codestart reference, use the extension id ref: resteasy -# the type of codestart (other types are used for other project files) +# use 'code' (other types are for base codestarts) type: code -# public metadata for this example (they will also be accessible from this codestart qute templates by using the key: {title}) +# use 'extension-codestart' +tags: extension-codestart +# public metadata for this example (accessible as data in the templates e.g. {title}) metadata: title: RESTEasy JAX-RS 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 - # the path is optional and used by the generated index.html if present + # (optional) use this in web extensions with a specific path (and also add the index page) path: /some-path -language: - base: - # Specify the extension and possibly other required dependencies - dependencies: - - io.quarkus:quarkus-resteasy - # And maybe test dependencies? - test-dependencies: - - io.rest-assured:rest-assured ---- [#directory-structure] @@ -178,57 +292,35 @@ NOTE: `codestart.yml` is the only required file. [source,bash] ---- -gen-info.time: time of generation (in millis) - -input.selected-extensions[].name|description|guide: list of selected extensions with info - -input.selected-extensions-ga: Set of String with the list of extensions groupId:artifactId, usefull for dynamic codestarts depending on selected extensions - +gen-info.time = time of generation (in millis) +input.selected-extensions[].name|description|guide = list of selected extensions with info +input.selected-extensions-ga = Set of String with the list of extensions groupId:artifactId, usefull for dynamic codestarts depending on selected extensions input.provided-code[].name|tags|title|description|related-guide: list of selected codestarts with info - ---- === Static Config Keys in Codestart -[source,bash] +[source,properties] ---- -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.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 +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.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 ---- === Naming Convention for files