= Quarkus - Extension Codestarts
:toc: preamble
:toclevels: 3
:showtitle:

This guide explains how to create and configure a Quarkus Codestart for an extension.

== Description

"Extension Codestarts" is the name we gave to our Quarkus extension quickstart 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 necessary resources and code required to start using that particular extension.

You can play with the extension codestarts in the Quarkus tooling:

* The https://code.quarkus.io web app
* The Quarkus Maven plugin:
+
[source,bash]
----
mvn io.quarkus:quarkus-maven-plugin:create
----

* The Quarkus CLI:
+
[source,bash]
----
quarkus create app
----

Glossary:

* "Codestart(s)" is the tool (the code generator system).
* A "codestart" is a directory following a specific structure containing a `codestart.yml` and templates. It is used by the tool in combinations with other codestarts to generate a project.
* An "Extension codestart" is a specific codestart providing starter code for a Quarkus extension.

== How it works

There are two kinds of codestarts contributing to the generation of a project, the kind where we want to have only one for a project (called Base) and the rest (called Extra).

Base:

* project: The project skeleton (e.g. a Quarkus project)
* buildtool: The build tool (e.g. Maven, Gradle, Gradle with Kotlin DSL)
* language: The coding language (e.g. Java, Kotlin, Scala)
* config: The config type (e.g. yaml, properties)

Extra:

* tooling: Anything that can be added to improve the project (e.g. dockerfiles)
* code: Any Quarkus extension can provide example code. The user can decide to activate it or not.

Each codestart consists of:

. A codestart unique name, ie `my-codestart`
. A directory for the codestart files, ie `my-codestart/`
. A `codestart.yml` file
. Optionally some templates which following a common structure and naming conventions

== Where are the Quarkus Extension Codestarts located

* Extension codestarts directory: https://github.com/quarkusio/quarkus/tree/main/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts
* Quarkus base codestarts dir: https://github.com/quarkusio/quarkus/tree/main/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus-extension


== Writing an Extension Codestart

As we discussed before, the base project files (pom.xml, dockerfiles, ...) are already generated by some existing base codestarts. Thanks to this, we can only focus on the important, the starter code for the extension.

The codestart should not have any business code, 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.

This example extension contains a codestart & tests: https://github.com/ia3andy/aloha-code/

== Writing an Extension Codestart in Quarkus Core

1. Put it alongside the other core extensions codestarts:
https://github.com/quarkusio/quarkus/tree/main/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts

2. Add the metadata to the extension. Example:
https://github.com/quarkusio/quarkus/blob/main/extensions/config-yaml/runtime/src/main/resources/META-INF/quarkus-extension.yaml#L11-L16

3. Create an integration test like this one (to make sure the content is valid). You can also use it for dev using the `buildAllProjectsForLocalUse` (It's disabled by default because already covered by `QuarkusCodestartBuildIT`).
https://github.com/quarkusio/quarkus/blob/main/integration-tests/devtools/src/test/java/io/quarkus/devtools/codestarts/quarkus/ConfigYamlCodestartTest.java


=== Writing tips

* Your extension codestart must/should be independent of buildtool and dockerfiles
* Extension codestarts should be able to work alongside each other without interference
* Make sure your class names are unique across all extension codestarts.
* Use `org.acme` as package name.
* Use a unique path `/[unique]` for your REST paths
* Write the config in `src/main/resources/application.yml`.
+
It is going to be merged with the other codestarts config and automatically converted to the selected config type (yaml or properties).
* You can start with java and add kotlin later in another PR
* If the extension codestart is a bad citizen and may have some compatibility issues, make it an `example` instead.
* Ping me @ia3andy on https://quarkusio.zulipchat.com/

=== Directory Structure

*NOTE* `codestart.yml` is the only required file.

* `codestart.yml` must be at the root of the codestart
* `./base` contains all the files that will be processed
* `./[java/kotlin/scala]` contains all the files that will be processed if the specified language has been selected (overriding base)

=== codestart.yml

codestart.yml:
[source,yaml]
----
name: resteasy-example // the codestart unique name
ref: resteasy // the codestart reference (the name is used if not set)
type: code // the type of codestart (other types are used for other project files)
metadata: // metadata for this example to describe it outside (also available as data in the qute templates)
  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
language:
  base: //  most of the time, only base is needed (we may also define java, kotlin, scala overrides)
    dependencies:
      - io.quarkus:quarkus-resteasy // You need to specify the dependencies to add (even if it's the one attached)
    test-dependencies:
      - io.rest-assured:rest-assured // And maybe test dependencies?
----

== Advanced topics

=== Naming Convention for files

* `.tpl.qute` will be processed with Qute and can use data (`.tpl.qute` will be removed from the output file name).
* some files have a specific processing (`readme.md`, `src/test/resources/application.yml`, `src/main/resources/META-INF/resources/index.html`)
* other files are copied.

=== Templates (Qute)

Codestarts may use Qute templates `MyClass.tpl.qute.java` for dynamic rendering.

Those templates are able to use data which contains:

* The `data` of the codestart to generate (specified in the `codestart.yml`)
* A merge of the `shared-data` from the all the codestarts used to generate the project
* The user input
* Some dynamically generated data (e.g. `dependencies` and `test-dependencies`)

=== README.md

You may add a `README.md` or `README.tpl.qute.md` in the `base` directory, it will be appended to the others.
So just add the info relative to your extension codestart.

base/readme.tpl.qute.md
[source,html]
----
{#include readme-header /}

[Optionally, Here you may add information about how to use the example, settings, ...]
----

NOTE: The `{#include readme-header /}` will use a template located in the Quarkus project codestart which displays standard info from the `codestart.yml` metadata.

=== application.properties

As a convention, you should always provide the Quarkus configuration as a yaml file (`src/test/resources/application.yml`).

It is going to be:

* merged with the other extension codestarts configs
* automatically converted to the selected config type (yaml or properties) at generation time depending on the selected extensions

=== index.html and Cloud Extension codestarts

Extension codestarts may provide a snippet for the generated index.html by adding this file:

base/src/main/resources/META-INF/resources/index.entry.qute.html:
[source,html]
----
{#include index-entry /}
----

NOTE: The `{#include index-entry /}` will use a template located in the Quarkus project codestart which displays standard info from the `codestart.yml` metadata.


=== Example

You want to provide an example application which will be generated alone (without any other extension codestart)

This is a big constraint and should not be done when there is a choice:

* The extension can't be selected with another extension containing example if "code" is activated
* When selected, it will automatically disable all other extension codestarts

To make it an example:

* Put it in this directory: https://github.com/quarkusio/quarkus/tree/main/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/examples
* Add `example` in the tags:
+
codestart.yml
[source,yaml]
----
...
tags: example
...
----

== The generator sources

* Codestart generator: https://github.com/quarkusio/quarkus/tree/main/independent-projects/tools/codestarts
* Quarkus implementation of the Codestart generator: https://github.com/quarkusio/quarkus/tree/main/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus

== Issues and Feature requests

https://github.com/quarkusio/quarkus/labels/area%2Fcodestarts
