Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/CLI/ApiClientCodeGen.CLI/Commands/JMeterCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ public override int Execute(CommandContext context, Settings settings, Cancellat
var outputPath = settings.OutputPath;
if (!Directory.Exists(outputPath))
{
outputPath = Path.Combine(Path.GetDirectoryName(settings.SwaggerFile)!, settings.OutputPath);
var swaggerDirectory = Path.GetDirectoryName(settings.SwaggerFile) ?? Directory.GetCurrentDirectory();
outputPath = Path.Combine(swaggerDirectory, settings.OutputPath);
}

var directoryInfo = new DirectoryInfo(outputPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public OpenApiGeneratorCommand(
this.console = console ?? throw new ArgumentNullException(nameof(console));
this.progressReporter = progressReporter ?? throw new ArgumentNullException(nameof(progressReporter));
this.options = options ?? throw new ArgumentNullException(nameof(options));
this.factory = factory;
this.factory = factory ?? throw new ArgumentNullException(nameof(factory));
this.processLauncher = processLauncher ?? throw new ArgumentNullException(nameof(processLauncher));
this.dependencyInstaller =
dependencyInstaller ?? throw new ArgumentNullException(nameof(dependencyInstaller));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ public static string GetDescription<T>(this T e) where T : Enum, IConvertible
{
if (val == e.ToInt32(CultureInfo.InvariantCulture))
{
var memInfo = type.GetMember(type.GetEnumName(val));
var enumName = type.GetEnumName(val);
if (enumName == null)
continue;

var memInfo = type.GetMember(enumName);
if (memInfo.Length == 0)
continue;

var descriptionAttribute = memInfo[0]
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.FirstOrDefault() as DescriptionAttribute;
Expand Down
19 changes: 13 additions & 6 deletions src/Core/ApiClientCodeGen.Core/External/PathProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,22 @@ public static string GetNpmPath(
if (Environment.OSVersion.Platform is PlatformID.MacOSX or PlatformID.Unix || withoutPath)
return "npm";

if (string.IsNullOrWhiteSpace(programFiles))
programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
var programFilesPath = programFiles;
if (string.IsNullOrWhiteSpace(programFilesPath))
programFilesPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);

if (string.IsNullOrWhiteSpace(programFiles64))
programFiles64 = programFiles!.Replace(" (x86)", string.Empty);
// If still null/empty after getting from environment, return npm command without path
if (string.IsNullOrWhiteSpace(programFilesPath))
return "npm";

// At this point programFilesPath is guaranteed to be non-null/non-empty
var effectiveProgramFiles64 = !string.IsNullOrWhiteSpace(programFiles64)
? programFiles64
: programFilesPath!.Replace(" (x86)", string.Empty);

var npmCommand = Path.Combine(programFiles, "nodejs\\npm.cmd");
var npmCommand = Path.Combine(programFilesPath!, "nodejs\\npm.cmd");
if (!File.Exists(npmCommand))
npmCommand = Path.Combine(programFiles64, "nodejs\\npm.cmd");
npmCommand = Path.Combine(effectiveProgramFiles64, "nodejs\\npm.cmd");

return File.Exists(npmCommand) ? npmCommand : string.Empty;
}
Expand Down
18 changes: 12 additions & 6 deletions src/Core/ApiClientCodeGen.Core/Generators/CSharpFileMerger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ public static string MergeFilesAndDeleteSource(string output)
finally
{
ActionExtensions.SafeInvoke(
() => Directory.Delete(
Directory.GetParent(output)!.FullName,
true));
() =>
{
var parent = Directory.GetParent(output);
if (parent != null)
Directory.Delete(parent.FullName, true);
});
}
}

Expand All @@ -51,9 +54,12 @@ public static void CopyFilesAndDeleteSource(string input, string output)
finally
{
ActionExtensions.SafeInvoke(
() => Directory.Delete(
Directory.GetParent(input)!.FullName,
true));
() =>
{
var parent = Directory.GetParent(input);
if (parent != null)
Directory.Delete(parent.FullName, true);
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ public string GenerateCode(IProgressReporter? pGenerateProgress)
}

pGenerateProgress?.Progress(30);
var swaggerDirectory = Path.GetDirectoryName(swaggerFile) ?? Directory.GetCurrentDirectory();
string outputFolder = options.GenerateMultipleFiles
? Path.GetDirectoryName(swaggerFile)
? swaggerDirectory
: Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

if (!Directory.Exists(outputFolder))
Expand All @@ -46,15 +47,15 @@ public string GenerateCode(IProgressReporter? pGenerateProgress)
RunKiotaGenerate(outputFolder);

if (!options.GenerateMultipleFiles &&
File.Exists(Path.Combine(Path.GetDirectoryName(swaggerFile)!, KiotaLockFile)))
File.Exists(Path.Combine(swaggerDirectory, KiotaLockFile)))
{
File.Copy(
swaggerFile,
Path.Combine(outputFolder, swaggerFilename),
true);

File.Copy(
Path.Combine(Path.GetDirectoryName(swaggerFile)!, KiotaLockFile),
Path.Combine(swaggerDirectory, KiotaLockFile),
Path.Combine(outputFolder, KiotaLockFile),
true);

Expand All @@ -78,7 +79,7 @@ public string GenerateCode(IProgressReporter? pGenerateProgress)
{
File.Copy(
kiotaConfigFile,
Path.Combine(Path.GetDirectoryName(swaggerFile)!, KiotaLockFile),
Path.Combine(swaggerDirectory, KiotaLockFile),
true);
}
}
Expand Down Expand Up @@ -109,7 +110,8 @@ private void RunKiotaGenerate(string outputFolder)

private void RunKiotaUpdate()
{
var arguments = $" update -o \"{Path.GetDirectoryName(swaggerFile)!}\"";
var outputDirectory = Path.GetDirectoryName(swaggerFile) ?? Directory.GetCurrentDirectory();
var arguments = $" update -o \"{outputDirectory}\"";
using var context = new DependencyContext("Kiota", $"{Command} {arguments}");
processLauncher.Start(Command, arguments);
context.Succeeded();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ public string GenerateCode(IProgressReporter? pGenerateProgress)
pGenerateProgress?.Progress(50);

var arguments = $"run \"{nswagStudioFile}\"";
var workingDirectory = Path.GetDirectoryName(nswagStudioFile) ?? Directory.GetCurrentDirectory();

using var context = new DependencyContext("NSwag Studio", $"{command} {arguments}");
processLauncher.Start(command, arguments, Path.GetDirectoryName(nswagStudioFile)!);
processLauncher.Start(command, arguments, workingDirectory);
context.Succeeded();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public OpenApiCSharpCodeGenerator(

public string GenerateCode(IProgressReporter? pGenerateProgress)
{
string arguments = null!;
string arguments = "";
try
{
pGenerateProgress?.Progress(10);
Expand Down Expand Up @@ -118,20 +118,22 @@ public string GenerateCode(IProgressReporter? pGenerateProgress)
arguments += openApiGeneratorOptions.CustomAdditionalProperties;
}

var swaggerDirectory = Path.GetDirectoryName(swaggerFile) ?? Directory.GetCurrentDirectory();

if (!string.IsNullOrWhiteSpace(openApiGeneratorOptions.TemplatesPath))
{
var templatesPath = openApiGeneratorOptions.TemplatesPath;
if (!Directory.Exists(templatesPath))
{
templatesPath = Path.Combine(Path.GetDirectoryName(swaggerFile)!, templatesPath);
templatesPath = Path.Combine(swaggerDirectory, templatesPath);
}

arguments += $"-t \"{templatesPath}\" ";
}

var java = javaPathProvider.GetJavaExePath();
using var context = new DependencyContext("OpenAPI Generator", $"{java} {arguments}");
processLauncher.Start(java, arguments, Path.GetDirectoryName(swaggerFile));
processLauncher.Start(java, arguments, swaggerDirectory);
context.Succeeded();

pGenerateProgress?.Progress(80);
Expand All @@ -158,7 +160,7 @@ public string GenerateCode(IProgressReporter? pGenerateProgress)
{
CSharpFileMerger.CopyFilesAndDeleteSource(
Path.Combine(output, "src", defaultNamespace),
Path.GetDirectoryName(swaggerFile)!);
swaggerDirectory);
}

return string.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,10 @@ private string BuildRefitterArguments(string inputFile, string outputPath)

private static string GetOutputFilePath(RefitterSettings? settings, string? workingDirectory)
{
if (settings == null || workingDirectory == null)
return Path.Combine(workingDirectory ?? "", "Output.cs");
var effectiveWorkingDirectory = workingDirectory ?? Directory.GetCurrentDirectory();

if (settings == null)
return Path.Combine(effectiveWorkingDirectory, "Output.cs");

var outputFolder = settings.OutputFolder ?? "";
var outputFilename = settings.OutputFilename ?? "Output.cs";
Expand All @@ -188,7 +190,7 @@ private static string GetOutputFilePath(RefitterSettings? settings, string? work
return Path.Combine(outputFolder, outputFilename);
}

return Path.Combine(workingDirectory, outputFolder, outputFilename);
return Path.Combine(effectiveWorkingDirectory, outputFolder, outputFilename);
}

// Minimal representation of Refitter settings for JSON deserialization
Expand Down
35 changes: 29 additions & 6 deletions src/Core/ApiClientCodeGen.Core/Installer/DependencyInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,43 @@ public void InstallKiota()
});
if (!kiotaVersion.StartsWith("1.30.0"))
{
//older or newer? i guess this should be handled.
// Version mismatch detected, try to update to required version
try
{
UpdateKiotaTool();
}
catch (ProcessLaunchException ex) when (ex.ErrorData?.Contains("is already installed") == true)
{
// Tool is already installed at correct version, ignore
Logger.Instance.WriteLine("Kiota is already installed at the required version.");
}
}
}
catch (Win32Exception)
{
// if command doesn't exist Win32Exception is thrown.
command = PathProvider.GetDotNetPath();
arguments = "tool install --global Microsoft.OpenApi.Kiota --version 1.30.0";
using var context = new DependencyContext(command, $"{command} {arguments}");
processLauncher.Start(command, arguments);
context.Succeeded();
InstallKiotaTool();
}
}

