Skip to content

Commit

Permalink
Allow rendering contributed contents from nugetize
Browse files Browse the repository at this point in the history
If the project was not packable, we were not rendering anything, which wasn't
very useful when tweaking a project that contributes to a parent package.

This adds that capability by explicitly re-running the GetPackageContents target
with additional indication that we're collecting contents, so that the package path
assignment happens forcedly. Note that this does not account for the potential
retargeting of contents if the referencing project happens to redefine the TF
(i.e. contributing a NS2 library, but referencing project is net472+net5.0, the
lib will actually contribute to both TFMs).

Also make it possible to select a specific project if the directory contains
more than one, by smartly parsing the extra arguments.
  • Loading branch information
kzu committed Oct 22, 2020
1 parent 8c0869d commit 1b01911
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 47 deletions.
11 changes: 10 additions & 1 deletion src/NuGetizer.Tasks/dotnet-nugetize.targets
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Copyright (c) .NET Foundation. All rights reserved.

<Target Name="CopyFilesToOutputDirectory" />

<Target Name="_WritePackageContents" Condition="'$(dotnet-nugetize)' != '' and '$(IsPackable)' == 'true'" AfterTargets="GetPackageContents">
<Target Name="_WritePackageContents" Condition="'$(dotnet-nugetize)' != '' and ('$(IsPackable)' == 'true' or '$(dotnet-nugetize-contents)' == 'true')"
AfterTargets="GetPackageContents">
<ItemGroup Condition="'@(NuspecFile)' == ''">
<NuspecFile Include="$(NuspecFile)" />
</ItemGroup>
Expand All @@ -24,6 +25,14 @@ Copyright (c) .NET Foundation. All rights reserved.
<PackageMetadata Update="@(PackageMetadata)" Nuspec="$(_NuspecFile)" NuPkg="@(PackageTargetPath)" />
<PackageContent Include="@(_PackageContent)" Exclude="@(PackageMetadata)" />
</ItemGroup>
<!-- Force assign path if rendering contents only -->
<AssignPackagePath Files="@(PackageFile)" IsPackaging="true" KnownFolders="@(PackFolderKind)" Condition="'$(dotnet-nugetize-contents)' == 'true'">
<Output TaskParameter="AssignedFiles" ItemName="_AssignedPackageContent" />
</AssignPackagePath>
<ItemGroup Condition="'$(dotnet-nugetize-contents)' == 'true'">
<PackageContent Remove="@(PackageContent)" />
<PackageContent Include="@(_AssignedPackageContent)" />
</ItemGroup>
<WriteItemsToFile Condition="'@(PackageMetadata)' != ''" Overwrite="false" Items="@(PackageMetadata)" ItemName="PackageMetadata" File="$(dotnet-nugetize)" />
<WriteItemsToFile Condition="'@(PackageContent)' != ''" Overwrite="false" Items="@(PackageContent)" ItemName="PackageContent" File="$(dotnet-nugetize)" />
</Target>
Expand Down
152 changes: 106 additions & 46 deletions src/dotnet-nugetize/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,61 +93,52 @@ int Run(string[] args)
int Execute()
{
var tooldir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var project = "";
var invalidChars = Path.GetInvalidPathChars();
var project = extra.Where(arg => arg.IndexOfAny(invalidChars) == -1).FirstOrDefault(arg => File.Exists(arg)) ?? "";
var file = items ?? Path.GetTempFileName();

var projects = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.*proj").ToList();
var solutions = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.sln").ToList();

// TODO: allow specifying which project.
if (solutions.Count == 1)
project = solutions[0];
else if (projects.Count > 1)
project = projects[0];
if (string.IsNullOrEmpty(project))
{
var projects = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.*proj").ToList();
var solutions = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.sln").ToList();

// TODO: allow specifying which project.
if (solutions.Count == 1)
project = solutions[0];
else if (projects.Count > 1)
project = projects[0];
}
else
{
extra.Remove(project);
}

if (File.Exists(file))
File.Delete(file);

// Optimize the "build" so that it doesn't actually do a full compile if possible.

var contentsOnly = false;
if (!Execute(DotnetMuxer.Path.FullName, $"msbuild {project} {string.Join(' ', extra)} -p:dotnet-nugetize=\"{file}\" -t:\"GetPackageContents;Pack\""))
return -1;

var doc = XDocument.Load(file);
var foundPackage = false;

foreach (var metadata in doc.Root.Descendants("PackageMetadata")
.Distinct(AnonymousComparer.Create<XElement>(
(x, y) => x.Element("PackageId")?.Value == y.Element("PackageId")?.Value,
x => x.Element("PackageId")?.Value.GetHashCode() ?? 0)))
if (!File.Exists(file))
{
var packageId = metadata.Element("PackageId").Value;
if (string.IsNullOrEmpty(packageId))
continue;

foundPackage = true;
ColorConsole.WriteLine($"Package: {Path.GetFileName(metadata.Element("NuPkg").Value)}".Yellow());
ColorConsole.WriteLine($" {metadata.Element("Nuspec").Value}".Yellow());
// Re-run requesting contents only.
if (!Execute(DotnetMuxer.Path.FullName, $"msbuild {project} {string.Join(' ', extra)} -p:dotnet-nugetize-contents=true -p:dotnet-nugetize=\"{file}\" -t:\"GetPackageContents\""))
return -1;

var width = metadata.Elements()
.Select(x => x.Name.LocalName.Length)
.OrderByDescending(x => x)
.First();
contentsOnly = true;
}

foreach (var md in metadata.Elements()
.Where(x =>
x.Name != "PackageId" &&
x.Name != "Nuspec" &&
x.Name != "NuPkg")
.OrderBy(x => x.Name.LocalName))
{
ColorConsole.WriteLine($" {md.Name.LocalName.PadRight(width)}: ", md.Value.White());
}
var doc = XDocument.Load(file);

if (contentsOnly)
{
ColorConsole.WriteLine($"Project {project} is not packable, rendering its contributed package contents.".Yellow());

var dependencies = doc.Root.Descendants("PackageContent")
.Where(x =>
"Dependency".Equals(x.Element("PackFolder")?.Value, StringComparison.OrdinalIgnoreCase) &&
packageId == x.Element("PackageId")?.Value)
"Dependency".Equals(x.Element("PackFolder")?.Value, StringComparison.OrdinalIgnoreCase))
.Distinct(AnonymousComparer.Create<XElement>(x =>
x.Attribute("Include").Value + "|" +
x.Element("Version").Value + "|" +
Expand All @@ -172,21 +163,90 @@ int Execute()
ColorConsole.WriteLine($" Contents:".Yellow());

var contents = doc.Root.Descendants("PackageContent")
.Where(x =>
x.Element("PackagePath") != null &&
x.Element("PackageId")?.Value == packageId)
.Where(x => x.Element("PackagePath") != null)
.Distinct(AnonymousComparer.Create<XElement>(x => x.Element("PackagePath").Value))
.OrderBy(x => Path.GetDirectoryName(x.Element("PackagePath").Value))
.ThenBy(x => x.Element("PackagePath").Value);

Render(contents.ToList(), 0, 0, "");
Console.WriteLine();
}

if (!foundPackage)
else
{
ColorConsole.WriteLine($"No package content was found.".Red());
return -1;
var foundPackage = false;

foreach (var metadata in doc.Root.Descendants("PackageMetadata")
.Distinct(AnonymousComparer.Create<XElement>(
(x, y) => x.Element("PackageId")?.Value == y.Element("PackageId")?.Value,
x => x.Element("PackageId")?.Value.GetHashCode() ?? 0)))
{
var packageId = metadata.Element("PackageId").Value;
if (string.IsNullOrEmpty(packageId))
continue;

foundPackage = true;
ColorConsole.WriteLine($"Package: {Path.GetFileName(metadata.Element("NuPkg").Value)}".Yellow());
ColorConsole.WriteLine($" {metadata.Element("Nuspec").Value}".Yellow());

var width = metadata.Elements()
.Select(x => x.Name.LocalName.Length)
.OrderByDescending(x => x)
.First();

foreach (var md in metadata.Elements()
.Where(x =>
x.Name != "PackageId" &&
x.Name != "Nuspec" &&
x.Name != "NuPkg")
.OrderBy(x => x.Name.LocalName))
{
ColorConsole.WriteLine($" {md.Name.LocalName.PadRight(width)}: ", md.Value.White());
}

var dependencies = doc.Root.Descendants("PackageContent")
.Where(x =>
"Dependency".Equals(x.Element("PackFolder")?.Value, StringComparison.OrdinalIgnoreCase) &&
packageId == x.Element("PackageId")?.Value)
.Distinct(AnonymousComparer.Create<XElement>(x =>
x.Attribute("Include").Value + "|" +
x.Element("Version").Value + "|" +
x.Element("TargetFramework").Value))
.OrderBy(x => x.Element("TargetFramework").Value)
.ThenBy(x => x.Attribute("Include").Value)
.ToList();

if (dependencies.Count > 0)
{
ColorConsole.WriteLine($" Dependencies:".Yellow());
foreach (var group in dependencies.GroupBy(x => x.Element("TargetFramework").Value))
{
ColorConsole.WriteLine(" ", group.Key.Green());
foreach (var dependency in group)
{
ColorConsole.WriteLine(" ", dependency.Attribute("Include").Value.White(), $", {dependency.Element("Version").Value}".Gray());
}
}
}

ColorConsole.WriteLine($" Contents:".Yellow());

var contents = doc.Root.Descendants("PackageContent")
.Where(x =>
x.Element("PackagePath") != null &&
x.Element("PackageId")?.Value == packageId)
.Distinct(AnonymousComparer.Create<XElement>(x => x.Element("PackagePath").Value))
.OrderBy(x => Path.GetDirectoryName(x.Element("PackagePath").Value))
.ThenBy(x => x.Element("PackagePath").Value);

Render(contents.ToList(), 0, 0, "");
Console.WriteLine();
}

if (!foundPackage)
{
ColorConsole.WriteLine($"No package content was found.".Red());
return -1;
}
}

Console.WriteLine();
Expand Down

0 comments on commit 1b01911

Please sign in to comment.