-
Notifications
You must be signed in to change notification settings - Fork 82
Add a task to generate a manifest with the file system structure of the original files #308
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
|
||
namespace Microsoft.Extensions.FileProviders.Embedded.Manifest.Task | ||
{ | ||
public class EmbeddedItem : IEquatable<EmbeddedItem> | ||
{ | ||
public string ManifestFilePath { get; set; } | ||
|
||
public string AssemblyResourceName { get; set; } | ||
|
||
public bool Equals(EmbeddedItem other) => | ||
string.Equals(ManifestFilePath, other?.ManifestFilePath, StringComparison.Ordinal) && | ||
string.Equals(AssemblyResourceName, other?.AssemblyResourceName, StringComparison.Ordinal); | ||
|
||
public override bool Equals(object obj) => Equals(obj as EmbeddedItem); | ||
public override int GetHashCode() => ManifestFilePath.GetHashCode() ^ AssemblyResourceName.GetHashCode(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
|
||
namespace Microsoft.Extensions.FileProviders.Embedded.Manifest.Task.Internal | ||
{ | ||
/// <summary> | ||
/// This type is for internal uses only and is not meant to be consumed by any other library. | ||
/// </summary> | ||
[DebuggerDisplay("{Name,nq}")] | ||
public class Entry : IEquatable<Entry> | ||
{ | ||
public bool IsFile { get; private set; } | ||
|
||
public string Name { get; private set; } | ||
|
||
public string AssemblyResourceName { get; private set; } | ||
|
||
public ISet<Entry> Children { get; } = new SortedSet<Entry>(NameComparer.Instance); | ||
|
||
public static Entry Directory(string name) => | ||
new Entry { Name = name }; | ||
|
||
public static Entry File(string name, string assemblyResourceName) => | ||
new Entry { Name = name, AssemblyResourceName = assemblyResourceName, IsFile = true }; | ||
|
||
internal void AddChild(Entry child) | ||
{ | ||
if (IsFile) | ||
{ | ||
throw new InvalidOperationException("Tried to add children to a file."); | ||
} | ||
|
||
if (Children.Contains(child)) | ||
{ | ||
throw new InvalidOperationException($"An item with the name '{child.Name}' already exists."); | ||
} | ||
|
||
Children.Add(child); | ||
} | ||
|
||
internal Entry GetDirectory(string currentSegment) | ||
{ | ||
if (IsFile) | ||
{ | ||
throw new InvalidOperationException("Tried to get a directory from a file."); | ||
} | ||
|
||
foreach (var child in Children) | ||
{ | ||
if (child.HasName(currentSegment)) | ||
{ | ||
if (child.IsFile) | ||
{ | ||
throw new InvalidOperationException("Tried to find a directory but found a file instead"); | ||
} | ||
else | ||
{ | ||
return child; | ||
} | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public bool Equals(Entry other) | ||
{ | ||
if (other == null || !other.HasName(Name) || other.IsFile != IsFile) | ||
{ | ||
return false; | ||
} | ||
|
||
if (IsFile) | ||
{ | ||
return string.Equals(other.AssemblyResourceName, AssemblyResourceName, StringComparison.Ordinal); | ||
} | ||
else | ||
{ | ||
return SameChildren(Children, other.Children); | ||
} | ||
} | ||
|
||
private bool HasName(string currentSegment) | ||
{ | ||
return string.Equals(Name, currentSegment, StringComparison.Ordinal); | ||
} | ||
|
||
private bool SameChildren(ISet<Entry> left, ISet<Entry> right) | ||
{ | ||
if (left.Count != right.Count) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't there a SetEquals on set? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Equality for these sets is not based solely on the name. We check that we aren't adding two files with the same name but different metadata There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup. But you should be able to use ``SortedSet.CreateSetComparer(EqualityComparer.Default).Equals(left, right);` |
||
{ | ||
return false; | ||
} | ||
|
||
var le = left.GetEnumerator(); | ||
var re = right.GetEnumerator(); | ||
while (le.MoveNext() && re.MoveNext()) | ||
{ | ||
if (!le.Current.Equals(re.Current)) | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
private class NameComparer : IComparer<Entry> | ||
{ | ||
public static NameComparer Instance { get; } = new NameComparer(); | ||
|
||
public int Compare(Entry x, Entry y) => | ||
string.Compare(x?.Name, y?.Name, StringComparison.Ordinal); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<RootNamespace>Microsoft.Extensions.FileProviders.Embedded.Manifest.Task</RootNamespace> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you considered putting this inside the Microsoft.Extensions.FileProviders.Embedded nuget package, instead of making a new package? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean the MSBuild part of it? (The targets file). I would definitely keep the assembly separate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The assembly definitely needs to be separate. One way to layout this package is like this:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
<AssemblyName>Microsoft.Extensions.FileProviders.Embedded.Manifest.Task</AssemblyName> | ||
<Description>MSBuild task to generate a manifest that can be used by Microsoft.Extensions.FileProviders.Embedded to preserve | ||
metadata of the files embedded in the assembly at compilation time.</Description> | ||
<TargetFrameworks>netstandard1.5;net461</TargetFrameworks> | ||
<GenerateDocumentationFile>false</GenerateDocumentationFile> | ||
<EnableApiCheck>false</EnableApiCheck> | ||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Build" Version="$(MicrosoftBuildPackageVersion)" PrivateAssets="All" /> | ||
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkPackageVersion)" PrivateAssets="All" /> | ||
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(MicrosoftBuildTasksCorePackageVersion)" PrivateAssets="All" /> | ||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCorePackageVersion)" PrivateAssets="All" /> | ||
</ItemGroup> | ||
|
||
</Project> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this now.