Skip to content

Commit 2662167

Browse files
author
Ole Lensmar
committed
Merge pull request #805 from hyeghiazaryan/develop_2.0
Support for file based config. Implementation for #616.
2 parents e983208 + d258a6c commit 2662167

File tree

12 files changed

+374
-27
lines changed

12 files changed

+374
-27
lines changed

README.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ NAME
6060
6161
SYNOPSIS
6262
swagger generate [(-a <authorization> | --auth <authorization>)]
63+
[(-c <configuration file> | --config <configuration file>)]
64+
[-D <system properties>]
6365
(-i <spec file> | --input-spec <spec file>)
6466
(-l <language> | --lang <language>)
6567
[(-o <output directory> | --output <output directory>)]
@@ -72,6 +74,16 @@ OPTIONS
7274
remotely. Pass in a URL-encoded string of name:header with a comma
7375
separating multiple values
7476
77+
-c <configuration file>, --config <configuration file>
78+
Path to json configuration file. File content should be in a json
79+
format {"optionKey":"optionValue", "optionKey1":"optionValue1"...}
80+
Supported options can be different for each language. Run
81+
config-help -l {lang} command for language specific config options.
82+
83+
-D <system properties>
84+
sets specified system properties in the format of
85+
name=value,name=value
86+
7587
-i <spec file>, --input-spec <spec file>
7688
location of the swagger spec, as URL or file (required)
7789
@@ -166,8 +178,60 @@ SwaggerYamlGenerator.java
166178
TizenClientCodegen.java
167179
```
168180

169-
Each of these files creates reasonable defaults so you can get running quickly. But if you want to configure package names, prefixes, model folders, etc., you may want to extend these.
181+
Each of these files creates reasonable defaults so you can get running quickly. But if you want to configure package names, prefixes, model folders, etc. you can use a json config file to pass the values.
182+
183+
```
184+
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
185+
-i http://petstore.swagger.io/v2/swagger.json \
186+
-l java \
187+
-o samples/client/petstore/java \
188+
-c path/to/config.json
189+
```
190+
Supported config options can be different per language. Running `config-help -l {lang}` will show available options.
191+
192+
```
193+
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jarr config-help -l java
194+
```
195+
196+
Output
197+
198+
```
199+
CONFIG OPTIONS
200+
modelPackage
201+
package for generated models
202+
203+
apiPackage
204+
package for generated api classes
205+
206+
invokerPackage
207+
root package for generated code
208+
209+
groupId
210+
groupId in generated pom.xml
211+
212+
artifactId
213+
artifactId in generated pom.xml
214+
215+
artifactVersion
216+
artifact version in generated pom.xml
217+
218+
sourceFolder
219+
source folder for generated code
220+
```
221+
222+
Your config file for java can look like
223+
224+
```
225+
{
226+
"groupId":"com.my.company",
227+
"artifactId":"MyClent",
228+
"artifactVersion":"1.2.0"
229+
}
230+
```
231+
232+
For all the unspecified options default values will be used.
170233

234+
Another way to override default options is to extend config class for specific language.
171235
To change, for example, the prefix for the Objective-C generated files, simply subclass the ObjcClientCodegen.java:
172236

173237
```

modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/SwaggerCodegen.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.wordnik.swagger.codegen;
22

3+
import com.wordnik.swagger.codegen.cmd.ConfigHelp;
34
import com.wordnik.swagger.codegen.cmd.Generate;
45
import com.wordnik.swagger.codegen.cmd.Langs;
56
import com.wordnik.swagger.codegen.cmd.Meta;
@@ -27,7 +28,8 @@ public static void main(String[] args) {
2728
Generate.class,
2829
Meta.class,
2930
Langs.class,
30-
Help.class
31+
Help.class,
32+
ConfigHelp.class
3133
);
3234

3335
builder.build().parse(args).run();
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.wordnik.swagger.codegen.cmd;
2+
3+
import com.wordnik.swagger.codegen.CliOption;
4+
import com.wordnik.swagger.codegen.CodegenConfig;
5+
import io.airlift.airline.Command;
6+
import io.airlift.airline.Option;
7+
import java.util.ServiceLoader;
8+
import static java.util.ServiceLoader.load;
9+
10+
@Command(name = "config-help", description = "Config help for chosen lang")
11+
public class ConfigHelp implements Runnable {
12+
13+
@Option(name = {"-l", "--lang"}, title = "language", required = true,
14+
description = "language to get config help for")
15+
private String lang;
16+
17+
@Override
18+
public void run() {
19+
System.out.println();
20+
CodegenConfig config = forName(lang);
21+
System.out.println("CONFIG OPTIONS");
22+
for (CliOption langCliOption : config.cliOptions()) {
23+
System.out.println("\t" + langCliOption.getOpt());
24+
System.out.println("\t " + langCliOption.getDescription());
25+
System.out.println();
26+
}
27+
}
28+
29+
/**
30+
* Tries to load config class with SPI first, then with class name directly from classpath
31+
* @param name name of config, or full qualified class name in classpath
32+
* @return config class
33+
*/
34+
private static CodegenConfig forName(String name) {
35+
ServiceLoader<CodegenConfig> loader = load(CodegenConfig.class);
36+
for (CodegenConfig config : loader) {
37+
if (config.getName().equals(name)) {
38+
return config;
39+
}
40+
}
41+
42+
// else try to load directly
43+
try {
44+
return (CodegenConfig) Class.forName(name).newInstance();
45+
} catch (Exception e) {
46+
throw new RuntimeException("Can't load config class with name ".concat(name), e);
47+
}
48+
}
49+
}

modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/Generate.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.wordnik.swagger.codegen.cmd;
22

3+
import com.wordnik.swagger.codegen.CliOption;
34
import com.wordnik.swagger.codegen.ClientOptInput;
45
import com.wordnik.swagger.codegen.ClientOpts;
56
import com.wordnik.swagger.codegen.CodegenConfig;
67
import com.wordnik.swagger.codegen.DefaultGenerator;
78
import com.wordnik.swagger.models.Swagger;
9+
import config.Config;
10+
import config.ConfigParser;
811
import io.airlift.airline.Command;
912
import io.airlift.airline.Option;
1013
import io.swagger.parser.SwaggerParser;
@@ -57,6 +60,11 @@ public class Generate implements Runnable {
5760
@Option( name= {"-D"}, title = "system properties", description = "sets specified system properties in " +
5861
"the format of name=value,name=value")
5962
private String systemProperties;
63+
64+
@Option( name= {"-c", "--config"}, title = "configuration file", description = "Path to json configuration file. " +
65+
"File content should be in a json format {\"optionKey\":\"optionValue\", \"optionKey1\":\"optionValue1\"...} " +
66+
"Supported options can be different for each language. Run config-help -l {lang} command for language specific config options.")
67+
private String configFile;
6068

6169
@Override
6270
public void run() {
@@ -76,6 +84,17 @@ public void run() {
7684
if (null != templateDir) {
7785
config.additionalProperties().put(TEMPLATE_DIR_PARAM, new File(templateDir).getAbsolutePath());
7886
}
87+
88+
if(null != configFile){
89+
Config genConfig = ConfigParser.read(configFile);
90+
if (null != genConfig) {
91+
for (CliOption langCliOption : config.cliOptions()) {
92+
if (genConfig.hasOption(langCliOption.getOpt())) {
93+
config.additionalProperties().put(langCliOption.getOpt(), genConfig.getOption(langCliOption.getOpt()));
94+
}
95+
}
96+
}
97+
}
7998

8099
input.setConfig(config);
81100

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.wordnik.swagger.codegen;
2+
3+
public class CliOption {
4+
private final String opt;
5+
private String description;
6+
7+
public CliOption(String opt, String description) {
8+
this.opt = opt;
9+
this.description = description;
10+
}
11+
12+
public String getOpt() {
13+
return opt;
14+
}
15+
16+
public String getDescription() {
17+
return description;
18+
}
19+
20+
public void setDescription(String description) {
21+
this.description = description;
22+
}
23+
}

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/Codegen.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,4 @@ public static CodegenConfig getConfig(String name) {
140140
}
141141
}
142142
}
143-
}
143+
}

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public interface CodegenConfig {
2727
String getTypeDeclaration(Property p);
2828
String getTypeDeclaration(String name);
2929
void processOpts();
30+
List<CliOption> cliOptions();
3031
String generateExamplePath(String path, Operation operation);
3132

3233
Set<String> reservedWords();

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,24 @@ public class DefaultCodegen {
7777
protected String templateDir;
7878
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
7979
protected List<SupportingFile> supportingFiles = new ArrayList<SupportingFile>();
80+
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
81+
82+
public List<CliOption> cliOptions() {
83+
return cliOptions;
84+
}
8085

8186
public void processOpts(){
8287
if(additionalProperties.containsKey("templateDir")) {
8388
this.setTemplateDir((String)additionalProperties.get("templateDir"));
8489
}
90+
91+
if(additionalProperties.containsKey("modelPackage")) {
92+
this.setModelPackage((String)additionalProperties.get("modelPackage"));
93+
}
94+
95+
if(additionalProperties.containsKey("apiPackage")) {
96+
this.setApiPackage((String)additionalProperties.get("apiPackage"));
97+
}
8598
}
8699

87100
// override with any special post-processing
@@ -178,6 +191,14 @@ public void setTemplateDir(String templateDir) {
178191
this.templateDir = templateDir;
179192
}
180193

194+
public void setModelPackage(String modelPackage) {
195+
this.modelPackage = modelPackage;
196+
}
197+
198+
public void setApiPackage(String apiPackage) {
199+
this.apiPackage = apiPackage;
200+
}
201+
181202
public String toApiFilename(String name) {
182203
return toApiName(name);
183204
}
@@ -281,6 +302,9 @@ public DefaultCodegen() {
281302
importMapping.put("LocalDateTime", "org.joda.time.*");
282303
importMapping.put("LocalDate", "org.joda.time.*");
283304
importMapping.put("LocalTime", "org.joda.time.*");
305+
306+
cliOptions.add(new CliOption("modelPackage", "package for generated models"));
307+
cliOptions.add(new CliOption("apiPackage", "package for generated api classes"));
284308
}
285309

286310

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,6 @@ public JavaClientCodegen() {
4545
"native", "super", "while")
4646
);
4747

48-
additionalProperties.put("invokerPackage", invokerPackage);
49-
additionalProperties.put("groupId", groupId);
50-
additionalProperties.put("artifactId", artifactId);
51-
additionalProperties.put("artifactVersion", artifactVersion);
52-
53-
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
54-
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
55-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
56-
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
57-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
58-
supportingFiles.add(new SupportingFile("apiException.mustache",
59-
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
60-
6148
languageSpecificPrimitives = new HashSet<String>(
6249
Arrays.asList(
6350
"String",
@@ -71,8 +58,65 @@ public JavaClientCodegen() {
7158
);
7259
instantiationTypes.put("array", "ArrayList");
7360
instantiationTypes.put("map", "HashMap");
61+
62+
cliOptions.add(new CliOption("invokerPackage", "root package for generated code"));
63+
cliOptions.add(new CliOption("groupId", "groupId in generated pom.xml"));
64+
cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml"));
65+
cliOptions.add(new CliOption("artifactVersion", "artifact version in generated pom.xml"));
66+
cliOptions.add(new CliOption("sourceFolder", "source folder for generated code"));
7467
}
7568

69+
@Override
70+
public void processOpts() {
71+
super.processOpts();
72+
73+
if(additionalProperties.containsKey("invokerPackage")) {
74+
this.setInvokerPackage((String)additionalProperties.get("invokerPackage"));
75+
}
76+
else{
77+
//not set, use default to be passed to template
78+
additionalProperties.put("invokerPackage", invokerPackage);
79+
}
80+
81+
if(additionalProperties.containsKey("groupId")) {
82+
this.setGroupId((String)additionalProperties.get("groupId"));
83+
}
84+
else{
85+
//not set, use to be passed to template
86+
additionalProperties.put("groupId", groupId);
87+
}
88+
89+
if(additionalProperties.containsKey("artifactId")) {
90+
this.setArtifactId((String)additionalProperties.get("artifactId"));
91+
}
92+
else{
93+
//not set, use to be passed to template
94+
additionalProperties.put("artifactId", artifactId);
95+
}
96+
97+
if(additionalProperties.containsKey("artifactVersion")) {
98+
this.setArtifactVersion((String)additionalProperties.get("artifactVersion"));
99+
}
100+
else{
101+
//not set, use to be passed to template
102+
additionalProperties.put("artifactVersion", artifactVersion);
103+
}
104+
105+
if(additionalProperties.containsKey("sourceFolder")) {
106+
this.setSourceFolder((String)additionalProperties.get("sourceFolder"));
107+
}
108+
109+
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
110+
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
111+
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java"));
112+
supportingFiles.add(new SupportingFile("JsonUtil.mustache",
113+
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java"));
114+
supportingFiles.add(new SupportingFile("apiException.mustache",
115+
(sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java"));
116+
}
117+
118+
119+
76120
@Override
77121
public String escapeReservedWord(String name) {
78122
return "_" + name;
@@ -169,5 +213,23 @@ public String toOperationId(String operationId) {
169213
return camelize(operationId, true);
170214
}
171215

216+
public void setInvokerPackage(String invokerPackage) {
217+
this.invokerPackage = invokerPackage;
218+
}
172219

220+
public void setGroupId(String groupId) {
221+
this.groupId = groupId;
222+
}
223+
224+
public void setArtifactId(String artifactId) {
225+
this.artifactId = artifactId;
226+
}
227+
228+
public void setArtifactVersion(String artifactVersion) {
229+
this.artifactVersion = artifactVersion;
230+
}
231+
232+
public void setSourceFolder(String sourceFolder) {
233+
this.sourceFolder = sourceFolder;
234+
}
173235
}

0 commit comments

Comments
 (0)