-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a plugin architecture #846
Comments
It's been almost a year. Is there any plan to be able to bring in an external generator? I'm not sure we absolutely need an interface through maven. Our use case is that we need to tweak some of the generators (Kotlin, Swift) to do some logic specific to our needs, that cannot be done via template support only (It's mostly related to assigning a special type to some properties of a Model: decimal support, bitfield enums support, etc.). It would be great to simply be able to extend the existing generator in a new class and use that rather than forking the whole project and having to maintain the fork. PS: I didn't find any documentation for it. Do you think this is something that should be documented? Would you accept a PR for it? |
@lemoinem custom generators have been available since prior to our fork. We have documentation here: https://openapi-generator.tech/docs/customization and you can find an example of what you're hoping to achieve (extending a built-in generator) here: https://github.com/jimschubert/custom-generator-example The plugin stuff in this issue is more about internals (loading specs, json/yaml parsing, etc) in a way that users can do this easily via config rather than modifying classpath. We allow generator options via config which allows users to generate multiple outputs from the same file. This is useful for CI (see our own bin folder). The work described here would allow users to generate multiple outputs (with potentially conflicting dependencies) in a similar manner without orchestrating all the classpath stuff. |
Ok, I did find this documentation (customization is the first one I went to actually), but I overlooked it because it says "Creating a new template" which is not quite what I want... "Creating a new template" sounds more like overriding the template-dir than creating a new generator, but maybe it's just me. Thank you for the answer and more details. I'm looking forward to avoid classpath manipulation as well! |
Description
This is only relevant in the context of the Separation of Concerns project workflow.
Once we have enabled multiple extension points in the code:
We'd want an easy way for users to manage these for a per-invocation basis. I think this really only makes sense from the CLI level, as other entry points (embedding, Gradle or Maven plugins) can easily modify classpath for the generator.
A use case is described in #503, in which I propose a plugin architecture
In my prototype, I've also worked out loading external plugins on demand. The problem is a little more involved than is listed in the above discussion.
First, we need a clearly defined interface for the plugins. Then, we also need to separate the loading of plugins such that two conflicting versions aren't on the same classpath. My prototype does this by implementing a Maven repository system that downloads plugins on demand and allows you to define the repository directory for a given run.
As an example, my prototype has a configuration system with the following format:
This defaults to loading plugins from maven local (
~/.m2/repository
). Suppose my plugin isus.jimschubert:csharp:3.0
, but this version doesn't output C# 4.0 code as its support had been deprecated in the previous version and removed in the current version. As long as my core interfaces are the same, I can load the hypothetical previous version with C# 4.0 support fromus.jimschubert:csharp:2.9
and define a different maven location:This would result in all required artifacts being cached under
/src/generators/csharp-4.0-support
, and pulling only fromhttps://my-internal-nexus/
for this individual CLI run. I've only tested this a handful of times, but it seems especially useful for CI. I don't have environment variable interpolation or anything. (edit: also, the prototype doesn't support exclusions to allow advanced conflict resolution scenarios)NOTE: This plugin architecture and ability to load differing versions via config is only really relevant when running from CLI. I don't know of a way to load two different versions from classpath in the same JVM instance, and if there was a way I wouldn't recommend it.
Suggest a fix/enhancement
I'd created a plugin architecture for a personal prototype. This exists in a private repository, but we can reuse key snippets to get started.
NOTE The following code is written by and copyrighted me (unless otherwise noted). I grant permission for this code to be used in the openapi-generator project only, after which time the code will be available under the license terms of this project. If this code does not become integrated into openapi-generator, please contact me for licensing terms.
JSON Config loading (Kotlin)
Click to expand
CliConfig.kt
snippet.Click to expand
Config.kt
snippet.Click to expand
Delegates.kt
snippet.Maven embedded loading
Click to expand
ExtensionsLoader.kt
snippetClick to expand
ConsoleRepositoryListener.kt
snippet.Click to expand
ConsoleTransferListener.kt
snippet.Click to expand
MyURLClassLoader.kt
snippet.The above infrastructure would allow for multiple CLI invocations to use localized classpaths, reducing the complexity of CI scenarios.
For example, using my openapi-generator-cli.sh script, one could easily automate generation using conflicting extensions (and even exposed core interfaces!).
Suppose you maintain a Client SDK and one of your consumers is unable to update their system to newer versions of some technology, but openapi-generator has deprecated/removed your desired generator. This could happen to the C# 2.0 client generator, for instance.
With the above code snippets and a new option for targeting these configs via CLI (this doesn't exist yet), you could have:
config-old.json
The above is the older artifact, from an internal nexus repo.
config-current.json
Assuming you have an environment variable
OPENAPI_GENERATOR_CLIENTA
which holds the version of the generator supporting the hypothetically deprecated/removed workflow:The text was updated successfully, but these errors were encountered: