Skip to content

Commit

Permalink
Reduce DotNet dependencies (#28)
Browse files Browse the repository at this point in the history
* Make it possible to run from a local swagger file

* Remove usage of Environment.MachineName and File.ReadAllBytes

* Correct version number when running from file on disk

* InternalRequest should be private

* Update version number

* Upgrade dependencies

* Fix status code for Java

* Fix capitalization issue in typescript

* Fix import for HttpStatusCode

* Fix one more reference
  • Loading branch information
tspence authored Sep 3, 2024
1 parent d07d411 commit 1522649
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 73 deletions.
2 changes: 1 addition & 1 deletion src/SdkGenerator/DownloadFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public static async Task<SwaggerDiff> GeneratePatchNotes(GeneratorContext contex
}

// Compare these two files
var oldContext = await GeneratorContext.FromSwaggerFileOnDisk(mostRecentFile, context.LogPath);
var oldContext = await GeneratorContext.FromSwaggerFileOnDisk(null, mostRecentFile, context.LogPath);
oldContext.OfficialVersion = mostRecentVersion.ToString();
oldContext.Project = context.Project;
return PatchNotesGenerator.Compare(oldContext, context);
Expand Down
33 changes: 27 additions & 6 deletions src/SdkGenerator/Languages/CSharpSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ private string FixupType(GeneratorContext context, string typeName, bool isArray
case "uri":
case "tel":
case "email":
case "HttpStatusCode":
case "File":
s = "string"; // We convert "file" to "filename" in processing
break;
Expand Down Expand Up @@ -349,6 +350,10 @@ private async Task ExportCategoryClient(GeneratorContext context, string cat, st
// Do we need to specify options?
var options = (from p in endpoint.Parameters where p.Location == "query" select p).ToList();
var isFileUpload = (from p in endpoint.Parameters where p.Location == "form" select p).Any();
if (isFileUpload)
{
paramList.Add("byte[] fileBytes");
}

// What is our return type? Note that we're assuming this can be non-nullable since the
// response class already handles the case where the value ends up being null.
Expand Down Expand Up @@ -383,13 +388,24 @@ private async Task ExportCategoryClient(GeneratorContext context, string cat, st
method = "new HttpMethod(\"PATCH\")";
}

// Send the request
var hasBody = (from p in endpoint.Parameters where p.Location == "body" select p).Any();
// There are three types of requests: basic, with body, and with multipart file upload
var optionsStr = options.Count > 0 ? ", options" : ", null";
var bodyStr = hasBody ? ", body" : ", null";
var fileStr = isFileUpload ? ", filename" : ", null";
sb.AppendLine(
$" return await _client.Request<{returnType}>({method}, url{optionsStr}{bodyStr}{fileStr});");
var hasBody = (from p in endpoint.Parameters where p.Location == "body" select p).Any();
if (hasBody)
{
sb.AppendLine(
$" return await _client.RequestWithBody<{returnType}>({method}, url{optionsStr}, body);");
}
else if (isFileUpload)
{
sb.AppendLine(
$" return await _client.RequestWithFile<{returnType}>({method}, url{optionsStr}, fileBytes, fileName);");
}
else
{
sb.AppendLine(
$" return await _client.Request<{returnType}>({method}, url{optionsStr});");
}
sb.AppendLine(" }");
}

Expand Down Expand Up @@ -431,13 +447,18 @@ private async Task ExportCategoryInterface(GeneratorContext context, string cat,

// Figure out the parameter list
var paramList = new List<string>();
var isFileUpload = (from p in endpoint.Parameters where p.Location == "form" select p).Any();
foreach (var p in from p in endpoint.Parameters orderby p.Required descending select p)
{
var isNullable = !p.Required || p.Nullable;
var typeName = FixupType(context, p.DataType, p.IsArray, isNullable);
var paramText = $"{typeName} {p.Name.ToVariableName()}{(isNullable ? " = null" : "")}";
paramList.Add(paramText);
}
if (isFileUpload)
{
paramList.Add("byte[] fileBytes");
}

// What is our return type? Note that we're assuming this can be non-nullable since the
// response class already handles the case where the value ends up being null.
Expand Down
1 change: 1 addition & 0 deletions src/SdkGenerator/Languages/JavaSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ private string JavaTypeName(GeneratorContext context, string typeName, bool isAr
case "Uri":
case "tel":
case "email":
case "HttpStatusCode":
s = "String";
break;
case "int32":
Expand Down
4 changes: 3 additions & 1 deletion src/SdkGenerator/Languages/TypescriptSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private string FixupType(GeneratorContext context, string typeName, bool isArray
{
case "tel":
case "Uri":
case "HttpStatusCode":
s = "string";
break;
case "TestTimeoutException":
Expand Down Expand Up @@ -236,7 +237,7 @@ orderby p.Required descending

var hasBody = (from p in endpoint.Parameters where p.Location == "body" select p).Any();
var optionsStr = options.Count > 0 ? ", options" : ", null";
var bodyStr = isFileUpload ? ", filename" : hasBody ? ", body" : ", null";
var bodyStr = isFileUpload ? ", fileName" : hasBody ? ", body" : ", null";
sb.AppendLine($" return this.client.{requestMethod}(\"{endpoint.Method}\", url{optionsStr}{bodyStr});");
sb.AppendLine(" }");
}
Expand Down Expand Up @@ -280,6 +281,7 @@ private void AddImport(GeneratorContext context, string name, List<string> list)
// Ignore base types
switch (name)
{
case "HttpStatusCode":
case "string":
case "uuid":
case "object":
Expand Down
37 changes: 24 additions & 13 deletions src/SdkGenerator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ private class BuildOptions : BaseOptions
{
[Option('t', "template", HelpText = "To build only one single template, specify this option")]
public string TemplateName { get; set; }

[Option('f', "file", HelpText = "Use a specific OpenAPI/Swagger file and do not attempt to download from source")]
public string SwaggerFile { get; set; }
}

[Verb("create", HelpText = "Create a new template file for a new SDK")]
Expand Down Expand Up @@ -128,8 +131,8 @@ private static async Task GetPatchNotesTask(GetPatchNotesOptions options)
var mostRecentFile = allSwaggerFiles[1];

// Load in the current and previous files
var prevContext = await GeneratorContext.FromSwaggerFileOnDisk(mostRecentFile, null);
var currentContext = await GeneratorContext.FromSwaggerFileOnDisk(currentFile, null);
var prevContext = await GeneratorContext.FromSwaggerFileOnDisk(null, mostRecentFile, null);
var currentContext = await GeneratorContext.FromSwaggerFileOnDisk(null, currentFile, null);
var patchNotes = PatchNotesGenerator.Compare(prevContext, currentContext);
Console.WriteLine(patchNotes.ToSummaryMarkdown());
}
Expand Down Expand Up @@ -164,7 +167,7 @@ private static async Task CompletePatchNotesTask(CompletePatchNotesOptions arg)
try
{
Console.WriteLine($"Processing {file}...");
var newContext = await GeneratorContext.FromSwaggerFileOnDisk(file, null);
var newContext = await GeneratorContext.FromSwaggerFileOnDisk(null, file, null);
versions.Add(newContext);
}
catch
Expand Down Expand Up @@ -198,7 +201,7 @@ private static async Task DiffTask(DiffOptions options)
Console.WriteLine($"Comparing {newContext.Project.SwaggerUrl} against old version {options.OldVersion}");

// Load the previous version of the swagger file from disk, and compare it
var oldContext = await GeneratorContext.FromSwaggerFileOnDisk(options.OldVersion, options.LogPath);
var oldContext = await GeneratorContext.FromSwaggerFileOnDisk(null, options.OldVersion, options.LogPath);
var diffs = PatchNotesGenerator.Compare(oldContext, newContext);

// Print out human readable description
Expand All @@ -208,8 +211,8 @@ private static async Task DiffTask(DiffOptions options)
private static async Task CompareTask(CompareOptions options)
{
// Load the current state of the project
var oldContext = await GeneratorContext.FromSwaggerFileOnDisk(options.OldFile, null);
var newContext = await GeneratorContext.FromSwaggerFileOnDisk(options.NewFile, null);
var oldContext = await GeneratorContext.FromSwaggerFileOnDisk(null, options.OldFile, null);
var newContext = await GeneratorContext.FromSwaggerFileOnDisk(null, options.NewFile, null);
Console.WriteLine($"Comparing {oldContext.Version4} against old version {newContext.Version4}");

// Load the previous version of the swagger file from disk, and compare it
Expand Down Expand Up @@ -238,15 +241,23 @@ private static async Task BuildTask(BuildOptions options)
var context = await GeneratorContext.FromFile(options.ProjectFile, options.LogPath);

// Fetch the environment and version number
Console.WriteLine($"Retrieving swagger file from {context.Project.SwaggerUrl}");
context.Api = await DownloadFile.GenerateApi(context);
if (context.Api == null)
if (options.SwaggerFile == null)
{
Console.WriteLine("Unable to retrieve API and version number successfully.");
return;
Console.WriteLine($"Retrieving swagger file from {context.Project.SwaggerUrl}");
context.Api = await DownloadFile.GenerateApi(context);
if (context.Api == null)
{
Console.WriteLine("Unable to retrieve API and version number successfully.");
return;
}

Console.WriteLine($"Retrieved swagger file. Version: {context.Version4}");
}
Console.WriteLine($"Retrieved swagger file. Version: {context.Version4}");

else
{
context = await GeneratorContext.FromSwaggerFileOnDisk(context, options.SwaggerFile, context.LogPath);
}

// Generate patch notes
context.PatchNotes = await DownloadFile.GeneratePatchNotes(context);

Expand Down
30 changes: 22 additions & 8 deletions src/SdkGenerator/Project/GeneratorContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public static async Task<GeneratorContext> FromFile(string filename, string logP
return context;
}

public static async Task<GeneratorContext> FromSwaggerFileOnDisk(string swaggerFilename, string logPath)
public static async Task<GeneratorContext> FromSwaggerFileOnDisk(GeneratorContext context, string swaggerFilename, string logPath)
{
// Retrieve project
if (!File.Exists(swaggerFilename))
Expand All @@ -99,14 +99,28 @@ public static async Task<GeneratorContext> FromSwaggerFileOnDisk(string swaggerF

// Ensure the folder for collecting swagger files exists
var swaggerJson = await File.ReadAllTextAsync(swaggerFilename);
var context = new GeneratorContext()
if (context == null)
{
Project = new ProjectSchema(),
Api = null,
LogPath = logPath,
SwaggerJson = swaggerJson,
OfficialVersion = DownloadFile.GetVersion(swaggerJson)
};
context = new GeneratorContext()
{
Project = new ProjectSchema(),
Api = null,
LogPath = logPath,
SwaggerJson = swaggerJson,
OfficialVersion = DownloadFile.GetVersion(swaggerJson)
};
}
else
{
context.LogPath = logPath ?? context.LogPath;
context.SwaggerJson = swaggerJson;
context.OfficialVersion = DownloadFile.GetVersion(swaggerJson);
context.Version4 = context.OfficialVersion;
var segments = context.Version4.Split(".");
context.Version2 = $"{segments[0]}.{segments[1]}";
context.Version3 = $"{segments[0]}.{segments[1]}.{segments[2]}";
Console.WriteLine($"Official version number is {context.OfficialVersion}");
}
context.Api = DownloadFile.GatherSchemas(context);
return context;
}
Expand Down
2 changes: 1 addition & 1 deletion src/SdkGenerator/Schema/SchemaFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ public static List<EndpointItem> MakeEndpoint(GeneratorContext context, JsonProp
{
item.Parameters.Add(new ParameterField
{
Name = "filename",
Name = "fileName",
Location = "form",
DescriptionMarkdown = "The full path of a file to upload to the API",
Required = true,
Expand Down
30 changes: 12 additions & 18 deletions src/SdkGenerator/SdkGenerator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
<PackageTags>SDK generator swagger openapi swashbuckle</PackageTags>
<Copyright>Copyright 2021 - 2024</Copyright>
<PackageReleaseNotes>
# 1.3.1
August 18, 2024
# 1.3.2
September 2, 2024

* Make automated publishing workflow scripts create-only so updates do not trigger GitHub security
* Reduced dependencies for C# / DotNet SDK
* Made Environment.MachineName optional
* Modified file upload APIs to take byte arrays rather than filenames
* New option -f for testing - ability to specify a Swagger/OpenAPI file on disk for builds
</PackageReleaseNotes>
<PackageIcon>docs/icons-puzzle.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>1.3.1</Version>
<Version>1.3.2</Version>
<Authors>Ted Spence</Authors>
<!-- Project Url is filled in by sourcelink in the .NET 8 SDK, but you can add it explicitly via
package -->
Expand All @@ -30,29 +33,20 @@
<PackageReference
Include="CommandLineParser"
Version="2.9.1" />
<PackageReference Include="CompareNETObjects" Version="4.82.0" />
<PackageReference
Include="HtmlAgilityPack"
Version="1.11.50" />
<PackageReference Include="CompareNETObjects" Version="4.83.0" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.65" />
<PackageReference
Include="JsonDiffPatch.Net"
Version="2.3.0" />
<PackageReference
Include="Newtonsoft.Json"
Version="13.0.3" />
<PackageReference
Include="RestSharp"
Version="110.2.0" />
<PackageReference
Include="Scriban"
Version="5.7.0" />
<PackageReference Include="RestSharp" Version="112.0.0" />
<PackageReference Include="Scriban" Version="5.10.0" />
<PackageReference
Include="Semver"
Version="2.3.0" />
<PackageReference
Include="Microsoft.SourceLink.GitHub"
Version="1.1.1"
PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 1522649

Please sign in to comment.