Skip to content

Commit efb560b

Browse files
author
Maddie Clayton
authored
Merge pull request #6095 from MiYanni/NetCoreTestCsProj
Test project generation for NetCore
2 parents 1ec6758 + 41aae8b commit efb560b

File tree

4 files changed

+264
-35
lines changed

4 files changed

+264
-35
lines changed

tools/NetCoreCsProjSync/NetCoreCsProjSync/NetCoreCsProjGenerator.cs

Lines changed: 168 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,38 @@ internal static class NetCoreCsProjGenerator
3232
private const string NetCoreFilter = @"*" + NetCoreCsProjExtension;
3333

3434
private const string CommandsFilter = @"Commands.*";
35-
private const string TestFolderDenoter = @".Test";
36-
private const string TestFolderDenoter2 = @".UnitTest";
35+
private static readonly string[] TestFolderDenoters = {@".Test", @".UnitTest", @".Tests"};
36+
37+
private static bool IsTestFolder(string path) => TestFolderDenoters.Any(path.EndsWith);
38+
39+
private static bool HasCsProj(string path, bool ignoreExisting = false) =>
40+
Directory.EnumerateFiles(path, CsProjFilter, SearchOption.TopDirectoryOnly).Any() &&
41+
(ignoreExisting || !Directory.EnumerateFiles(path, NetCoreFilter, SearchOption.TopDirectoryOnly).Any());
3742

3843
// https://stackoverflow.com/a/25245678/294804
3944
public static IEnumerable<string> GetProjectFolderPaths(string rmPath, bool ignoreExisting = false) =>
4045
Directory.EnumerateDirectories(rmPath).SelectMany(md =>
4146
Directory.EnumerateDirectories(md, CommandsFilter).Where(pd =>
42-
!pd.EndsWith(TestFolderDenoter) && !pd.EndsWith(TestFolderDenoter2) &&
43-
Directory.EnumerateFiles(pd, CsProjFilter, SearchOption.TopDirectoryOnly).Any() &&
44-
(ignoreExisting || !Directory.EnumerateFiles(pd, NetCoreFilter, SearchOption.TopDirectoryOnly).Any())));
47+
!IsTestFolder(pd) && HasCsProj(pd, ignoreExisting)));
48+
49+
private static readonly List<(string[] FolderNames, Func<string, IEnumerable<string>> GetTestDirs)?> TestFolderMapper =
50+
new List<(string[] FolderNames, Func<string, IEnumerable<string>> GetTestDirs)?>
51+
{
52+
(new []{"Common", "Storage"},
53+
dir => Directory.EnumerateDirectories(dir).Where(IsTestFolder)),
54+
(new []{"ResourceManager", "StackAdmin"},
55+
dir => Directory.EnumerateDirectories(dir).SelectMany(md => Directory.EnumerateDirectories(md).Where(IsTestFolder)))
56+
};
57+
58+
//https://stackoverflow.com/a/5229311/294804
59+
public static IEnumerable<string> GetTestProjectFolderPaths(string srcPath, bool ignoreExisting = false) =>
60+
Directory.EnumerateDirectories(srcPath)
61+
.SelectMany(dir => TestFolderMapper.FirstOrDefault(m => m?.FolderNames?.Contains(new DirectoryInfo(dir).Name) ?? false)?.GetTestDirs(dir) ?? Enumerable.Empty<string>())
62+
.Where(pd => HasCsProj(pd, ignoreExisting));
63+
64+
public static IEnumerable<string> GetTestDesktopFilePaths(IEnumerable<string> testProjectPaths) =>
65+
testProjectPaths.Select(pd => Directory.EnumerateFiles(pd).Where(f => TestFolderDenoters.Any(tfd => f.EndsWith(tfd + CsProjExtension)))
66+
.First(f => !f.Contains(NetCoreCsProjExtension)));
4567

4668
public static IEnumerable<string> GetDesktopFilePaths(IEnumerable<string> projectPaths) =>
4769
projectPaths.Select(pd => Directory.EnumerateFiles(pd, CsProjFilter, SearchOption.TopDirectoryOnly).First(f => !f.Contains(NetCoreCsProjExtension)));
@@ -119,7 +141,11 @@ private static string CreateVersionFromHintPath(string hintPath)
119141
var slashParts = hintPath.Split('\\');
120142
if (slashParts[0] != "..") return null;
121143

122-
var parts = slashParts[4].Split('.');
144+
var slashPartIndex = slashParts.Select((sp, i) => ((int Index, string SlashPart)?)(Index: i, SlashPart: sp))
145+
.FirstOrDefault(t => t?.SlashPart?.ToLower()?.Contains("packages") ?? false)?.Index;
146+
if (slashPartIndex == null) return null;
147+
148+
var parts = slashParts[slashPartIndex.Value + 1].Split('.');
123149
//https://stackoverflow.com/a/18251942/294804
124150
var firstDigitIndex = parts.Select((p, i) => (Index: i, Part: p)).First(a => a.Part.All(Char.IsDigit)).Index;
125151
//https://stackoverflow.com/a/14435083/294804
@@ -135,11 +161,11 @@ public static string GetVersionString(OldReference oldReference)
135161
return version ?? (hasVersion ? oldReference.Include.Split(',')[1].Replace(versionToken, String.Empty) : null);
136162
}
137163

