Skip to content

Commit 1cef811

Browse files
authored
Find test-only prebuilts with simple path patterns (#787)
Also, write usage reports before baseline validation to make sure info is always generated.
1 parent d5f808d commit 1cef811

File tree

3 files changed

+79
-40
lines changed

3 files changed

+79
-40
lines changed

repos/dir.targets

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,16 @@
419419
<FailOnPrebuiltBaselineError Condition="'$(FailOnPrebuiltBaselineError)' == ''">false</FailOnPrebuiltBaselineError>
420420
</PropertyGroup>
421421

422+
<ItemGroup>
423+
<PackageVersionPropsSavedSnapshotFiles Include="$(PackageReportDir)snapshots/PackageVersions.props.pre.*.xml" />
424+
</ItemGroup>
425+
426+
<WriteUsageReports DataFile="$(PackageReportDataFile)"
427+
PackageVersionPropsSnapshots="@(PackageVersionPropsSavedSnapshotFiles)"
428+
ProdConBuildManifestFile="$(ProdConManifestFile)"
429+
PoisonedReportFile="$(PoisonedReportFile)"
430+
OutputDirectory="$(PackageReportDir)" />
431+
422432
<PropertyGroup Condition="'$(ContinueOnPrebuiltBaselineError)' == ''">
423433
<ContinueOnPrebuiltBaselineError>false</ContinueOnPrebuiltBaselineError>
424434
<ContinueOnPrebuiltBaselineError Condition="'$(FailOnPrebuiltBaselineError)' != 'true'">true</ContinueOnPrebuiltBaselineError>
@@ -430,16 +440,6 @@
430440
OutputBaselineFile="$(PackageReportDir)generated-new-baseline.xml"
431441
OutputReportFile="$(PackageReportDir)baseline-comparison.xml"
432442
ContinueOnError="$(ContinueOnPrebuiltBaselineError)" />
433-
434-
<ItemGroup>
435-
<PackageVersionPropsSavedSnapshotFiles Include="$(PackageReportDir)snapshots/PackageVersions.props.pre.*.xml" />
436-
</ItemGroup>
437-
438-
<WriteUsageReports DataFile="$(PackageReportDataFile)"
439-
PackageVersionPropsSnapshots="@(PackageVersionPropsSavedSnapshotFiles)"
440-
ProdConBuildManifestFile="$(ProdConManifestFile)"
441-
PoisonedReportFile="$(PoisonedReportFile)"
442-
OutputDirectory="$(PackageReportDir)" />
443443
</Target>
444444

445445
<Target Name="GetProjectDirectory" Outputs="$(ProjectDirectory)" />

tools-local/tasks/Microsoft.DotNet.SourceBuild.Tasks/UsageReport/AnnotatedUsage.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ public class AnnotatedUsage
1414
public string SourceBuildPackageIdCreator { get; set; }
1515
public string ProdConPackageIdCreator { get; set; }
1616
public bool EndsUpInOutput { get; set; }
17+
public bool TestProjectByHeuristic { get; set; }
18+
public bool TestProjectOnlyByHeuristic { get; set; }
1719

1820
public XElement ToXml() => new XElement(
1921
nameof(AnnotatedUsage),
2022
Usage.ToXml().Attributes(),
2123
Project.ToXAttributeIfNotNull(nameof(Project)),
2224
SourceBuildPackageIdCreator.ToXAttributeIfNotNull(nameof(SourceBuildPackageIdCreator)),
2325
ProdConPackageIdCreator.ToXAttributeIfNotNull(nameof(ProdConPackageIdCreator)),
26+
TestProjectByHeuristic.ToXAttributeIfTrue(nameof(TestProjectByHeuristic)),
27+
TestProjectOnlyByHeuristic.ToXAttributeIfTrue(nameof(TestProjectOnlyByHeuristic)),
2428
EndsUpInOutput.ToXAttributeIfTrue(nameof(EndsUpInOutput)));
2529
}
2630
}

tools-local/tasks/Microsoft.DotNet.SourceBuild.Tasks/UsageReport/WriteUsageReports.cs

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -108,54 +108,66 @@ public override bool Execute()
108108

109109
var report = new XElement("AnnotatedUsages");
110110

