Read original app.config and add to it
This commit is contained in:
parent
1115fc22fa
commit
91acc03a13
2 changed files with 81 additions and 35 deletions
|
@ -34,43 +34,77 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
private readonly SHA1 _sha1 = SHA1.Create();
|
||||
|
||||
public XDocument Generate(IEnumerable<LibraryExport> dependencies)
|
||||
public XDocument Generate(IEnumerable<LibraryExport> dependencies, XDocument document)
|
||||
{
|
||||
var redirects = CollectRedirects(dependencies);
|
||||
|
||||
|
||||
if (!redirects.Any())
|
||||
{
|
||||
// No redirects required
|
||||
return null;
|
||||
return document;
|
||||
}
|
||||
document = document ?? new XDocument();
|
||||
|
||||
var configuration = GetOrAddElement(document, ConfigurationElementName);
|
||||
var runtime = GetOrAddElement(configuration, RuntimeElementName);
|
||||
var assemblyBindings = GetOrAddElement(runtime, AssemblyBindingElementName);
|
||||
|
||||
foreach (var redirect in redirects)
|
||||
{
|
||||
AddDependentAssembly(redirect, assemblyBindings);
|
||||
}
|
||||
|
||||
var document = new XDocument(
|
||||
new XElement(ConfigurationElementName,
|
||||
new XElement(RuntimeElementName,
|
||||
new XElement(AssemblyBindingElementName,
|
||||
redirects.Select(GetDependentAssembly)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
return document;
|
||||
}
|
||||
|
||||
private XElement GetDependentAssembly(AssemblyRedirect redirect)
|
||||
private void AddDependentAssembly(AssemblyRedirect redirect, XElement assemblyBindings)
|
||||
{
|
||||
var culture = string.IsNullOrEmpty(redirect.From.Culture) ? "neutral" : redirect.From.Culture;
|
||||
var dependencyElement = assemblyBindings.Elements(DependentAssemblyElementName)
|
||||
.FirstOrDefault(element => IsSameAssembly(redirect, element));
|
||||
|
||||
return new XElement(DependentAssemblyElementName,
|
||||
new XElement(AssemblyIdentityElementName,
|
||||
new XAttribute(NameAttributeName, redirect.From.Name),
|
||||
new XAttribute(PublicKeyTokenAttributeName, redirect.From.PublicKeyToken),
|
||||
new XAttribute(CultureAttributeName, culture)
|
||||
),
|
||||
new XElement(BindingRedirectElementName,
|
||||
if (dependencyElement == null)
|
||||
{
|
||||
dependencyElement = new XElement(DependentAssemblyElementName,
|
||||
new XElement(AssemblyIdentityElementName,
|
||||
new XAttribute(NameAttributeName, redirect.From.Name),
|
||||
new XAttribute(PublicKeyTokenAttributeName, redirect.From.PublicKeyToken),
|
||||
new XAttribute(CultureAttributeName, redirect.From.Culture)
|
||||
)
|
||||
);
|
||||
assemblyBindings.Add(dependencyElement);
|
||||
}
|
||||
|
||||
dependencyElement.Add(new XElement(BindingRedirectElementName,
|
||||
new XAttribute(OldVersionAttributeName, redirect.From.Version),
|
||||
new XAttribute(NewVersionAttributeName, redirect.To.Version)
|
||||
)
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
private bool IsSameAssembly(AssemblyRedirect redirect, XElement dependentAssemblyElement)
|
||||
{
|
||||
var identity = dependentAssemblyElement.Element(AssemblyIdentityElementName);
|
||||
if (identity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (string) identity.Attribute(NameAttributeName) == redirect.From.Name &&
|
||||
(string) identity.Attribute(PublicKeyTokenAttributeName) == redirect.From.PublicKeyToken &&
|
||||
(string) identity.Attribute(CultureAttributeName) == redirect.From.Culture;
|
||||
}
|
||||
|
||||
public static XElement GetOrAddElement(XContainer parent, XName elementName)
|
||||
{
|
||||
XElement element;
|
||||
if (parent.Element(elementName) != null)
|
||||
{
|
||||
element = parent.Element(elementName);
|
||||
}
|
||||
else
|
||||
{
|
||||
element = new XElement(elementName);
|
||||
parent.Add(element);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
private AssemblyRedirect[] CollectRedirects(IEnumerable<LibraryExport> dependencies)
|
||||
|
@ -109,15 +143,12 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
var metadataReader = peReader.GetMetadataReader();
|
||||
|
||||
var definition = metadataReader.GetAssemblyDefinition();
|
||||
|
||||
var publicKey = metadataReader.GetBlobBytes(definition.PublicKey);
|
||||
var publicKeyToken = GetPublicKeyToken(publicKey);
|
||||
|
||||
var identity = new AssemblyIdentity(
|
||||
metadataReader.GetString(definition.Name),
|
||||
definition.Version,
|
||||
metadataReader.GetString(definition.Culture),
|
||||
publicKeyToken
|
||||
GetPublicKeyToken(metadataReader.GetBlobBytes(definition.PublicKey))
|
||||
);
|
||||
|
||||
var references = new List<AssemblyIdentity>(metadataReader.AssemblyReferences.Count);
|
||||
|
@ -184,7 +215,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
{
|
||||
Name = name;
|
||||
Version = version;
|
||||
Culture = culture;
|
||||
Culture = string.IsNullOrEmpty(culture)? "neutral" : culture;
|
||||
PublicKeyToken = publicKeyToken;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||
|
@ -507,17 +507,32 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
private static void GenerateBindingRedirects(ProjectContext runtimeContext, string outputPath, LibraryExporter exporter)
|
||||
{
|
||||
var generator = new BindingRedirectGenerator();
|
||||
var config = generator.Generate(exporter.GetAllExports());
|
||||
var appConfigNames = new[] { "app.config", "App.config" };
|
||||
XDocument baseAppConfig = null;
|
||||
|
||||
if (config != null)
|
||||
foreach (var appConfigName in appConfigNames)
|
||||
{
|
||||
var baseAppConfigPath = Path.Combine(runtimeContext.ProjectDirectory, appConfigName);
|
||||
|
||||
if (File.Exists(baseAppConfigPath))
|
||||
{
|
||||
using (var fileStream = File.OpenRead(baseAppConfigPath))
|
||||
{
|
||||
baseAppConfig = XDocument.Load(fileStream);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var generator = new BindingRedirectGenerator();
|
||||
var appConfig = generator.Generate(exporter.GetAllExports(), baseAppConfig);
|
||||
|
||||
if (appConfig != null)
|
||||
{
|
||||
// TODO: Handle existing App.config file transformation
|
||||
// We have something to generate
|
||||
var path = Path.Combine(outputPath, runtimeContext.ProjectFile.Name + ".exe.config");
|
||||
using (var stream = File.Create(path))
|
||||
{
|
||||
config.Save(stream);
|
||||
appConfig.Save(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue