Skip to content
This repository has been archived by the owner on May 29, 2024. It is now read-only.

Creator: Create a Custom Generator

Tako Schotanus edited this page Jul 27, 2019 · 8 revisions

Creating a Generator

Try not to make a Generator do too much, think of who would be maintaining the module for example. If a Generator could generate the code for all the available languages it would soon become pretty complex and all the different people or teams that have the necessary expertise for their particular language would have to collaborate on that one module. Better to create one module for each language. If there are many common elements, for example they use a lot of the same supporting non-code files, consider splitting those out into a different Generator.

So make Generators simple, split them up into several different Generators and move any remaining complexity to the Capabilities.

These are the requirements for making a Generator:

  • Generators need resources that are stored subfolders of the catalog/generators folder in the resources/META-INF folder of the Creator module
  • The folder name should be lower case and only contain letters (eg. "superduper")
  • Any files that have to be copied should be contained in a sub folder called files
  • A file named info.json must exist with the following contents:
{
  "type": "generator",
  "name": "Short description",
  "description": "Some longer description for the Generator"
}
  • Generators also need a class that must be created in the io.fabric8.launcher.creator.catalog.generators package
  • The class must have the same name as the folder but now Camel Cased (and without dashes, eg. "SuperDuper")
  • The class must implement Generator.
  • It's recommended the class extends BaseGenerator.

The Generator class

A Generator must normally do a bunch of menial tasks: generate OpenShift resources, copy files, make changes to configuration. That sort of thing. All of that is done in a single method that gets called when the Generator gets "applied" to the project that we're generating. To do that it must implement Generator.

This is what the API looks like:

fun apply(resources: Resources, props: Properties, extra: Properties): Resources

When called this method allows the Generator to make changes to the project we're generating and to the OpenShift/K8s Resources list that get passed in. Files can be copied and/or generated. It's also possible to update already pre-existing files (for example to add new dependencies a Maven POM file). When the Generator also needs new Resources to be created in the user's OpenShift project it can add them to the list that gets passed in and in the end that will be sent to OpenShift.

See Implementation Details for more details on using this API.

Adding support for a new Language

A "Language Generator" is a Generator that handles the basic support requirements for a Language or Platform like Java or Node.js. It means that it's responsible for setting up a project to be used with that particular Language or Platform. Language Generators are normally the first Generator that gets applied when creating a new project, so they should contain all the necessary files to get a project up-and-running for that particular Language or Platform.

Requirements for a Language Generator:

  • Everything that's required for all Generators.
  • A set of common files that all projects using that Language will need. This normally includes all configuration and build files. At also includes any code that will be shared among all Capabilities.
  • The files should contain a generic README.
  • The Generator folder should be named "languagename" where "name" is the lowercase name of the Language you want to implement
  • The Generator class should be named "LanguageName" where "Name" is camel cased.

The whole idea of a Language Generator is to put as much of the common files and code together into a single place. Other Generators that want to implement a certain feature on top of that language would then use the Language Generator to do most of the heavy lifting: for example they won't have to worry about the OpenShift resources anymore because in most cases what the Language Generator has added will be sufficient. They would most likely still have a files folder but there would be a lot less files in there because you'd only need to store the files that are not available in the Runtime Generator.

Adding support for a new Runtime

A "Runtime Generator" is a Generator that handles the basic support requirements for a Runtime like Vert.x, Spring Boot or React. It means that it's responsible for setting up a project to be used with that particular Runtime. Runtime Generators are normally the next layer on top of a Language Generator. They handle the extra files and configuration needed, on top of the base created by a Language Generator, to get project to run with that particular Runtime.

Requirements for a Runtime Generator:

  • Everything that's required for all Generators.
  • A set of common files that all projects using that Runtime will need. This normally includes all configuration and any changes to build files. At also includes any code that will be shared among all Capabilities.
  • The files should contain a generic README.
  • The Generator folder should be named "runtimename" where "name" is the lowercase name of the Runtime you want to implement
  • The Generator class should be named "RuntimeName" where "Name" is camel cased.
  • Update the runtime section in the META-INF/catalog/enums.yaml to add an entry for your new runtime.
  • Update the props.runtime.values in the info.json files of all the Capabilities that have support for your new runtime.
  • Update the code in the Capabilities that deal with runtimes. Look for runtimeByType().

Like with Language Generators, the whole idea of a Runtime Generator is to put as much of the common files and code together into a single place. Other Generators that want to implement a certain feature on top of that runtime would then use the Runtime Generator to do most of the heavy lifting.