<commit_before>[[configuration-guide]]
= Configuration Guide

[partintro]
--
You can use Spring Initializr to create your own service that can generate JVM projects.
This section describes how you can create your own service and tune it for
your needs, and also how you can configure an existing service.
--

[[project-generation-overview]]
== Project Generation Overview

Before getting into <<#create-instance, creating your own service>>, let's take a look at
the core concepts of project generation and how the library is structured to support them.

Initializr is split across several modules:

* `initializr-actuator`: optional module to provide additional information and statistics
on project generation.
* `initializr-bom`: provides a Bill of Materials for easier dependency management in your
project.
* `initializr-docs`: documentation.
* `initializr-generator`: core project generation library.
* `initializr-generator-spring`: optional module defining the conventions for a typical
Spring Boot project. Can be reused or replaced by your own conventions.
* `initializr-generator-test`: test infrastructure for project generation.
* `initializr-metadata`: metadata infrastructure for various aspects of the project.
* `initializr-service-sample`: showcases a basic custom instance.
* `initializr-version-resolver`: optional module to extract version numbers from an
arbitrary POM.
* `initializr-web`: web endpoints for third party clients.

To understand concepts behind project generation, let's take a look at
`initializr-generator` and `initializr-generator-spring` in a little more detail.



[[initializr-generator]]
=== Initializr Generator
The `initializr-generator` module contains the low-level infrastructure necessary to
generate JVM-based projects.



[[initializr-generator-project]]
==== Project Generator
The `ProjectGenerator` class is the main entry point for project generation. A
`ProjectGenerator` takes a `ProjectDescription` that defines a particular project to
generate as well as an implementation of `ProjectAssetGenerator` that is responsible to
generate assets based on available candidates.

A project is defined by `ProjectDescription` which consists of the following properties:

* Basic coordinates such as `groupId`, `artifactId`, `name`, `description`
* The `BuildSystem` and `Packaging`
* The JVM `Language`
* The requested dependencies, indexed by ID
* A platform `Version` used by the project. This can be used to tune available
dependencies according to the chosen generation.
* The name of the `application`
* The root package name
* The base directory for the project (if different from the root)

Project generation occurs in a dedicated application context (`ProjectGenerationContext`),
which means that for every project that is generated, the context only contains
configuration and components relevant to that particular project. Candidate components for
a `ProjectGenerationContext` are defined in `@ProjectGenerationConfiguration`-annotated
configuration classes. These configuration classes are imported automatically if they are
registered in `META-INF/spring.factories`, as shown in the following example:

[indent=0]
----
io.spring.initializr.generator.project.ProjectGenerationConfiguration=\
com.example.acme.build.BuildProjectGenerationConfiguration,\
com.example.acme.code.SourceCodeProjectGenerationConfiguration
----

Components that are added to the `ProjectGenerationContext` are generally made available
using conditions. Using conditions avoids exposing beans that have to check if they have
to do something and makes the declaration more idiomatic. Consider the following example:

[source,java,indent=0]
----
	@Bean
	@ConditionalOnBuildSystem(GradleBuildSystem.ID)
	@ConditionalOnPackaging(WarPackaging.ID)
	public BuildCustomizer<GradleBuild> warPluginContributor() {
		return (build) -> build.addPlugin("war");
	}
----

This registers a component that can customize a Gradle build only if the project to
generate uses the "Gradle" `BuildSystem` and "war" `Packaging`. Check the
`io.spring.initializr.generator.condition` package for more conditions. You can create
custom conditions easily by inheriting from `ProjectGenerationCondition`.

You can only use such conditions on beans that have been loaded on the
`ProjectGenerationConfiguration` as they require a concrete `ProjectDescription` bean
to operate properly.

Project generation may also rely on infrastructure that is not specific to a particular
project configuration and is usually configured in the main `ApplicationContext` to avoid
registering it every time a new request comes in. A common use case is to set the main
`ApplicationContext` as the parent of the `ProjectGenerationContext`, as shown in the
following example:

[source,java,indent=0,subs="verbatim,quotes,attributes"]
----<commit_msg>Fix sample code on how to add plugin conditionally<commit_after>[[configuration-guide]]
= Configuration Guide