138-
private static NewPackageReference ConvertOldToNewPackageReference(OldReference oldReference)
164+
public static NewPackageReference ConvertOldToNewPackageReference(OldReference oldReference, IEnumerable<string> skipList)
139165
{
140166
var version = GetVersionString(oldReference);
141167
var include = oldReference.Include.Split(',').First();
142-
return version == null || include == "System.Management.Automation" ? null : new NewPackageReference { Include = include, Version = version };
168+
return version == null || skipList.Contains(include) ? null : new NewPackageReference { Include = include, Version = version };
143169
}
144170

145171
private static string ModifyOutputPath(string outputPath)
@@ -165,7 +191,8 @@ private static string ModifyOutputPath(string outputPath)
165191
{"Commands.Common.Strategies.csproj", "Common.Strategies.Netcore.csproj"},
166192
{"Commands.ResourceManager.Common.csproj", "Common.ResourceManager.Netcore.csproj"},
167193

168-
{"Commands.Resources.Rest.csproj", "Commands.Resources.Rest.Netcore.csproj"}
194+
{"Commands.Resources.Rest.csproj", "Commands.Resources.Rest.Netcore.csproj"},
195+
{"Commands.ScenarioTests.ResourceManager.Common.csproj","Common.ResourceManager.ScenarioTests.Netcore.csproj"}
169196
};
170197

