Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit 5318697

Browse files
mrwardTherzok
authored andcommitted
[Core] Convert strings to paths when calling methods on the string (#9442)
An MSBuild expression such as the following will fail since the path is not converted to a native path when not on Windows. $(SrcRelativeProjectDirectory.IndexOf('/')) Arguments passed were converted but the original string was not. To match MSBuild's behaviour the conversion of the slash characters is only done if the directory exists. Fixes VSTS #1028961 - MSBuild Properties are not fully evaluated causing build to fail
1 parent 280d310 commit 5318697

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,18 @@ bool EvaluateMethod (ReadOnlySpan<char> str, MemberInfo[] member, object instanc
745745
}
746746

747747
// Invoke the method
748+
if (instance is string instanceString &&
749+
instanceString != null &&
750+
instanceString.IndexOf ('\\') >= 0 &&
751+
Path.DirectorySeparatorChar != '\\') {
752+
// Ensure expressions such as $(SomePath.IndexOf('/')) work by using the native path separator.
753+
// The directory must exist.
754+
string convertedInstance = instanceString.Replace ('\\', Path.DirectorySeparatorChar);
755+
if (Path.IsPathRooted (convertedInstance) && Directory.Exists (convertedInstance)) {
756+
val = method.Invoke (convertedInstance, convertedArgs);
757+
return true;
758+
}
759+
}
748760
val = method.Invoke (instance, convertedArgs);
749761
} catch (Exception ex) {
750762
LoggingService.LogError ("MSBuild property evaluation failed: " + str.ToString (), ex);

main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/ProjectTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,21 @@ public async Task MSBuildRuntimeVersionProperty ()
971971
}
972972
}
973973

974+
[Test]
975+
public async Task SubstringOfPath_HandlesForwardSlashesInPath ()
976+
{
977+
if (!Platform.IsMac)
978+
Assert.Ignore ();
979+
980+
string solFile = Util.GetSampleProject ("path-substring-eval", "path-substring-eval.sln");
981+
using (var sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solFile)) {
982+
var p = (DotNetProject)sol.Items [0];
983+
var expectedBaseIntermediateOutputPath = sol.BaseDirectory.Combine ("obj", "src");
984+
var baseIntermediateOutputPath = p.MSBuildProject.EvaluatedProperties.GetPathValue ("BaseIntermediateOutputPath", relativeToProject: false);
985+
Assert.AreEqual (expectedBaseIntermediateOutputPath, baseIntermediateOutputPath);
986+
}
987+
}
988+
974989
[Test]
975990
public async Task ItemDefinitionGroup ()
976991
{
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project>
2+
<PropertyGroup>
3+
<RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))</RepoRoot>
4+
<SrcRelativeProjectDirectory>$(MSBuildProjectDirectory.Substring($(MSBuildThisFileDirectory.Length)))</SrcRelativeProjectDirectory>
5+
<BuildSubPath>$(SrcRelativeProjectDirectory.Substring(0, $(SrcRelativeProjectDirectory.IndexOf('/'))))</BuildSubPath>
6+
<BaseIntermediateOutputPath>$(RepoRoot)obj\$(BuildSubPath)</BaseIntermediateOutputPath>
7+
</PropertyGroup>
8+
</Project>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.26124.0
5+
MinimumVisualStudioVersion = 15.0.26124.0
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "path-substring-eval", "src\project\path-substring-eval.csproj", "{4BE84824-112F-49B2-B44B-56C5C404C2A7}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Debug|x64 = Debug|x64
12+
Debug|x86 = Debug|x86
13+
Release|Any CPU = Release|Any CPU
14+
Release|x64 = Release|x64
15+
Release|x86 = Release|x86
16+
EndGlobalSection
17+
GlobalSection(SolutionProperties) = preSolution
18+
HideSolutionNode = FALSE
19+
EndGlobalSection
20+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
21+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
23+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Debug|x64.ActiveCfg = Debug|Any CPU
24+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Debug|x64.Build.0 = Debug|Any CPU
25+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Debug|x86.ActiveCfg = Debug|Any CPU
26+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Debug|x86.Build.0 = Debug|Any CPU
27+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Release|x64.ActiveCfg = Release|Any CPU
30+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Release|x64.Build.0 = Release|Any CPU
31+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Release|x86.ActiveCfg = Release|Any CPU
32+
{4BE84824-112F-49B2-B44B-56C5C404C2A7}.Release|x86.Build.0 = Release|Any CPU
33+
EndGlobalSection
34+
EndGlobal
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Project Sdk="Microsoft.NET.Sdk">
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net472</TargetFramework>
6+
</PropertyGroup>
7+
</Project>

0 commit comments

Comments
 (0)