[aspnetcore] - make more configurable and generate abstract class library #2181 (#2282)

* Add ability control out put generation and support to generate a library

* Roll back pom version - it seems to break the CI/CD checks

* Roll back pom version - it seems to break the CI/CD checks

* Match with genrators - no changes from new code

* Fix inadvertent changes

* No idea why the names of params have changed pet to body for instance

* Match generated document

* Clarify logic as per PR review

* Remove the generatewwwroot option and use the buildtarget option

* Remove ar artifactVerson (not used), update docs and TODO notes

* Add ability control out put generation and support to generate a library

* Roll back pom version - it seems to break the CI/CD checks

* Roll back pom version - it seems to break the CI/CD checks

* Fix inadvertent changes

* Match generated document

* Add ability control out put generation and support to generate a library

* Roll back pom version - it seems to break the CI/CD checks

* Roll back pom version - it seems to break the CI/CD checks

* Fix inadvertent changes

* Match generated document

* Clarify logic as per PR review

* Remove the generatewwwroot option and use the buildtarget option

* Remove ar artifactVerson (not used), update docs and TODO notes
This commit is contained in:
William Cheng 2019-03-03 23:23:17 +08:00 committed by GitHub
parent 8c88f46fba
commit 8843df65a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 198 additions and 23 deletions

View File

@ -7,6 +7,11 @@ sidebar_label: aspnetcore
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|licenseUrl|The URL of the license| |http://localhost|
|licenseName|The name of the license| |NoLicense|
|packageCopyright|Specifies an AssemblyCopyright for the .NET Framework global assembly attributes stored in the AssemblyInfo file.| |No Copyright|
|packageAuthors|Specifies Authors property in the .NET Core project file.| |OpenAPI|
|packageTitle|Specifies an AssemblyTitle for the .NET Framework global assembly attributes stored in the AssemblyInfo file.| |OpenAPI Library|
|packageName|C# package name (convention: Title.Case).| |Org.OpenAPITools|
|packageVersion|C# package version.| |1.0.0|
|packageGuid|The GUID that will be associated with the C# project| |null|
@ -17,3 +22,7 @@ sidebar_label: aspnetcore
|useCollection|Deserialize array types to Collection<T> instead of List<T>.| |false|
|returnICollection|Return ICollection<T> instead of the concrete type.| |false|
|useSwashbuckle|Uses the Swashbuckle.AspNetCore NuGet package for documentation.| |true|
|classModifier|Class modifiers such as abstract or partial| ||
|operationModifier|Operation modifiers such as virtual or abstract.| |virtual|
|generateBody|Generates method body.| |true|
|buildTarget|Target the build for a program or library.| |program|

View File

@ -48,6 +48,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
protected String modelPropertyNaming = CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.PascalCase.name();
protected String licenseUrl = "http://localhost";
protected String licenseName = "NoLicense";
protected String packageVersion = "1.0.0";
protected String packageName = "Org.OpenAPITools";
protected String packageTitle = "OpenAPI Library";
@ -226,6 +229,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
}
@Override
public void processOpts() {
super.processOpts();
@ -235,6 +239,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
// License info
if (additionalProperties.containsKey(CodegenConstants.LICENSE_URL)) {
setLicenseUrl((String) additionalProperties.get(CodegenConstants.LICENSE_URL));
} else {
additionalProperties.put(CodegenConstants.LICENSE_URL, this.licenseUrl);
}
if (additionalProperties.containsKey(CodegenConstants.LICENSE_NAME)) {
setLicenseName((String) additionalProperties.get(CodegenConstants.LICENSE_NAME));
} else {
additionalProperties.put(CodegenConstants.LICENSE_NAME, this.licenseName);
}
// {{packageVersion}}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
@ -927,6 +944,10 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
return toModelName(name) + "Tests";
}
public void setLicenseUrl(String licenseUrl) {this.licenseUrl = licenseUrl;}
public void setLicenseName(String licenseName) {this.licenseName = licenseName;}
public void setPackageName(String packageName) {
this.packageName = packageName;
}

View File

