Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ public void Cancel() { }
public partial class CreateCSharpManifestResourceName : Microsoft.Build.Tasks.CreateManifestResourceName
{
public CreateCSharpManifestResourceName() { }
public override string SourceFileExtension { get { throw null; } }
protected override string CreateManifestName(string fileName, string linkFileName, string rootNamespace, string dependentUponFileName, System.IO.Stream binaryStream) { throw null; }
protected override bool IsSourceFile(string fileName) { throw null; }
}
Expand All @@ -219,6 +220,8 @@ protected CreateManifestResourceName() { }
[Microsoft.Build.Framework.OutputAttribute]
public Microsoft.Build.Framework.ITaskItem[] ResourceFilesWithManifestResourceNames { get { throw null; } set { } }
public string RootNamespace { get { throw null; } set { } }
public abstract string SourceFileExtension { get; }
public bool UseDependentUponConvention { get { throw null; } set { } }
protected abstract string CreateManifestName(string fileName, string linkFileName, string rootNamespaceName, string dependentUponFileName, System.IO.Stream binaryStream);
public override bool Execute() { throw null; }
protected abstract bool IsSourceFile(string fileName);
Expand All @@ -236,6 +239,7 @@ public CreateProperty() { }
public partial class CreateVisualBasicManifestResourceName : Microsoft.Build.Tasks.CreateManifestResourceName
{
public CreateVisualBasicManifestResourceName() { }
public override string SourceFileExtension { get { throw null; } }
protected override string CreateManifestName(string fileName, string linkFileName, string rootNamespace, string dependentUponFileName, System.IO.Stream binaryStream) { throw null; }
protected override bool IsSourceFile(string fileName) { throw null; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public void Cancel() { }
public partial class CreateCSharpManifestResourceName : Microsoft.Build.Tasks.CreateManifestResourceName
{
public CreateCSharpManifestResourceName() { }
public override string SourceFileExtension { get { throw null; } }
protected override string CreateManifestName(string fileName, string linkFileName, string rootNamespace, string dependentUponFileName, System.IO.Stream binaryStream) { throw null; }
protected override bool IsSourceFile(string fileName) { throw null; }
}
Expand All @@ -149,6 +150,8 @@ protected CreateManifestResourceName() { }
[Microsoft.Build.Framework.OutputAttribute]
public Microsoft.Build.Framework.ITaskItem[] ResourceFilesWithManifestResourceNames { get { throw null; } set { } }
public string RootNamespace { get { throw null; } set { } }
public abstract string SourceFileExtension { get; }
public bool UseDependentUponConvention { get { throw null; } set { } }
protected abstract string CreateManifestName(string fileName, string linkFileName, string rootNamespaceName, string dependentUponFileName, System.IO.Stream binaryStream);
public override bool Execute() { throw null; }
protected abstract bool IsSourceFile(string fileName);
Expand All @@ -166,6 +169,7 @@ public CreateProperty() { }
public partial class CreateVisualBasicManifestResourceName : Microsoft.Build.Tasks.CreateManifestResourceName
{
public CreateVisualBasicManifestResourceName() { }
public override string SourceFileExtension { get { throw null; } }
protected override string CreateManifestName(string fileName, string linkFileName, string rootNamespace, string dependentUponFileName, System.IO.Stream binaryStream) { throw null; }
protected override bool IsSourceFile(string fileName) { throw null; }
}
Expand Down
141 changes: 141 additions & 0 deletions src/Tasks.UnitTests/CreateCSharpManifestResourceName_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,21 @@
using Microsoft.Build.Shared;
using Microsoft.Build.Tasks;
using Microsoft.Build.Utilities;
using Shouldly;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.Build.UnitTests
{
sealed public class CreateCSharpManifestResourceName_Tests
{

private readonly ITestOutputHelper _testOutput;

public CreateCSharpManifestResourceName_Tests(ITestOutputHelper output)
{
_testOutput = output;
}
/// <summary>
/// Test the basic functionality.
/// </summary>
Expand Down Expand Up @@ -377,6 +386,138 @@ public void Regress188319()
Assert.Equal(@"CustomToolTest.SR1", resourceNames[0].ItemSpec);
}

/// <summary>
/// Opt into DependentUpon convention and load the expected file properly.
/// </summary>
[Fact]
public void DependentUpon_UseConvention()
Comment thread
benvillalobos marked this conversation as resolved.
Outdated
{
using (var env = TestEnvironment.Create())
{
var csFile = env.CreateFile("SR1.cs", "namespace MyStuff.Namespace { class Class { } }");
var resXFile = env.CreateFile("SR1.resx", "");

ITaskItem i = new TaskItem(resXFile.Path);
i.SetMetadata("BuildAction", "EmbeddedResource");
// Don't set DependentUpon so it goes by convention

CreateCSharpManifestResourceName t = new CreateCSharpManifestResourceName
{
BuildEngine = new MockEngine(_testOutput),
UseDependentUponConvention = true,
ResourceFiles = new ITaskItem[] { i }
};

t.Execute().ShouldBeTrue("Expected the task to succeed.");

t.ManifestResourceNames.Length.ShouldBe(1, "Only 1 resource file should exist");
Comment thread
benvillalobos marked this conversation as resolved.
Outdated

t.ManifestResourceNames[0].ItemSpec.ShouldBe("MyStuff.Namespace.Class", "Expecting to find the namespace & class name from SR1.cs");
}
}

/// <summary>
/// Opt into DependentUpon convention without creating the equivalent .cs file for our resource file.
/// </summary>
[Fact]
public void DependentUpon_UseConventionFileDoesNotExist()
{
using (var env = TestEnvironment.Create())
{
// cs file doesn't exist for this case.
var resXFile = env.CreateFile("SR1.resx", "");

ITaskItem i = new TaskItem(Path.GetFileName(resXFile.Path));
i.SetMetadata("BuildAction", "EmbeddedResource");
// Don't set DependentUpon so it goes by convention

// Use relative paths to ensure short manifest name based on the path to the resx.
// See CreateManifestNameImpl
env.SetCurrentDirectory(Path.GetDirectoryName(resXFile.Path));

CreateCSharpManifestResourceName t = new CreateCSharpManifestResourceName
{
BuildEngine = new MockEngine(_testOutput),
UseDependentUponConvention = true,
ResourceFiles = new ITaskItem[] { i }
};

t.Execute().ShouldBeTrue("Expected the task to succeed.");

t.ManifestResourceNames.Length.ShouldBe(1, "Only 1 resource should exist");

t.ManifestResourceNames[0].ItemSpec.ShouldBe("SR1", "Expected only the file name.");
}
}

/// <summary>
/// Opt into DependentUponConvention, but include DependentUpon metadata with different name.
/// </summary>
[Fact]
public void DependentUpon_SpecifyNewFile()
{
using (var env = TestEnvironment.Create())
{
var conventionCSFile = env.CreateFile("SR1.cs", "namespace MyStuff.Namespace { class Class { } }");
var nonConventionCSFile = env.CreateFile("SR2.cs", "namespace MyStuff2.Namespace { class Class2 { } }");
var resXFile = env.CreateFile("SR1.resx", "");

ITaskItem i = new TaskItem(resXFile.Path);
i.SetMetadata("BuildAction", "EmbeddedResource");
i.SetMetadata("DependentUpon", "SR2.cs");

CreateCSharpManifestResourceName t = new CreateCSharpManifestResourceName
{
BuildEngine = new MockEngine(_testOutput),
UseDependentUponConvention = true,
ResourceFiles = new ITaskItem[] { i }
};

t.Execute().ShouldBeTrue("Expected the task to succeed.");

t.ManifestResourceNames.Length.ShouldBe(1, "Only 1 resource file should exist");

t.ManifestResourceNames[0].ItemSpec.ShouldBe("MyStuff2.Namespace.Class2", "Expected the namespace & class of SR2.");
}
}



Comment thread
benvillalobos marked this conversation as resolved.
Outdated
/// <summary>
/// When disabling UseDependentUponConvention it will find no .cs file and default to filename.
/// </summary>
[Fact]
public void DependentUpon_DisableConvention()
Comment thread
benvillalobos marked this conversation as resolved.
Outdated
{
using (var env = TestEnvironment.Create())
{
var csFile = env.CreateFile("SR1.cs", "namespace MyStuff.Namespace { class Class { } }");
var resXFile = env.CreateFile("SR1.resx", "");

ITaskItem i = new TaskItem(Path.GetFileName(resXFile.Path));
i.SetMetadata("BuildAction", "EmbeddedResource");
// No need to set DependentUpon

// Use relative paths to ensure short manifest name based on the path to the resx.
// See CreateManifestNameImpl
env.SetCurrentDirectory(Path.GetDirectoryName(resXFile.Path));

CreateCSharpManifestResourceName t = new CreateCSharpManifestResourceName
{
BuildEngine = new MockEngine(_testOutput),
UseDependentUponConvention = false,
ResourceFiles = new ITaskItem[] { i }
};

t.Execute().ShouldBeTrue("Expected the task to succeed.");

t.ManifestResourceNames.Length.ShouldBe(1, "Only 1 resource file should exist");

t.ManifestResourceNames[0].ItemSpec.ShouldBe("SR1", "Expected only the file name.");
}
}


Comment thread
benvillalobos marked this conversation as resolved.
Outdated
/// <summary>
/// helper method for verifying manifest resource names
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Tasks/CreateCSharpManifestResourceName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace Microsoft.Build.Tasks
/// </summary>
public class CreateCSharpManifestResourceName : CreateManifestResourceName
{
public override string SourceFileExtension => ".cs";

/// <summary>
/// Utility function for creating a C#-style manifest name from
/// a resource name.
Expand Down
15 changes: 15 additions & 0 deletions src/Tasks/CreateManifestResourceName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public abstract class CreateManifestResourceName : TaskExtension
/// </summary>
public bool PrependCultureAsDirectory { get; set; } = true;

public bool UseDependentUponConvention { get; set; }

public abstract string SourceFileExtension { get; }
Comment thread
benvillalobos marked this conversation as resolved.
Outdated

/// <summary>
/// The possibly dependent resource files.
/// </summary>
Expand Down Expand Up @@ -142,6 +146,17 @@ CreateFileStream createFileStream
string fileName = resourceFile.ItemSpec;
string dependentUpon = resourceFile.GetMetadata(ItemMetadataNames.dependentUpon);

//If opted into convention and no DependentUpon metadata, go by convention "<filename>.cs" if it exists.
Comment thread
benvillalobos marked this conversation as resolved.
Outdated
if(UseDependentUponConvention && string.IsNullOrEmpty(dependentUpon))
Comment thread
benvillalobos marked this conversation as resolved.
Outdated
{
string conventionDependentUpon = Path.ChangeExtension(fileName, SourceFileExtension);

if(File.Exists(conventionDependentUpon))
Comment thread
benvillalobos marked this conversation as resolved.
Outdated
{
dependentUpon = conventionDependentUpon;
}
}

// Pre-log some information.
bool isDependentOnSourceFile = !string.IsNullOrEmpty(dependentUpon) && IsSourceFile(dependentUpon);

Expand Down
2 changes: 2 additions & 0 deletions src/Tasks/CreateVisualBasicManifestResourceName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace Microsoft.Build.Tasks
/// </summary>
public class CreateVisualBasicManifestResourceName : CreateManifestResourceName
{
public override string SourceFileExtension => ".vb";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an F# equivalent to this somewhere? cc @KevinRansom

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


/// <summary>
/// Utility function for creating a VB-style manifest name from
/// a resource name.
Expand Down
4 changes: 3 additions & 1 deletion src/Tasks/Microsoft.CSharp.CurrentVersion.targets
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<!-- Create manifest names for culture and non-culture Resx files, and for non-culture Non-Resx resources -->
<CreateCSharpManifestResourceName
ResourceFiles="@(EmbeddedResource)"
RootNamespace="$(RootNamespace)"
RootNamespace="$(RootNamespace)"
UseDependentUponConvention="$(EmbeddedResourceUseDependentUponConvention)"
Condition="'%(EmbeddedResource.ManifestResourceName)' == '' and ('%(EmbeddedResource.WithCulture)' == 'false' or '%(EmbeddedResource.Type)' == 'Resx')">

<Output TaskParameter="ResourceFilesWithManifestResourceNames" ItemName="_Temporary" />
Expand All @@ -111,6 +112,7 @@ Copyright (C) Microsoft Corporation. All rights reserved.
ResourceFiles="@(EmbeddedResource)"
RootNamespace="$(RootNamespace)"
PrependCultureAsDirectory="false"
UseDependentUponConvention="$(EmbeddedResourceUseDependentUponConvention)"
Condition="'%(EmbeddedResource.ManifestResourceName)' == '' and '%(EmbeddedResource.WithCulture)' == 'true' and '%(EmbeddedResource.Type)' == 'Non-Resx'">

<Output TaskParameter="ResourceFilesWithManifestResourceNames" ItemName="_Temporary" />
Expand Down
4 changes: 3 additions & 1 deletion src/Tasks/Microsoft.VisualBasic.CurrentVersion.targets
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<CreateVisualBasicManifestResourceName
ResourceFiles="@(EmbeddedResource)"
RootNamespace="$(RootNamespace)"
UseDependentUponConvention="$(EmbeddedResourceUseDependentUponConvention)"
Condition="'%(EmbeddedResource.ManifestResourceName)' == '' and ('%(EmbeddedResource.WithCulture)' == 'false' or '%(EmbeddedResource.Type)' == 'Resx')">

<Output TaskParameter="ResourceFilesWithManifestResourceNames" ItemName="_Temporary" />
Expand All @@ -110,7 +111,8 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<CreateVisualBasicManifestResourceName
ResourceFiles="@(EmbeddedResource)"
RootNamespace="$(RootNamespace)"
PrependCultureAsDirectory="false"
PrependCultureAsDirectory="false"
UseDependentUponConvention="$(EmbeddedResourceUseDependentUponConvention)"
Condition="'%(EmbeddedResource.ManifestResourceName)' == '' and '%(EmbeddedResource.WithCulture)' == 'true' and '%(EmbeddedResource.Type)' == 'Non-Resx'">

<Output TaskParameter="ResourceFilesWithManifestResourceNames" ItemName="_Temporary" />
Expand Down