-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TS#38029 Introduce AssemblyExtractor to fix EmbeddudUploadTarget Hand…
…ling
- Loading branch information
Showing
19 changed files
with
301 additions
and
245 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
using NLog; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Resources; | ||
using System.Text.RegularExpressions; | ||
using static UploadDaemon.SymbolAnalysis.RevisionFileUtils; | ||
|
||
namespace UploadDaemon.Scanning | ||
{ | ||
public class AssemblyExtractor | ||
{ | ||
Check warning on line 13 in UploadDaemon/Scanning/AssemblyExtractor.cs cqse.teamscale.io / teamscale-findingsUploadDaemon/Scanning/AssemblyExtractor.cs#L12-L13
|
||
private static readonly Logger logger = LogManager.GetCurrentClassLogger(); | ||
|
||
/// <summary> | ||
/// The name of the Resource .resx file that holed information about embedded upload targets. | ||
/// </summary> | ||
private const String TeamscaleResourceName = "Teamscale"; | ||
private static readonly Regex AssemblyLineRegex = new Regex(@"^Assembly=(?<name>[^:]+):(?<id>\d+).*?(?: Path:(?<path>.*))?$"); | ||
|
||
public readonly Dictionary<uint, (string name, string path)> Assemblies = new Dictionary<uint, (string name, string path)>(); | ||
Check warning on line 22 in UploadDaemon/Scanning/AssemblyExtractor.cs cqse.teamscale.io / teamscale-findingsUploadDaemon/Scanning/AssemblyExtractor.cs#L22
|
||
public readonly List<(string project, RevisionOrTimestamp revisionOrTimestamp)> EmbeddedUploadTargets = new List<(string project, RevisionOrTimestamp revisionOrTimestamp)>(); | ||
Check warning on line 23 in UploadDaemon/Scanning/AssemblyExtractor.cs cqse.teamscale.io / teamscale-findingsUploadDaemon/Scanning/AssemblyExtractor.cs#L23
|
||
|
||
public void ExtractAssemblies(string[] lines) | ||
{ | ||
Check warning on line 26 in UploadDaemon/Scanning/AssemblyExtractor.cs cqse.teamscale.io / teamscale-findingsUploadDaemon/Scanning/AssemblyExtractor.cs#L25-L26
|
||
foreach (string line in lines) | ||
{ | ||
string[] keyValuePair = line.Split(new[] { '=' }, 2); | ||
if (keyValuePair.Length < 2) | ||
{ | ||
continue; | ||
} | ||
|
||
if (keyValuePair[0] == "Assembly") | ||
{ | ||
Match assemblyMatch = AssemblyLineRegex.Match(line); | ||
Assemblies[Convert.ToUInt32(assemblyMatch.Groups["id"].Value)] = (assemblyMatch.Groups["name"].Value, assemblyMatch.Groups["path"].Value); | ||
} | ||
} | ||
|
||
SearchForEmbeddedUploadTargets(Assemblies, EmbeddedUploadTargets); | ||
} | ||
|
||
/// <summary> | ||
/// Checks the loaded assemblies for resources that contain information about target revision or teamscale projects. | ||
/// </summary> | ||
private void SearchForEmbeddedUploadTargets(Dictionary<uint, (string, string)> assemblyTokens, List<(string project, RevisionOrTimestamp revisionOrTimestamp)> uploadTargets) | ||
{ | ||
foreach (KeyValuePair<uint, (string, string)> entry in assemblyTokens) | ||
{ | ||
Assembly assembly = LoadAssemblyFromPath(entry.Value.Item2); | ||
if (assembly == null || assembly.DefinedTypes == null) | ||
{ | ||
continue; | ||
} | ||
TypeInfo teamscaleResourceType = assembly.DefinedTypes.FirstOrDefault(x => x.Name == TeamscaleResourceName) ?? null; | ||
if (teamscaleResourceType == null) | ||
{ | ||
continue; | ||
} | ||
logger.Info("Found embedded Teamscale resource in {assembly} that can be used to identify upload targets.", assembly); | ||
ResourceManager teamscaleResourceManager = new ResourceManager(teamscaleResourceType.FullName, assembly); | ||
string embeddedTeamscaleProject = teamscaleResourceManager.GetString("Project"); | ||
string embeddedRevision = teamscaleResourceManager.GetString("Revision"); | ||
string embeddedTimestamp = teamscaleResourceManager.GetString("Timestamp"); | ||
AddUploadTarget(embeddedRevision, embeddedTimestamp, embeddedTeamscaleProject, uploadTargets, assembly.FullName); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Adds a revision or timestamp and optionally a project to the list of upload targets. This method checks if both, revision and timestamp, are declared, or neither. | ||
/// </summary> | ||
/// <param name="revision"></param> | ||
/// <param name="timestamp"></param> | ||
/// <param name="project"></param> | ||
/// <param name="uploadTargets"></param> | ||
/// <param name="origin"></param> | ||
public static void AddUploadTarget(string revision, string timestamp, string project, List<(string project, RevisionOrTimestamp revisionOrTimestamp)> uploadTargets, string origin) | ||
{ | ||
Logger logger = LogManager.GetCurrentClassLogger(); | ||
|
||
if (revision == null && timestamp == null) | ||
{ | ||
logger.Error("Not all required fields in {origin}. Please specify either 'Revision' or 'Timestamp'", origin); | ||
return; | ||
} | ||
if (revision != null && timestamp != null) | ||
{ | ||
logger.Error("'Revision' and 'Timestamp' are both set in {origin}. Please set only one, not both.", origin); | ||
return; | ||
} | ||
if (revision != null) | ||
{ | ||
uploadTargets.Add((project, new RevisionOrTimestamp(revision, true))); | ||
} | ||
else | ||
{ | ||
uploadTargets.Add((project, new RevisionOrTimestamp(timestamp, false))); | ||
} | ||
} | ||
|
||
private Assembly LoadAssemblyFromPath(string path) | ||
{ | ||
if (String.IsNullOrEmpty(path)) | ||
{ | ||
return null; | ||
} | ||
Assembly assembly; | ||
try | ||
{ | ||
assembly = Assembly.LoadFrom(path); | ||
// Check that defined types can actually be loaded | ||
if (assembly == null) | ||
{ | ||
return null; | ||
} | ||
IEnumerable<TypeInfo> ignored = assembly.DefinedTypes; | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.Debug("Could not load {assembly}. Skipping upload resource discovery. {e}", path, e); | ||
return null; | ||
} | ||
return assembly; | ||
} | ||
|
||
|
||
} | ||
} |
Oops, something went wrong.