Add sync algorithm for references.

This commit is contained in:
Gandifil 2023-12-20 19:51:03 +03:00
parent 6b4edb024a
commit a7d451600c

View file

@ -4,15 +4,16 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Build.Construction;
using Microsoft.Xna.Framework.Content.Pipeline; using Microsoft.Xna.Framework.Content.Pipeline;
using Newtonsoft.Json; using Newtonsoft.Json;
using NuGet.Configuration;
namespace Contentless; namespace Contentless;
public static class Program { public static class Program {
public static void Main(string[] args) { public static void Main(string[] args) {
if (args.Length != 1) { if (args.Length < 1) {
Console.WriteLine("Please specify the location of the content file you want to use"); Console.WriteLine("Please specify the location of the content file you want to use");
return; return;
} }
@ -43,11 +44,62 @@ public static class Program {
var excluded = config.ExcludedFiles.Select(Program.MakeFileRegex).ToArray(); var excluded = config.ExcludedFiles.Select(Program.MakeFileRegex).ToArray();
var overrides = Program.GetOverrides(config.Overrides).ToArray(); var overrides = Program.GetOverrides(config.Overrides).ToArray();
var referencesVersions = config.References.ToList().ToDictionary(x => x, x => (string)null, StringComparer.OrdinalIgnoreCase);
if (config.References.Any())
{
var csprojPath = args[1];
Console.WriteLine($"Using project file {csprojPath}");
var projectRootElement = ProjectRootElement.Open(csprojPath);
foreach (var property in projectRootElement.AllChildren.Where(x => x.ElementName == "PackageReference").Select(x => x as ProjectItemElement))
{
var libraryName = property.Include;
var version = (property.Children.First() as ProjectMetadataElement).Value;
if (config.References.Any(x => x.Equals(libraryName, StringComparison.InvariantCultureIgnoreCase)))
if (referencesVersions.Keys.Contains(libraryName))
{
referencesVersions[libraryName] = version;
//syncingReferences.Add(libraryName, version);
Console.WriteLine($"Found library version for sync: {libraryName}, {version}");
}
}
foreach (var library in referencesVersions)
if (library.Value is null)
{
Console.WriteLine($"Unable to find library {library.Key}");
return;
}
}
var changed = false;
var referencesSyncs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
// load any references to be able to include custom content types as well // load any references to be able to include custom content types as well
foreach (var line in content) { for (int i = 0; i < content.Count; i++)
if (!line.StartsWith("/reference:")) {
const string REFERENCE_HEADER = "/reference:";
var line = content[i];
if (!line.StartsWith(REFERENCE_HEADER))
continue; continue;
var reference = line.Substring(11); var reference = line.Substring(REFERENCE_HEADER.Length);
var libraryName = Path.GetFileName(reference)[..^4];
if (referencesVersions.Keys.Contains(libraryName))
{
var fullLibraryPath = CalculateFullPathToLibrary(libraryName, referencesVersions[libraryName]);
if (reference != fullLibraryPath)
{
Console.WriteLine($"Change library reference from {reference} to {fullLibraryPath}");
reference = fullLibraryPath;
content[i] = REFERENCE_HEADER + fullLibraryPath;
changed = true;
}
else
Console.WriteLine($"Skipping library reference {fullLibraryPath} (success sync)");
referencesSyncs.Add(libraryName);
}
var refPath = Path.GetFullPath(Path.Combine(contentFile.DirectoryName, reference)); var refPath = Path.GetFullPath(Path.Combine(contentFile.DirectoryName, reference));
try { try {
Assembly.LoadFrom(refPath); Assembly.LoadFrom(refPath);
@ -57,12 +109,20 @@ public static class Program {
} }
} }
// check references not in .mgcb now
foreach (var reference in referencesVersions)
if (!referencesSyncs.Contains(reference.Key))
{
Console.WriteLine($"Please, add reference for {reference.Key} in .mgcb file or remove it from Contentless! Reference was skipped!");
return;
}
// load content importers // load content importers
var (importers, processors) = Program.GetContentData(); var (importers, processors) = Program.GetContentData();
Console.WriteLine($"Found possible importer types {string.Join(", ", importers)}"); Console.WriteLine($"Found possible importer types {string.Join(", ", importers)}");
Console.WriteLine($"Found possible processor types {string.Join(", ", processors)}"); Console.WriteLine($"Found possible processor types {string.Join(", ", processors)}");
var changed = false;
foreach (var file in contentFile.Directory.EnumerateFiles("*", SearchOption.AllDirectories)) { foreach (var file in contentFile.Directory.EnumerateFiles("*", SearchOption.AllDirectories)) {
// is the file the content or config file? // is the file the content or config file?
if (file.Name == contentFile.Name || file.Name == configFile.Name) if (file.Name == contentFile.Name || file.Name == configFile.Name)
@ -142,6 +202,12 @@ public static class Program {
Console.Write("Done"); Console.Write("Done");
} }
private static string CalculateFullPathToLibrary(string libraryName, string referencesVersion)
{
var settings = Settings.LoadDefaultSettings(null);
return Path.Combine(SettingsUtility.GetGlobalPackagesFolder(settings), libraryName.ToLower(), referencesVersion, "tools", libraryName + ".dll");
}
private static (List<ImporterInfo>, List<string>) GetContentData() { private static (List<ImporterInfo>, List<string>) GetContentData() {
var importers = new List<ImporterInfo>(); var importers = new List<ImporterInfo>();
var processors = new List<string>(); var processors = new List<string>();