mirror of
https://github.com/Ellpeck/Contentless.git
synced 2024-11-22 07:23:30 +01:00
Add auto syncing references (#4)
* Add extraction of project file path.
* Add field for reference syncing in config file.
* Add new dependencies.
* Add sync algorithm for references.
* Update version
* Fix ups
* Rename ReferenceHeader
* Fix message
* Check arguments count.
* Fix
* Revert "Update version"
This reverts commit e24d75d18a
.
* Change error logic - no return
* Add adding new references.
* Add more true NuGet support.
* Fix braces.
* Fix First call.
---------
Co-authored-by: Ell <me@ellpeck.de>
This commit is contained in:
parent
d672f7e4b2
commit
a10689e3bb
7 changed files with 140 additions and 13 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ public class Config {
|
||||||
[JsonProperty("overrides")]
|
[JsonProperty("overrides")]
|
||||||
public Dictionary<string, Override> Overrides = new();
|
public Dictionary<string, Override> Overrides = new();
|
||||||
|
|
||||||
|
[JsonProperty("references")]
|
||||||
|
public string[] References = Array.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Override {
|
public class Override {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<RollForward>Major</RollForward>
|
<RollForward>Major</RollForward>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
@ -20,6 +21,12 @@
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1">
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1">
|
||||||
<PrivateAssets>All</PrivateAssets>
|
<PrivateAssets>All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Build" Version="17.3.2">
|
||||||
|
<PrivateAssets>All</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NuGet.Configuration" Version="6.8.0">
|
||||||
|
<PrivateAssets>All</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<Project>
|
<Project>
|
||||||
<Target Name="Contentless" BeforeTargets="BeforeBuild">
|
<Target Name="Contentless" BeforeTargets="BeforeBuild">
|
||||||
<Exec Command="dotnet $(MSBuildThisFileDirectory)/../tools/Contentless.dll @(MonoGameContentReference)" />
|
<Exec Command="dotnet $(MSBuildThisFileDirectory)/../tools/Contentless.dll @(MonoGameContentReference) $(MSBuildProjectFullPath)" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
15
Contentless/NuGetHelper.cs
Normal file
15
Contentless/NuGetHelper.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using NuGet.Configuration;
|
||||||
|
|
||||||
|
namespace Contentless;
|
||||||
|
|
||||||
|
public class NuGetHelper
|
||||||
|
{
|
||||||
|
private readonly ISettings _settings;
|
||||||
|
|
||||||
|
public NuGetHelper(string projectFolder)
|
||||||
|
{
|
||||||
|
_settings = Settings.LoadDefaultSettings(projectFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PackageFolder => SettingsUtility.GetGlobalPackagesFolder(_settings);
|
||||||
|
}
|
|
@ -4,15 +4,15 @@ 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;
|
||||||
|
|
||||||
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,26 +43,81 @@ 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.ToDictionary(x => x, x => (string)null, StringComparer.OrdinalIgnoreCase);
|
||||||
|
if (config.References.Length > 0) {
|
||||||
|
if (args.Length > 1) {
|
||||||
|
ExtractVersions(args[1], referencesVersions);
|
||||||
|
_nuGetHelper = new NuGetHelper(Path.GetDirectoryName(args[1]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Console.Error.WriteLine("You supplied references but there is no project file, this isn't compatible. Please specify the full path of project file, if you want to sync references");
|
||||||
|
}
|
||||||
|
|
||||||
|
const string ReferenceHeader = "/reference:";
|
||||||
|
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:"))
|
var line = content[i];
|
||||||
|
if (!line.StartsWith(ReferenceHeader))
|
||||||
continue;
|
continue;
|
||||||
var reference = line.Substring(11);
|
var reference = line.Substring(ReferenceHeader.Length);
|
||||||
|
var libraryName = Path.GetFileName(reference)[..^4];
|
||||||
|
|
||||||
|
if (referencesVersions.TryGetValue(libraryName, out var version) && version is not null) {
|
||||||
|
var fullLibraryPath = CalculateFullPathToLibrary(libraryName, version);
|
||||||
|
if (reference != fullLibraryPath) {
|
||||||
|
Console.WriteLine($"Changing library reference from {reference} to {fullLibraryPath}");
|
||||||
|
reference = fullLibraryPath;
|
||||||
|
content[i] = ReferenceHeader + 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));
|
||||||
|
SafeAssemblyLoad(refPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check references not in .mgcb now
|
||||||
|
var referencesLastIndex = 0;
|
||||||
|
// find place where I can add new reference
|
||||||
|
for (int i = 0; i < content.Count; i++)
|
||||||
|
{
|
||||||
|
var line = content[i];
|
||||||
|
if (line.StartsWith(ReferenceHeader))
|
||||||
|
referencesLastIndex = i + 1;
|
||||||
|
else if (line.StartsWith("/importer:") || line.StartsWith("/processor:") || line.StartsWith("/build:") ||
|
||||||
|
line.Contains("-- Content --")) {
|
||||||
|
if (referencesLastIndex == 0)
|
||||||
|
referencesLastIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var reference in referencesVersions)
|
||||||
|
if (!referencesSyncs.Contains(reference.Key) && reference.Value is not null) {
|
||||||
try {
|
try {
|
||||||
Assembly.LoadFrom(refPath);
|
var path = CalculateFullPathToLibrary(reference.Key, reference.Value);
|
||||||
Console.WriteLine($"Using reference {refPath}");
|
content.Insert(referencesLastIndex++, ReferenceHeader + path);
|
||||||
} catch (Exception e) {
|
changed = true;
|
||||||
Console.WriteLine($"Error loading reference {refPath}: {e}");
|
SafeAssemblyLoad(path);
|
||||||
|
Console.WriteLine($"Adding reference for {path} in .mgcb");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Error adding library {reference.Key} in .mgcb: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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 +197,45 @@ public static class Program {
|
||||||
Console.Write("Done");
|
Console.Write("Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void SafeAssemblyLoad(string refPath)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Assembly.LoadFrom(refPath);
|
||||||
|
Console.WriteLine($"Using reference {refPath}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine($"Error loading reference {refPath}: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ExtractVersions(string csprojPath, Dictionary<string, string> referencesVersions)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
if (property.Children.FirstOrDefault(x => x.ElementName == "Version") is not ProjectMetadataElement versionElement)
|
||||||
|
continue;
|
||||||
|
var version = versionElement.Value;
|
||||||
|
if (referencesVersions.Keys.Contains(libraryName))
|
||||||
|
{
|
||||||
|
referencesVersions[libraryName] = version;
|
||||||
|
Console.WriteLine($"Found library version for sync: {libraryName}, {version}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var library in referencesVersions)
|
||||||
|
if (library.Value is null)
|
||||||
|
Console.Error.WriteLine($"Unable to find library {library.Key} in .csproj");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NuGetHelper _nuGetHelper;
|
||||||
|
|
||||||
|
private static string CalculateFullPathToLibrary(string libraryName, string referencesVersion)
|
||||||
|
{
|
||||||
|
return Path.Combine(_nuGetHelper.PackageFolder, 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>();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"Ex*.png"
|
"Ex*.png"
|
||||||
],
|
],
|
||||||
"logSkipped": true,
|
"logSkipped": true,
|
||||||
|
"references": ["monogame.extended.content.pipeline"],
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"Copy.*": {
|
"Copy.*": {
|
||||||
"copy": true
|
"copy": true
|
||||||
|
|
7
Test/NuGet.Config
Normal file
7
Test/NuGet.Config
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="lithiumtoast" value="https://www.myget.org/F/lithiumtoast/api/v3/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
Loading…
Reference in a new issue