@ -39,6 +39,14 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
public static final String USE_SWASHBUCKLE = "useSwashbuckle";
public static final String ASPNET_CORE_VERSION = "aspnetCoreVersion";
public static final String CLASS_MODIFIER = "classModifier";
public static final String OPERATION_MODIFIER = "operationModifier";
public static final String GENERATE_BODY = "generateBody";
public static final String BUILD_TARGET = "buildTarget";
public static final String PROJECT_SDK = "projectSdk";
public static final String SDK_WEB = "Microsoft.NET.Sdk.Web";
public static final String SDK_LIB = "Microsoft.NET.Sdk";
private String packageGuid = "{" + randomUUID().toString().toUpperCase(Locale.ROOT) + "}";
@ -49,6 +57,12 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
protected int serverPort = 8080;
protected String serverHost = "0.0.0.0";
protected String aspnetCoreVersion= "2.1"; // default to 2.1
// TODO Make next two enums toensure fixed list.
private String classModifier = "";
private String operationModifier = "virtual";
private boolean generateBody = true;
private String buildTarget = "program";
private String projectSdk = SDK_WEB;
public AspNetCoreServerCodegen() {
super();
@ -69,6 +83,26 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
cliOptions.clear();
// CLI options
addOption(CodegenConstants.LICENSE_URL,
CodegenConstants.LICENSE_URL_DESC,
licenseUrl);
addOption(CodegenConstants.LICENSE_NAME,
CodegenConstants.LICENSE_NAME_DESC,
licenseName);
addOption(CodegenConstants.PACKAGE_COPYRIGHT,
CodegenConstants.PACKAGE_COPYRIGHT_DESC,
packageCopyright);
addOption(CodegenConstants.PACKAGE_AUTHORS,
CodegenConstants.PACKAGE_AUTHORS_DESC,
packageAuthors);
addOption(CodegenConstants.PACKAGE_TITLE,
CodegenConstants.PACKAGE_TITLE_DESC,
packageTitle);
addOption(CodegenConstants.PACKAGE_NAME,
"C# package name (convention: Title.Case).",
packageName);
@ -110,6 +144,22 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
"Uses the Swashbuckle.AspNetCore NuGet package for documentation.",
useSwashbuckle);
addOption(CLASS_MODIFIER,
"Class modifiers such as abstract or partial",
classModifier);
addOption(OPERATION_MODIFIER,
"Operation modifiers such as virtual or abstract.",
operationModifier);
addSwitch(GENERATE_BODY,
"Generates method body.",
generateBody);
addOption(BUILD_TARGET,
"Target the build for a program or library.",
buildTarget);
}
@Override
@ -138,6 +188,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
@Override
public void processOpts() {
super.processOpts();
boolean isLibrary = false;
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_PROJECT_GUID)) {
setPackageGuid((String) additionalProperties.get(CodegenConstants.OPTIONAL_PROJECT_GUID));
@ -155,6 +206,50 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
setAspnetCoreVersion((String) additionalProperties.get(ASPNET_CORE_VERSION));
}
// CHeck for class modifier if not present set the default value.
if (additionalProperties.containsKey(CLASS_MODIFIER)) {
classModifier = additionalProperties.get(CLASS_MODIFIER).toString();
} else {
additionalProperties.put(CLASS_MODIFIER, classModifier);
}
// TODO Validate modifier values
// If class modifierier is abstract then the methods need to be abstrat too.
if ("abstract".equals(classModifier)) {
operationModifier = classModifier;
additionalProperties.put(OPERATION_MODIFIER, operationModifier);
}
if (additionalProperties.containsKey(OPERATION_MODIFIER)) {
operationModifier = additionalProperties.get(OPERATION_MODIFIER).toString();
} else {
additionalProperties.put(OPERATION_MODIFIER, operationModifier);
}
// TODO Validate modifier values
// If operation modifier is abstract then dont generate any body
if ("abstract".equals(operationModifier)) {
generateBody = false;
additionalProperties.put(GENERATE_BODY, generateBody);
}
if (additionalProperties.containsKey(GENERATE_BODY)) {
generateBody = convertPropertyToBooleanAndWriteBack(GENERATE_BODY);
} else {
additionalProperties.put(GENERATE_BODY, generateBody);
}
// CHeck for class modifier if not present set the default value.
if (additionalProperties.containsKey(BUILD_TARGET)) {
buildTarget = additionalProperties.get(BUILD_TARGET).toString();
} else {
additionalProperties.put(BUILD_TARGET, buildTarget);
}
if ("library".equals(buildTarget)) {
isLibrary = true;
projectSdk = SDK_LIB;
}
additionalProperties.put(PROJECT_SDK, projectSdk);
additionalProperties.put("dockerTag", packageName.toLowerCase(Locale.ROOT));
apiPackage = packageName + ".Controllers";
@ -173,21 +268,53 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
throw new IllegalArgumentException("aspnetCoreVersion must be '2.1', '2.0' but found " + aspnetCoreVersion);
}
supportingFiles.add(new SupportingFile("build.sh.mustache", "", "build.sh"));
supportingFiles.add(new SupportingFile("build.bat.mustache", "", "build.bat"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("gitignore", packageFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json"));
supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs"));
supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs"));
supportingFiles.add(new SupportingFile("validateModel.mustache", packageFolder + File.separator + "Attributes", "ValidateModelStateAttribute.cs"));
supportingFiles.add(new SupportingFile("Project.csproj.mustache", packageFolder, packageName + ".csproj"));
if (!isLibrary) {
supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json"));
supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs"));
supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs"));
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json",
packageFolder + File.separator + "Properties", "launchSettings.json"));
} else {
supportingFiles.add(new SupportingFile("Project.nuspec.mustache", packageFolder, packageName + ".nuspec"));
// wwwroot files.
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "openapi-original.mustache",
packageFolder + File.separator + "wwwroot", "openapi-original.json"));
}
supportingFiles.add(new SupportingFile("validateModel.mustache", packageFolder + File.separator + "Attributes", "ValidateModelStateAttribute.cs"));
supportingFiles.add(new SupportingFile("Project.csproj.mustache", packageFolder, packageName + ".csproj"));
if (!isLibrary) {
supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile"));
supportingFiles.add(new SupportingFile("appsettings.json", packageFolder, "appsettings.json"));
supportingFiles.add(new SupportingFile("Startup.mustache", packageFolder, "Startup.cs"));
supportingFiles.add(new SupportingFile("Program.mustache", packageFolder, "Program.cs"));
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json",
packageFolder + File.separator + "Properties", "launchSettings.json"));
} else {
supportingFiles.add(new SupportingFile("Project.nuspec.mustache", packageFolder, packageName + ".nuspec"));
// wwwroot files.
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "openapi-original.mustache",
packageFolder + File.separator + "wwwroot", "openapi-original.json"));
}
supportingFiles.add(new SupportingFile("Properties" + File.separator + "launchSettings.json",
packageFolder + File.separator + "Properties", "launchSettings.json"));
if (useSwashbuckle) {
supportingFiles.add(new SupportingFile("Filters" + File.separator + "BasePathFilter.mustache",
@ -195,13 +322,6 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
supportingFiles.add(new SupportingFile("Filters" + File.separator + "GeneratePathParamsValidationFilter.mustache",
packageFolder + File.separator + "Filters", "GeneratePathParamsValidationFilter.cs"));
}
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "README.md", packageFolder + File.separator + "wwwroot", "README.md"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "index.html", packageFolder + File.separator + "wwwroot", "index.html"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "web.config", packageFolder + File.separator + "wwwroot", "web.config"));
supportingFiles.add(new SupportingFile("wwwroot" + File.separator + "openapi-original.mustache",
packageFolder + File.separator + "wwwroot", "openapi-original.json"));
}
public void setPackageGuid(String packageGuid) {

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="{{projectSdk}}">
<PropertyGroup>
<Description>{{packageName}}</Description>
<Copyright>{{packageName}}</Copyright>

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>$id$</id>
<version>{{packageVersion}}</version>
<title>{{packageTitle}}</title>
<authors>{{packageAuthors}}</authors>
<owners>{{packageAuthors}}</owners>
<licenseUrl>{{licenseUrl}}</licenseUrl>
<!--
<projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
<iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
-->
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>{{packageName}}</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>{{packageCopyright}}</copyright>
<tags>{{packageName}}</tags>
</metadata>
</package>

View File

@ -15,7 +15,7 @@ namespace {{packageName}}.Controllers
/// {{description}}
/// </summary>{{#description}}
[Description("{{description}}")]{{/description}}
public class {{classname}}Controller : ControllerBase
public {{classModifier}} class {{classname}}Controller : ControllerBase
{ {{#operation}}
/// <summary>
/// {{#summary}}{{summary}}{{/summary}}
@ -28,7 +28,8 @@ namespace {{packageName}}.Controllers
[ValidateModelState]{{#useSwashbuckle}}
[SwaggerOperation("{{operationId}}")]{{#responses}}{{#dataType}}
[SwaggerResponse(statusCode: {{code}}, type: typeof({{&dataType}}), description: "{{message}}")]{{/dataType}}{{^dataType}}{{/dataType}}{{/responses}}{{/useSwashbuckle}}
public virtual IActionResult {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
public {{operationModifier}} IActionResult {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{{#generateBody}}
{ {{#responses}}
{{#dataType}}
//TODO: Uncomment the next line to return response {{code}} or use other options such as return this.NotFound(), return this.BadRequest(..), ...
@ -49,6 +50,10 @@ namespace {{packageName}}.Controllers
return new ObjectResult(example);{{/returnType}}{{^returnType}}
throw new NotImplementedException();{{/returnType}}
}
{{/generateBody}}
{{^generateBody}}
;
{{/generateBody}}
{{/operation}}
}
{{/operations}}

View File

@ -23,7 +23,7 @@ namespace Org.OpenAPITools.Controllers
/// <summary>
///
/// </summary>
public class PetApiController : ControllerBase
public class PetApiController : ControllerBase
{
/// <summary>
/// Add a new pet to the store

View File

@ -23,7 +23,7 @@ namespace Org.OpenAPITools.Controllers
/// <summary>
///
/// </summary>
public class StoreApiController : ControllerBase
public class StoreApiController : ControllerBase
{
/// <summary>
/// Delete purchase order by ID

View File

@ -23,7 +23,7 @@ namespace Org.OpenAPITools.Controllers
/// <summary>
///
/// </summary>
public class UserApiController : ControllerBase
public class UserApiController : ControllerBase
{
/// <summary>
/// Create user

View File

@ -112,8 +112,8 @@
"type" : "array",
"items" : {
"type" : "string",
"default" : "available",
"enum" : [ "available", "pending", "sold" ]
"enum" : [ "available", "pending", "sold" ],
"default" : "available"
}
}
} ],