mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-07-06 07:31:01 +00:00
[bug] Templates via classpath (#5164)
* Fixes issue with templates loading via classpath The templating engines were originally written to load templates via the classpath, but this functionality was blocked by file-only checks further up the stack. This loosens those file-only checks, allowing files and relatively imported files to be included via classpath. * [docs] Add details about classpath-level templates * [feat][maven] templateResourcePath for template on classpath - NOTE templateResourcePath is not needed for gradle, as it accepts a string for the target template directory, which supports classpath
This commit is contained in:
parent
22c6c0ca68
commit
507f80617d
@ -26,6 +26,29 @@ OpenAPI Generator supports user-defined templates. This approach is often the ea
|
||||
|
||||
> **Note:** You cannot use this approach to create new templates, only override existing ones. If you'd like to create a new generator to contribute back to the project, see `new.sh` in the repository root. If you'd like to create a private generator for more templating control, see the [customization](./customization.md) docs.
|
||||
|
||||
OpenAPI Generator not only supports local files for templating, but also templates defined on the classpath. This is a great option if you want to reuse templates across multiple projects. To load a template via classpath, you'll need to generate a little differently. For example, if you've created an artifact called `template-classpath-example` which contains extended templates for the `htmlDocs` generator with the following structure:
|
||||
|
||||
```
|
||||
└── src
|
||||
├── main
|
||||
│ ├── java
|
||||
│ └── resources
|
||||
│ └── templates
|
||||
│ └── htmlDocs
|
||||
│ ├── index.mustache
|
||||
│ └── style.css.mustache
|
||||
```
|
||||
|
||||
You can define your classpath to contain your JAR and the openapi-generator-cli _fat jar_, then invoke main class `org.openapitools.codegen.OpenAPIGenerator`. For instance,
|
||||
|
||||
```sh
|
||||
java -cp /path/totemplate-classpath-example-1.0-SNAPSHOT.jar:modules/openapi-generator-cli/target/openapi-generator-cli.jar \
|
||||
org.openapitools.codegen.OpenAPIGenerator generate -i https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml \
|
||||
-g html -o template-example -t templates/htmlDocs
|
||||
```
|
||||
|
||||
Note that our template directory is relative to the resource directory of the JAR defined on the classpath.
|
||||
|
||||
### Custom Logic
|
||||
|
||||
For this example, let's modify a Java client to use AOP via [jcabi/jcabi-aspects](https://github.com/jcabi/jcabi-aspects). We'll log API method execution at the `INFO` level. The jcabi-aspects project could also be used to implement method retries on failures; this would be a great exercise to further play around with templating.
|
||||
|
@ -21,6 +21,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -406,15 +409,29 @@ public class WorkflowSettings {
|
||||
*/
|
||||
public Builder withTemplateDir(String templateDir) {
|
||||
if (templateDir != null) {
|
||||
URI uri = null;
|
||||
File f = new File(templateDir);
|
||||
|
||||
// check to see if the folder exists
|
||||
if (!(f.exists() && f.isDirectory())) {
|
||||
if (f.exists() && f.isDirectory()) {
|
||||
uri = f.toURI();
|
||||
this.templateDir = Paths.get(uri).toAbsolutePath().toString();
|
||||
} else {
|
||||
URL url = this.getClass().getClassLoader().getResource(templateDir);
|
||||
if (url != null) {
|
||||
try {
|
||||
uri = url.toURI();
|
||||
this.templateDir = templateDir;
|
||||
} catch (URISyntaxException e) {
|
||||
LOGGER.warn("The requested template was found on the classpath, but resulted in a syntax error.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Template directory " + templateDir + " does not exist.");
|
||||
}
|
||||
|
||||
this.templateDir = Paths.get(f.toURI()).toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -48,6 +48,7 @@ mvn clean compile
|
||||
| `generatorName` | `openapi.generator.maven.plugin.generatorName` | target generator name
|
||||
| `output` | `openapi.generator.maven.plugin.output` | target output path (default is `${project.build.directory}/generated-sources/openapi`. Can also be set globally through the `openapi.generator.maven.plugin.output` property)
|
||||
| `templateDirectory` | `openapi.generator.maven.plugin.templateDirectory` | directory with mustache templates
|
||||
| `templateResourcePath` | `openapi.generator.maven.plugin.templateResourcePath` | directory with mustache templates via resource path. This option will overwrite any option defined in `templateDirectory`.
|
||||
| `addCompileSourceRoot` | `openapi.generator.maven.plugin.addCompileSourceRoot` | add the output directory to the project as a source root (`true` by default)
|
||||
| `modelPackage` | `openapi.generator.maven.plugin.modelPackage` | the package to use for generated model objects/classes
|
||||
| `apiPackage` | `openapi.generator.maven.plugin.apiPackage` | the package to use for generated api objects/classes
|
||||
|
@ -40,6 +40,7 @@ import java.util.Set;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.CharSource;
|
||||
import io.swagger.v3.parser.util.ClasspathHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
@ -133,6 +134,12 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
@Parameter(name = "templateDirectory", property = "openapi.generator.maven.plugin.templateDirectory")
|
||||
private File templateDirectory;
|
||||
|
||||
/**
|
||||
* Resource path containing template files.
|
||||
*/
|
||||
@Parameter(name = "templateResourcePath", property = "openapi.generator.maven.plugin.templateResourcePath")
|
||||
private String templateResourcePath;
|
||||
|
||||
/**
|
||||
* The name of templating engine to use, "mustache" (default) or "handlebars" (beta)
|
||||
*/
|
||||
@ -583,6 +590,13 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
configurator.setTemplateDir(templateDirectory.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(templateResourcePath)) {
|
||||
if (null != templateDirectory) {
|
||||
LOGGER.warn("Both templateDirectory and templateResourcePath were configured. templateResourcePath overwrites templateDirectory.");
|
||||
}
|
||||
configurator.setTemplateDir(templateResourcePath);
|
||||
}
|
||||
|
||||
if (null != engine) {
|
||||
configurator.setTemplatingEngineName(engine);
|
||||
}
|
||||
|
@ -161,14 +161,14 @@ public abstract class AbstractGenerator implements TemplatingGenerator {
|
||||
if (StringUtils.isNotEmpty(library)) {
|
||||
//look for the file in the library subfolder of the supplied template
|
||||
final String libTemplateFile = buildLibraryFilePath(config.templateDir(), library, templateFile);
|
||||
if (new File(libTemplateFile).exists()) {
|
||||
if (new File(libTemplateFile).exists() || this.getClass().getClassLoader().getResource(libTemplateFile) != null) {
|
||||
return libTemplateFile;
|
||||
}
|
||||
}
|
||||
|
||||
//check the supplied template main folder for the file
|
||||
final String template = config.templateDir() + File.separator + templateFile;
|
||||
if (new File(template).exists()) {
|
||||
if (new File(template).exists() || this.getClass().getClassLoader().getResource(template) != null) {
|
||||
return template;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user