111-
foreach (Usage usage in data.Usages.NullAsEmpty())
112-
{
113-
string id = usage.PackageIdentity.Id;
114-
string version = usage.PackageIdentity.Version.OriginalVersion;
111+
var annotatedUsages = data.Usages.NullAsEmpty()
112+
.Select(usage =>
113+
{
114+
string id = usage.PackageIdentity.Id;
115+
string version = usage.PackageIdentity.Version.OriginalVersion;
115116

116-
string pvpIdent = WriteBuildOutputProps.GetPropertyName(id);
117+
string pvpIdent = WriteBuildOutputProps.GetPropertyName(id);
117118

118-
var sourceBuildCreator = new StringBuilder();
119-
foreach (RepoOutput output in sourceBuildRepoOutputs)
120-
{
121-
foreach (PackageVersionPropsElement p in output.Built)
119+
var sourceBuildCreator = new StringBuilder();
120+
foreach (RepoOutput output in sourceBuildRepoOutputs)
122121
{
123-
if (p.Name.Equals(pvpIdent, StringComparison.OrdinalIgnoreCase))
122+
foreach (PackageVersionPropsElement p in output.Built)
124123
{
125-
if (sourceBuildCreator.Length != 0)
124+
if (p.Name.Equals(pvpIdent, StringComparison.OrdinalIgnoreCase))
126125
{
126+
if (sourceBuildCreator.Length != 0)
127+
{
128+
sourceBuildCreator.Append(" ");
129+
}
130+
sourceBuildCreator.Append(output.Repo);
127131
sourceBuildCreator.Append(" ");
132+
sourceBuildCreator.Append(p.Name);
133+
sourceBuildCreator.Append("/");
134+
sourceBuildCreator.Append(p.Version);
128135
}
129-
sourceBuildCreator.Append(output.Repo);
130-
sourceBuildCreator.Append(" ");
131-
sourceBuildCreator.Append(p.Name);
132-
sourceBuildCreator.Append("/");
133-
sourceBuildCreator.Append(p.Version);
134136
}
135137
}
136-
}
137138

138-
prodConPackageOrigin.TryGetValue(id, out string prodConCreator);
139+
prodConPackageOrigin.TryGetValue(id, out string prodConCreator);
139140

140-
var annotated = new AnnotatedUsage
141-
{
142-
Usage = usage,
141+
return new AnnotatedUsage
142+
{
143+
Usage = usage,
143144

144-
Project = data.ProjectDirectories
145-
?.FirstOrDefault(p => usage.AssetsFile?.StartsWith(p) ?? false),
145+
Project = data.ProjectDirectories
146+
?.FirstOrDefault(p => usage.AssetsFile?.StartsWith(p) ?? false),
146147

147-
SourceBuildPackageIdCreator = sourceBuildCreator.Length == 0
148-
? null
149-
: sourceBuildCreator.ToString(),
148+
SourceBuildPackageIdCreator = sourceBuildCreator.Length == 0
149+
? null
150+
: sourceBuildCreator.ToString(),
150151

151-
ProdConPackageIdCreator = prodConCreator,
152+
ProdConPackageIdCreator = prodConCreator,
152153

153-
EndsUpInOutput = poisonNupkgFilenames.Contains($"{id}.{version}")
154-
};
154+
TestProjectByHeuristic = IsTestUsageByHeuristic(usage),
155155

156-
report.Add(annotated.ToXml());
156+
EndsUpInOutput = poisonNupkgFilenames.Contains($"{id}.{version}")
157+
};
158+
})
159+
.ToArray();
160+
161+
foreach (var onlyTestProjectUsage in annotatedUsages
162+
.GroupBy(u => u.Usage.PackageIdentity)
163+
.Where(g => g.All(u => u.TestProjectByHeuristic))
164+
.SelectMany(g => g))
165+
{
166+
onlyTestProjectUsage.TestProjectOnlyByHeuristic = true;
157167
}
158168

169+
report.Add(annotatedUsages.Select(u => u.ToXml()));
170+
159171
Directory.CreateDirectory(OutputDirectory);
160172

161173
File.WriteAllText(
@@ -233,6 +245,29 @@ private void AddProdConPackage(
233245
}
234246
}
235247

248+
public static bool IsTestUsageByHeuristic(Usage usage)
249+
{
250+
string[] assetsFileParts = usage.AssetsFile?.Split('/', '\\');
251+
252+
// If the dir name ends in Test(s), it's probably a test project.
253+
// Ignore the first two segments to avoid classifying everything in "src/vstest".
254+
// This also catches "test" dirs that contain many test projects.
255+
if (assetsFileParts?.Skip(2).Any(p =>
256+
p.EndsWith("Tests", StringComparison.OrdinalIgnoreCase) ||
257+
p.EndsWith("Test", StringComparison.OrdinalIgnoreCase)) == true)
258+
{
259+
return true;
260+
}
261+
262+
// CoreFX restores test dependencies during this sync project.
263+
if (assetsFileParts?.Contains("XUnit.Runtime") == true)
264+
{
265+
return true;
266+
}
267+
268+
return false;
269+
}
270+
236271
private class RepoOutput
237272
{
238273
public string Repo { get; set; }

0 commit comments

Comments
 (0)