[partintro]
--
You can use Spring Initializr to create your own service that can generate JVM projects.
This section describes how you can create your own service and tune it for
your needs, and also how you can configure an existing service.
--

[[project-generation-overview]]
== Project Generation Overview

Before getting into <<#create-instance, creating your own service>>, let's take a look at
the core concepts of project generation and how the library is structured to support them.

Initializr is split across several modules:

* `initializr-actuator`: optional module to provide additional information and statistics
on project generation.
* `initializr-bom`: provides a Bill of Materials for easier dependency management in your
project.
* `initializr-docs`: documentation.
* `initializr-generator`: core project generation library.
* `initializr-generator-spring`: optional module defining the conventions for a typical
Spring Boot project. Can be reused or replaced by your own conventions.
* `initializr-generator-test`: test infrastructure for project generation.
* `initializr-metadata`: metadata infrastructure for various aspects of the project.
* `initializr-service-sample`: showcases a basic custom instance.
* `initializr-version-resolver`: optional module to extract version numbers from an
arbitrary POM.
* `initializr-web`: web endpoints for third party clients.

To understand concepts behind project generation, let's take a look at
`initializr-generator` and `initializr-generator-spring` in a little more detail.



[[initializr-generator]]
=== Initializr Generator
The `initializr-generator` module contains the low-level infrastructure necessary to
generate JVM-based projects.



[[initializr-generator-project]]
==== Project Generator
The `ProjectGenerator` class is the main entry point for project generation. A
`ProjectGenerator` takes a `ProjectDescription` that defines a particular project to
generate as well as an implementation of `ProjectAssetGenerator` that is responsible to
generate assets based on available candidates.

A project is defined by `ProjectDescription` which consists of the following properties:

* Basic coordinates such as `groupId`, `artifactId`, `name`, `description`
* The `BuildSystem` and `Packaging`
* The JVM `Language`
* The requested dependencies, indexed by ID
* A platform `Version` used by the project. This can be used to tune available
dependencies according to the chosen generation.
* The name of the `application`
* The root package name
* The base directory for the project (if different from the root)

Project generation occurs in a dedicated application context (`ProjectGenerationContext`),
which means that for every project that is generated, the context only contains
configuration and components relevant to that particular project. Candidate components for
a `ProjectGenerationContext` are defined in `@ProjectGenerationConfiguration`-annotated
configuration classes. These configuration classes are imported automatically if they are
registered in `META-INF/spring.factories`, as shown in the following example:

[indent=0]
----
io.spring.initializr.generator.project.ProjectGenerationConfiguration=\
com.example.acme.build.BuildProjectGenerationConfiguration,\
com.example.acme.code.SourceCodeProjectGenerationConfiguration
----

Components that are added to the `ProjectGenerationContext` are generally made available
using conditions. Using conditions avoids exposing beans that have to check if they have
to do something and makes the declaration more idiomatic. Consider the following example:

[source,java,indent=0]
----
	@Bean
	@ConditionalOnBuildSystem(GradleBuildSystem.ID)
	@ConditionalOnPackaging(WarPackaging.ID)
	public BuildCustomizer<GradleBuild> warPluginContributor() {
		return (build) -> build.plugins().add("war");
	}
----

This registers a component that can customize a Gradle build only if the project to
generate uses the "Gradle" `BuildSystem` and "war" `Packaging`. Check the
`io.spring.initializr.generator.condition` package for more conditions. You can create
custom conditions easily by inheriting from `ProjectGenerationCondition`.

You can only use such conditions on beans that have been loaded on the
`ProjectGenerationConfiguration` as they require a concrete `ProjectDescription` bean
to operate properly.

Project generation may also rely on infrastructure that is not specific to a particular
project configuration and is usually configured in the main `ApplicationContext` to avoid
registering it every time a new request comes in. A common use case is to set the main
`ApplicationContext` as the parent of the `ProjectGenerationContext`, as shown in the
following example:

[source,java,indent=0,subs="verbatim,quotes,attributes"]
----
{'fraction_non_alphanumeric': 0.0667901615725018, 'fraction_numerical': 0.0006174745291756715, 'mean_word_length': 5.656164383561644, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5524613', 'n_tokens_mistral': 2345, 'n_tokens_neox': 2262, 'n_words': 1124}