private void InstallKiotaTool()
{
var command = PathProvider.GetDotNetPath();
var arguments = "tool install --global Microsoft.OpenApi.Kiota --version 1.30.0";
using var context = new DependencyContext(command, $"{command} {arguments}");
processLauncher.Start(command, arguments);
context.Succeeded();
}

private void UpdateKiotaTool()
{
var command = PathProvider.GetDotNetPath();
var arguments = "tool update --global Microsoft.OpenApi.Kiota --version 1.30.0";
using var context = new DependencyContext(command, $"{command} {arguments}");
processLauncher.Start(command, arguments);
context.Succeeded();
}

public void InstallRefitter()
{
var command = PathProvider.GetDotNetPath();
Expand Down
16 changes: 13 additions & 3 deletions src/Core/ApiClientCodeGen.Core/Installer/FileDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,34 @@ public string DownloadFile(

Logger.Instance.WriteLine($"{outputFilename} downloaded successfully");

MoveFile(filePath, tempFile);
if (!MoveFile(filePath, tempFile))
{
// If move failed but temp file exists, use it directly as fallback
if (File.Exists(tempFile))
return tempFile;

// If temp file also doesn't exist, the download likely failed
// Log warning but return expected path for backward compatibility
Logger.Instance.WriteLine($"Warning: Downloaded file may not exist at expected location: {filePath}");
}

return filePath;
}

[ExcludeFromCodeCoverage]
private static void MoveFile(string filePath, string tempFile)
private static bool MoveFile(string filePath, string tempFile)
{
try
{
if (File.Exists(filePath))
File.Delete(filePath);
File.Move(tempFile, filePath);
return true;
}
catch (Exception e)
{
Logger.Instance.TrackError(e);

return false;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Core/ApiClientCodeGen.Core/NpmHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static string GetPrefixPath()
try
{
var npm = GetNpmPath();
string prefix = null!;
string prefix = "";

using var context = new DependencyContext("npm config get prefix");
(processLauncher ?? new ProcessLauncher()).Start(
Expand All @@ -33,7 +33,7 @@ public static string GetPrefixPath()
o => prefix += o,
e => Logger.Instance.WriteLine(e));
context.Succeeded();
return prefix;
return string.IsNullOrWhiteSpace(prefix) ? null : prefix;
}
catch (Exception e)
{
Expand Down
10 changes: 8 additions & 2 deletions src/VSCode/src/utils/version-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@ export function getExtensionVersion(context: vscode.ExtensionContext): string |
* @returns 1 if version1 > version2, -1 if version1 < version2, 0 if equal
*/
export function compareVersions(version1: string, version2: string): number {
const parts1 = version1.split('.').map(Number);
const parts2 = version2.split('.').map(Number);
const parts1 = version1.split('.').map(s => {
const num = parseInt(s, 10);
return isNaN(num) ? 0 : num;
});
const parts2 = version2.split('.').map(s => {
const num = parseInt(s, 10);
return isNaN(num) ? 0 : num;
});

for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
const p1 = i < parts1.length ? parts1[i] : 0;
Expand Down