swagger-api / swagger-api/swagger-codegen

CLI needs extension mechanism for new, external Codegen classes

Open
#4,846 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Description

We want to add a new codegen target language (-l apidoc). However, this is for internal use and not appropriate to contribute to the open source project (it's a rewrite of the io.swagger.codegen.languages.StaticHtmlGenerator but uses our own custom templates, style sheets, JavaScript, etc.) However, when I build that as a separate project / jar file that depends on swagger-codegen, it is not easy to integrate with swagger-codegen-cli. The resource

META-INF/services/io.swagger.codegen.CodegenConfig

is embedded in the swagger-codegen-cli jar file. I have to copy that resource from swagger-codegen source into my own source directory and add my Codegen class name to it. so it gets built into our jar. (This is also fragile since if new Codegen classes are added to swagger-codegen, I won't have access to them until I copy the file again)

If I embed a copy of that file in our internal jar and run java -classpath my.jar;swagger-codegen-cli.jar , it works, but this complicates everything:
I must specify a classpath and main class on the command line (I can't distribute just a single jar). If I try to build an uber jar with code/resources from our project and swagger-codegen-cli, the build results in two copies of META-INF/services/io.swagger.codegen.CodegenConfig and the second one seems to win. Hence, my class is not loaded so our -l apidoc language is not recognized.

Swagger-codegen version

2.2.2-SNAPSHOT

Command line used for generation
java -classpath '/path/to/sas-apidoc-1.0.0.jar:/path/to.swagger-codegen-cli-2.2.2-SNAPSHOT.jar'  \
   io.swagger.codegen.SwaggerCodegen \
   generate -i swagger.yaml  -l apidoc -o /tmp/apidoc `

I would rather do:

java -jar '/path/to/sas-apidoc-1.0.0.jar generate -i swagger.yaml  -l apidoc -o /tmp/apidoc `
Suggest a Fix

One possible fix:

io.swagger.codegen.CodegenConfig only looks at the service file.
Provide a method extend the set of CodeGen classes with additional classes.

private static ArrayList<CodegenConfig> configs = new ArrayList<CodegenConfig>();
public static add(CodegenConfig config) { 
  configs.add(config);
}

and have CodegenConfig.forName(lang) scan that list first, then look in the service list. My Main class can then register my CodegenConfig class, then call the io.swagger.codegen.SwaggerCodegen main.

Other fixes could include a classpath scanner for CodegenConfig classes and automatically register them instead of manually maintaining a list in the service file.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with io.swagger.codegen.CodegenConfig and its META-INF/services/io.swagger.codegen.CodegenConfig discovery, then trace how io.swagger.codegen.SwaggerCodegen invokes CodegenConfig.forName(lang). Define how an external CodegenConfig can be registered without replacing the service resource, and verify that a separately packaged jar recognizes the apidoc language through the documented CLI flow.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.