171198
private static string ModifyProjectReferencePath(string includePath)
@@ -180,7 +207,7 @@ private static string ModifyProjectReferencePath(string includePath)
180207
public static NewProjectDefinition ConvertOldToNewNetCore(OldProjectDefinition oldDefinition)
181208
{
182209
var oldReferences = oldDefinition.ItemGroups.Where(ig => ig.References?.Any() ?? false).SelectMany(ig => ig.References);
183-
var newPackageReferences = oldReferences.Select(ConvertOldToNewPackageReference).Where(r => r != null).ToList();
210+
var newPackageReferences = oldReferences.Select(or => ConvertOldToNewPackageReference(or, new []{ "System.Management.Automation" })).Where(r => r != null).ToList();
184211
var packageReferencesItemGroup = !newPackageReferences.Any() ? null : new NewItemGroup
185212
{
186213
PackageReferences = newPackageReferences
@@ -305,5 +332,136 @@ public static NewProjectDefinition ConvertOldToNewNetCore(OldProjectDefinition o
305332
}
306333
};
307334
}
335+
336+
private static readonly List<string> TestReferenceSkipList = new List<string>
337+
{
338+
"Hyak.Common",
339+
"Microsoft.Azure.Common",
340+
"Microsoft.Azure.Common.NetFramework",
341+
"Microsoft.Azure.Gallery",
342+
"Microsoft.Azure.Management.Authorization",
343+
"Microsoft.Azure.Management.ResourceManager",
344+
"Microsoft.Azure.ResourceManager",
345+
"Microsoft.Azure.Test.Framework",
346+
"Microsoft.Azure.Test.HttpRecorder",
347+
"Microsoft.IdentityModel.Clients.ActiveDirectory",
348+
"Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms",
349+
"Microsoft.Rest.ClientRuntime",
350+
"Microsoft.Rest.ClientRuntime.Azure",
351+
"Microsoft.Rest.ClientRuntime.Azure.Authentication",
352+
"Microsoft.Rest.ClientRuntime.Azure.TestFramework",
353+
"Microsoft.Threading.Tasks",
354+
"Microsoft.Threading.Tasks.Extensions",
355+
"Microsoft.Threading.Tasks.Extensions.Desktop",
356+
"Microsoft.WindowsAzure.Management",
357+
"Microsoft.Bcl.Build",
358+
"Microsoft.Data.Edm",
359+
"Microsoft.Data.OData",
360+
"Microsoft.Data.Services.Client",
361+
"Newtonsoft.Json",
362+
"System.Net.Http.Extensions",
363+
"System.Net.Http.Primitives",
364+
"System.Spatial",
365+
"xunit.abstractions",
366+
"xunit.assert",
367+
"xunit.core",
368+
"xunit.execution.desktop"
369+
};
370+
371+
public static NewProjectDefinition ConvertOldTestToNewTestNetCore(OldProjectDefinition oldDefinition)
372+
{
373+
var oldReferences = oldDefinition.ItemGroups.Where(ig => ig.References?.Any() ?? false).SelectMany(ig => ig.References);
374+
var newPackageReferences = oldReferences.Select(or => ConvertOldToNewPackageReference(or, TestReferenceSkipList)).Where(r => r != null).ToList();
375+
var packageReferencesItemGroup = !newPackageReferences.Any() ? null : new NewItemGroup
376+
{
377+
PackageReferences = newPackageReferences
378+
};
379+
380+
var newAssemblyName = oldDefinition.PropertyGroups.First(pg => pg.AssemblyName != null).AssemblyName;
381+
var testDenoter = TestFolderDenoters.First(tfd => oldDefinition.FilePath.Contains(tfd));
382+
var newDllReferenceInclude = newAssemblyName.Replace(testDenoter, String.Empty);
383+
var projectName = newDllReferenceInclude.Split('.').Last();
384+
var isRmModule = oldDefinition.FilePath.Contains("ResourceManager");
385+
386+
var newProjectReferences = oldDefinition.ItemGroups.Where(ig => ig.ProjectReferences?.Any() ?? false).SelectMany(ig => ig.ProjectReferences)
387+
.Where(pr => !(isRmModule && pr.Include.Contains(projectName)))
388+
.Select(pr => new NewProjectReference { Include = ModifyProjectReferencePath(pr.Include) }).ToList();
389+
var projectReferencesItemGroup = !newProjectReferences.Any() ? null : new NewItemGroup
390+
{
391+
ProjectReferences = newProjectReferences
392+
};
393+
394+
var dllReferenceItemGroup = !isRmModule ? null : new NewItemGroup
395+
{
396+
References = new List<NewReference>
397+
{
398+
new NewReference
399+
{
400+
Include = newDllReferenceInclude,
401+
HintPath = $"..\\..\\..\\Package\\$(Configuration)\\ResourceManager\\AzureResourceManager\\AzureRM.{projectName}.Netcore\\{newDllReferenceInclude}.dll"
402+
}
403+
}
404+
};
405+
406+
var projectFolder = Path.GetDirectoryName(oldDefinition.FilePath);
407+
var hasSessionRecords = Directory.Exists(Path.Combine(projectFolder, "SessionRecords"));
408+
var hasScenarioTests = Directory.Exists(Path.Combine(projectFolder, "ScenarioTests"));
409+
var noneItemGroup = !(hasSessionRecords || hasScenarioTests) ? null : new NewItemGroup
410+
{
411+
NoneItems = new List<NewNone>
412+
{
413+
!hasSessionRecords ? null : new NewNone
414+
{
415+
Update = @"SessionRecords\**\*.json",
416+
CopyToOutputDirectory = "PreserveNewest"
417+
},
418+
!hasScenarioTests ? null : new NewNone
419+
{
420+
Update = @"ScenarioTests\*.ps1",
421+
CopyToOutputDirectory = "PreserveNewest"
422+
}
423+
}
424+
};
425+
426+
return new NewProjectDefinition
427+
{
428+
Sdk = "Microsoft.NET.Sdk",
429+
Import = new NewImport
430+
{
431+
Project = @"..\..\..\..\tools\Common.Netcore.Dependencies.Test.targets"
432+
},
433+
PropertyGroups = new List<NewPropertyGroup>
434+
{
435+
new NewPropertyGroup
436+
{
437+
TargetFramework = "netcoreapp2.0",
438+
AssemblyName = newAssemblyName,
439+
RootNamespace = oldDefinition.PropertyGroups.First(pg => pg.RootNamespace != null).RootNamespace,
440+
GenerateAssemblyInfo = false
441+
},
442+
new NewPropertyGroup
443+
{
444+
Condition = "'$(Configuration)|$(Platform)'=='Debug|AnyCPU'",
445+
DelaySign = false,
446+
DefineConstants = "TRACE;DEBUG;NETSTANDARD"
447+
},
448+
new NewPropertyGroup
449+
{
450+
Condition = "'$(Configuration)|$(Platform)'=='Release|AnyCPU'",
451+
SignAssembly = true,
452+
DelaySign = true,
453+
AssemblyOriginatorKeyFile = "MSSharedLibKey.snk",
454+
DefineConstants = "TRACE;RELEASE;NETSTANDARD;SIGN"
455+
}
456+
},
457+
ItemGroups = new List<NewItemGroup>
458+
{
459+
packageReferencesItemGroup,
460+
projectReferencesItemGroup,
461+
dllReferenceItemGroup,
462+
noneItemGroup
463+
}
464+
};
465+
}
308466
}
309467
}

tools/NetCoreCsProjSync/NetCoreCsProjSync/NewModel/NewItemGroup.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,8 @@ public class NewItemGroup
4141

4242
[XmlElement("Content")]
4343
public List<NewContent> ContentItems { get; set; }
44+
45+
[XmlElement("Reference")]
46+
public List<NewReference> References { get; set; }
4447
}
4548
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Xml.Serialization;
17+
18+
namespace NetCoreCsProjSync.NewModel
19+
{
20+
[Serializable]
21+
public class NewReference
22+
{
23+
[XmlAttribute("Include")]
24+
public string Include { get; set; }
25+
26+
[XmlElement("HintPath")]
27+
public string HintPath { get; set; }
28+
}
29+
}

0 commit comments

Comments
 (0)