Skip to content

Commit

Permalink
refactor: use file scoped namespaces (#398)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieMagee authored Jan 5, 2023
1 parent fee6fb8 commit 0f3fa8a
Show file tree
Hide file tree
Showing 314 changed files with 20,790 additions and 21,106 deletions.
51 changes: 25 additions & 26 deletions src/Microsoft.ComponentDetection.Common/AsyncExecution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,40 @@
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.ComponentDetection.Common
namespace Microsoft.ComponentDetection.Common;

public static class AsyncExecution
{
public static class AsyncExecution
public static async Task<T> ExecuteWithTimeoutAsync<T>(Func<Task<T>> toExecute, TimeSpan timeout, CancellationToken cancellationToken)
{
public static async Task<T> ExecuteWithTimeoutAsync<T>(Func<Task<T>> toExecute, TimeSpan timeout, CancellationToken cancellationToken)
if (toExecute == null)
{
if (toExecute == null)
{
throw new ArgumentNullException(nameof(toExecute));
}

var work = Task.Run(toExecute);
throw new ArgumentNullException(nameof(toExecute));
}

var completedInTime = await Task.Run(() => work.Wait(timeout));
if (!completedInTime)
{
throw new TimeoutException($"The execution did not complete in the alotted time ({timeout.TotalSeconds} seconds) and has been terminated prior to completion");
}
var work = Task.Run(toExecute);

return await work;
var completedInTime = await Task.Run(() => work.Wait(timeout));
if (!completedInTime)
{
throw new TimeoutException($"The execution did not complete in the alotted time ({timeout.TotalSeconds} seconds) and has been terminated prior to completion");
}

public static async Task ExecuteVoidWithTimeoutAsync(Action toExecute, TimeSpan timeout, CancellationToken cancellationToken)
return await work;
}

public static async Task ExecuteVoidWithTimeoutAsync(Action toExecute, TimeSpan timeout, CancellationToken cancellationToken)
{
if (toExecute == null)
{
if (toExecute == null)
{
throw new ArgumentNullException(nameof(toExecute));
}
throw new ArgumentNullException(nameof(toExecute));
}

var work = Task.Run(toExecute);
var completedInTime = await Task.Run(() => work.Wait(timeout));
if (!completedInTime)
{
throw new TimeoutException($"The execution did not complete in the alotted time ({timeout.TotalSeconds} seconds) and has been terminated prior to completion");
}
var work = Task.Run(toExecute);
var completedInTime = await Task.Run(() => work.Wait(timeout));
if (!completedInTime)
{
throw new TimeoutException($"The execution did not complete in the alotted time ({timeout.TotalSeconds} seconds) and has been terminated prior to completion");
}
}
}
13 changes: 6 additions & 7 deletions src/Microsoft.ComponentDetection.Common/Column.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
namespace Microsoft.ComponentDetection.Common
namespace Microsoft.ComponentDetection.Common;

public class Column
{
public class Column
{
public int Width { get; set; }
public int Width { get; set; }

public string Header { get; set; }
public string Header { get; set; }

public string Format { get; set; }
}
public string Format { get; set; }
}
227 changes: 113 additions & 114 deletions src/Microsoft.ComponentDetection.Common/CommandLineInvocationService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
Expand All @@ -10,149 +10,148 @@
using Microsoft.ComponentDetection.Common.Telemetry.Records;
using Microsoft.ComponentDetection.Contracts;

namespace Microsoft.ComponentDetection.Common
namespace Microsoft.ComponentDetection.Common;

[Export(typeof(ICommandLineInvocationService))]
public class CommandLineInvocationService : ICommandLineInvocationService
{
[Export(typeof(ICommandLineInvocationService))]
public class CommandLineInvocationService : ICommandLineInvocationService
{
private readonly IDictionary<string, string> commandLocatableCache = new ConcurrentDictionary<string, string>();
private readonly IDictionary<string, string> commandLocatableCache = new ConcurrentDictionary<string, string>();

public async Task<bool> CanCommandBeLocated(string command, IEnumerable<string> additionalCandidateCommands = null, DirectoryInfo workingDirectory = null, params string[] parameters)
public async Task<bool> CanCommandBeLocated(string command, IEnumerable<string> additionalCandidateCommands = null, DirectoryInfo workingDirectory = null, params string[] parameters)
{
additionalCandidateCommands ??= Enumerable.Empty<string>();
parameters ??= new string[0];
var allCommands = new[] { command }.Concat(additionalCandidateCommands);
if (!this.commandLocatableCache.TryGetValue(command, out var validCommand))
{
additionalCandidateCommands ??= Enumerable.Empty<string>();
parameters ??= new string[0];
var allCommands = new[] { command }.Concat(additionalCandidateCommands);
if (!this.commandLocatableCache.TryGetValue(command, out var validCommand))
foreach (var commandToTry in allCommands)
{
foreach (var commandToTry in allCommands)
using var record = new CommandLineInvocationTelemetryRecord();

var joinedParameters = string.Join(" ", parameters);
try
{
using var record = new CommandLineInvocationTelemetryRecord();
var result = await RunProcessAsync(commandToTry, joinedParameters, workingDirectory);
record.Track(result, commandToTry, joinedParameters);

var joinedParameters = string.Join(" ", parameters);
try
if (result.ExitCode == 0)
{
var result = await RunProcessAsync(commandToTry, joinedParameters, workingDirectory);
record.Track(result, commandToTry, joinedParameters);

if (result.ExitCode == 0)
{
this.commandLocatableCache[command] = validCommand = commandToTry;
break;
}
}
catch (Exception ex) when (ex is Win32Exception || ex is FileNotFoundException || ex is PlatformNotSupportedException)
{
// When we get an exception indicating the command cannot be found.
record.Track(ex, commandToTry, joinedParameters);
this.commandLocatableCache[command] = validCommand = commandToTry;
break;
}
}
catch (Exception ex) when (ex is Win32Exception || ex is FileNotFoundException || ex is PlatformNotSupportedException)
{
// When we get an exception indicating the command cannot be found.
record.Track(ex, commandToTry, joinedParameters);
}
}

return !string.IsNullOrWhiteSpace(validCommand);
}

public async Task<CommandLineExecutionResult> ExecuteCommand(string command, IEnumerable<string> additionalCandidateCommands = null, DirectoryInfo workingDirectory = null, params string[] parameters)
{
var isCommandLocatable = await this.CanCommandBeLocated(command, additionalCandidateCommands);
if (!isCommandLocatable)
{
throw new InvalidOperationException(
$"{nameof(this.ExecuteCommand)} was called with a command that could not be located: `{command}`!");
}

if (workingDirectory != null && !Directory.Exists(workingDirectory.FullName))
{
throw new InvalidOperationException(
$"{nameof(this.ExecuteCommand)} was called with a working directory that could not be located: `{workingDirectory.FullName}`");
}

using var record = new CommandLineInvocationTelemetryRecord();
return !string.IsNullOrWhiteSpace(validCommand);
}

var pathToRun = this.commandLocatableCache[command];
var joinedParameters = string.Join(" ", parameters);
try
{
var result = await RunProcessAsync(pathToRun, joinedParameters, workingDirectory);
record.Track(result, pathToRun, joinedParameters);
return result;
}
catch (Exception ex)
{
record.Track(ex, pathToRun, joinedParameters);
throw;
}
public async Task<CommandLineExecutionResult> ExecuteCommand(string command, IEnumerable<string> additionalCandidateCommands = null, DirectoryInfo workingDirectory = null, params string[] parameters)
{
var isCommandLocatable = await this.CanCommandBeLocated(command, additionalCandidateCommands);
if (!isCommandLocatable)
{
throw new InvalidOperationException(
$"{nameof(this.ExecuteCommand)} was called with a command that could not be located: `{command}`!");
}

public bool IsCommandLineExecution()
if (workingDirectory != null && !Directory.Exists(workingDirectory.FullName))
{
return true;
throw new InvalidOperationException(
$"{nameof(this.ExecuteCommand)} was called with a working directory that could not be located: `{workingDirectory.FullName}`");
}

public async Task<bool> CanCommandBeLocated(string command, IEnumerable<string> additionalCandidateCommands = null, params string[] parameters)
using var record = new CommandLineInvocationTelemetryRecord();

var pathToRun = this.commandLocatableCache[command];
var joinedParameters = string.Join(" ", parameters);
try
{
return await this.CanCommandBeLocated(command, additionalCandidateCommands, workingDirectory: null, parameters);
var result = await RunProcessAsync(pathToRun, joinedParameters, workingDirectory);
record.Track(result, pathToRun, joinedParameters);
return result;
}

public async Task<CommandLineExecutionResult> ExecuteCommand(string command, IEnumerable<string> additionalCandidateCommands = null, params string[] parameters)
catch (Exception ex)
{
return await this.ExecuteCommand(command, additionalCandidateCommands, workingDirectory: null, parameters);
record.Track(ex, pathToRun, joinedParameters);
throw;
}
}

private static Task<CommandLineExecutionResult> RunProcessAsync(string fileName, string parameters, DirectoryInfo workingDirectory = null)
{
var tcs = new TaskCompletionSource<CommandLineExecutionResult>();
public bool IsCommandLineExecution()
{
return true;
}

if (fileName.EndsWith(".cmd") || fileName.EndsWith(".bat"))
{
// If a script attempts to find its location using "%dp0", that can return the wrong path (current
// working directory) unless the script is run via "cmd /C". An example is "ant.bat".
parameters = $"/C {fileName} {parameters}";
fileName = "cmd.exe";
}
public async Task<bool> CanCommandBeLocated(string command, IEnumerable<string> additionalCandidateCommands = null, params string[] parameters)
{
return await this.CanCommandBeLocated(command, additionalCandidateCommands, workingDirectory: null, parameters);
}

var process = new Process
{
StartInfo =
{
FileName = fileName,
Arguments = parameters,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
},
EnableRaisingEvents = true,
};

if (workingDirectory != null)
{
process.StartInfo.WorkingDirectory = workingDirectory.FullName;
}
public async Task<CommandLineExecutionResult> ExecuteCommand(string command, IEnumerable<string> additionalCandidateCommands = null, params string[] parameters)
{
return await this.ExecuteCommand(command, additionalCandidateCommands, workingDirectory: null, parameters);
}

var errorText = string.Empty;
var stdOutText = string.Empty;
private static Task<CommandLineExecutionResult> RunProcessAsync(string fileName, string parameters, DirectoryInfo workingDirectory = null)
{
var tcs = new TaskCompletionSource<CommandLineExecutionResult>();

var t1 = new Task(() =>
{
errorText = process.StandardError.ReadToEnd();
});
var t2 = new Task(() =>
{
stdOutText = process.StandardOutput.ReadToEnd();
});
if (fileName.EndsWith(".cmd") || fileName.EndsWith(".bat"))
{
// If a script attempts to find its location using "%dp0", that can return the wrong path (current
// working directory) unless the script is run via "cmd /C". An example is "ant.bat".
parameters = $"/C {fileName} {parameters}";
fileName = "cmd.exe";
}

process.Exited += (sender, args) =>
var process = new Process
{
StartInfo =
{
Task.WaitAll(t1, t2);
tcs.SetResult(new CommandLineExecutionResult { ExitCode = process.ExitCode, StdErr = errorText, StdOut = stdOutText });
process.Dispose();
};
FileName = fileName,
Arguments = parameters,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
},
EnableRaisingEvents = true,
};

if (workingDirectory != null)
{
process.StartInfo.WorkingDirectory = workingDirectory.FullName;
}

process.Start();
t1.Start();
t2.Start();
var errorText = string.Empty;
var stdOutText = string.Empty;

return tcs.Task;
}
var t1 = new Task(() =>
{
errorText = process.StandardError.ReadToEnd();
});
var t2 = new Task(() =>
{
stdOutText = process.StandardOutput.ReadToEnd();
});

process.Exited += (sender, args) =>
{
Task.WaitAll(t1, t2);
tcs.SetResult(new CommandLineExecutionResult { ExitCode = process.ExitCode, StdErr = errorText, StdOut = stdOutText });
process.Dispose();
};

process.Start();
t1.Start();
t2.Start();

return tcs.Task;
}
}
21 changes: 10 additions & 11 deletions src/Microsoft.ComponentDetection.Common/ComponentComparer.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Microsoft.ComponentDetection.Contracts.TypedComponent;

namespace Microsoft.ComponentDetection.Common
namespace Microsoft.ComponentDetection.Common;

public class ComponentComparer : EqualityComparer<TypedComponent>
{
public class ComponentComparer : EqualityComparer<TypedComponent>
public override bool Equals(TypedComponent t0, TypedComponent t1)
{
public override bool Equals(TypedComponent t0, TypedComponent t1)
{
return t0.Id.Equals(t1.Id);
}
return t0.Id.Equals(t1.Id);
}

public override int GetHashCode(TypedComponent typedComponent)
{
return typedComponent.Id.GetHashCode();
}
public override int GetHashCode(TypedComponent typedComponent)
{
return typedComponent.Id.GetHashCode();
}
}
Loading

0 comments on commit 0f3fa8a

Please sign in to comment.