Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion src/dotnet-roslyn-tools/Commands/NuGetPublishCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ internal class NuGetPublishCommand
internal static readonly Option<string> SourceOption = new Option<string>(new[] { "--source", "-s" }, () => "https://www.nuget.org", "Package source (URL, UNC/folder path or package source name) to use.");
internal static readonly Option<string> ApiKeyOption = new Option<string>(new[] { "--api-key", "-k" }, "The API key for the server.") { IsRequired = true };
internal static readonly Option<bool> UnlistedOption = new Option<bool>(new[] { "--unlisted", "-u" }, "Whether to publish the packages as unlisted.");
internal static readonly Option<bool> IgnoreMissingPackagesOption = new Option<bool>(new[] { "--ignore", "-i" }, "Whether to ignore missing packages.");

public static Symbol GetCommand()
{
Expand All @@ -30,6 +31,7 @@ public static Symbol GetCommand()
SourceOption,
ApiKeyOption,
UnlistedOption,
IgnoreMissingPackagesOption,
VerbosityOption
};
command.Handler = s_nuGetPublishCommandHandler;
Expand All @@ -47,8 +49,9 @@ public async Task<int> InvokeAsync(InvocationContext context)
var source = context.ParseResult.GetValueForOption(SourceOption)!;
var apiKey = context.ParseResult.GetValueForOption(ApiKeyOption)!;
var unlisted = context.ParseResult.GetValueForOption(UnlistedOption)!;
var ignore = context.ParseResult.GetValueForOption(IgnoreMissingPackagesOption)!;

return await NuGetPublish.PublishAsync(repoName, source, apiKey, unlisted, logger);
return await NuGetPublish.PublishAsync(repoName, source, apiKey, unlisted, ignore, logger);
}
}
}
107 changes: 107 additions & 0 deletions src/dotnet-roslyn-tools/NuGet/Helpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Licensed to the.NET Foundation under one or more agreements.
// The.NET Foundation licenses this file to you under the MIT license.
// See the License.txt file in the project root for more information.

using System.Diagnostics.CodeAnalysis;

namespace Microsoft.RoslynTools.NuGet
{
internal static class Helpers
{
public static readonly string[] RoslynPackageIds =
{
"Microsoft.CodeAnalysis",
"Microsoft.CodeAnalysis.Common",
"Microsoft.CodeAnalysis.Compilers",
"Microsoft.CodeAnalysis.CSharp",
"Microsoft.CodeAnalysis.CSharp.CodeStyle",
"Microsoft.CodeAnalysis.CSharp.Features",
"Microsoft.CodeAnalysis.CSharp.Scripting",
"Microsoft.CodeAnalysis.CSharp.Workspaces",
"Microsoft.CodeAnalysis.EditorFeatures.Text",
"Microsoft.CodeAnalysis.Features",
"Microsoft.CodeAnalysis.Scripting",
"Microsoft.CodeAnalysis.Scripting.Common",
"Microsoft.CodeAnalysis.VisualBasic",
"Microsoft.CodeAnalysis.VisualBasic.CodeStyle",
"Microsoft.CodeAnalysis.VisualBasic.Features",
"Microsoft.CodeAnalysis.VisualBasic.Workspaces",
"Microsoft.CodeAnalysis.Workspaces.Common",
"Microsoft.CodeAnalysis.Workspaces.MSBuild",
"Microsoft.Net.Compilers.Toolset",
"Microsoft.VisualStudio.LanguageServices"
};

public static readonly string[] RoslynSdkPackageIds =
{
"Microsoft.CodeAnalysis.Analyzer.Testing",
"Microsoft.CodeAnalysis.CodeFix.Testing",
"Microsoft.CodeAnalysis.CodeRefactoring.Testing",
"Microsoft.CodeAnalysis.CSharp.Analyzer.Testing",
"Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.MSTest",
"Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.NUnit",
"Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit",
"Microsoft.CodeAnalysis.CSharp.CodeFix.Testing",
"Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.MSTest",
"Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.NUnit",
"Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit",
"Microsoft.CodeAnalysis.CSharp.CodeRefactoring.Testing",
"Microsoft.CodeAnalysis.CSharp.CodeRefactoring.Testing.MSTest",
"Microsoft.CodeAnalysis.CSharp.CodeRefactoring.Testing.NUnit",
"Microsoft.CodeAnalysis.CSharp.CodeRefactoring.Testing.XUnit",
"Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing",
"Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.MSTest",
"Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.NUnit",
"Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.XUnit",
"Microsoft.CodeAnalysis.SourceGenerators.Testing",
"Microsoft.CodeAnalysis.Testing.Verifiers.MSTest",
"Microsoft.CodeAnalysis.Testing.Verifiers.NUnit",
"Microsoft.CodeAnalysis.Testing.Verifiers.XUnit",
"Microsoft.CodeAnalysis.VisualBasic.Analyzer.Testing",
"Microsoft.CodeAnalysis.VisualBasic.Analyzer.Testing.MSTest",
"Microsoft.CodeAnalysis.VisualBasic.Analyzer.Testing.NUnit",
"Microsoft.CodeAnalysis.VisualBasic.Analyzer.Testing.XUnit",
"Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing",
"Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing.MSTest",
"Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing.NUnit",
"Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing.XUnit",
"Microsoft.CodeAnalysis.VisualBasic.CodeRefactoring.Testing",
"Microsoft.CodeAnalysis.VisualBasic.CodeRefactoring.Testing.MSTest",
"Microsoft.CodeAnalysis.VisualBasic.CodeRefactoring.Testing.NUnit",
"Microsoft.CodeAnalysis.VisualBasic.CodeRefactoring.Testing.XUnit",
"Microsoft.CodeAnalysis.VisualBasic.SourceGenerators.Testing",
"Microsoft.CodeAnalysis.VisualBasic.SourceGenerators.Testing.MSTest",
"Microsoft.CodeAnalysis.VisualBasic.SourceGenerators.Testing.NUnit",
"Microsoft.CodeAnalysis.VisualBasic.SourceGenerators.Testing.XUnit"
};

public static bool TryDetermineRoslynPackageVersion([NotNullWhen(returnValue: true)] out string? version)
{
var packageFileName = Directory.GetFiles(Environment.CurrentDirectory, "Microsoft.Net.Compilers.Toolset.*.nupkg").FirstOrDefault();
if (packageFileName is null)
{
version = null;
return false;
}

version = Path.GetFileNameWithoutExtension(packageFileName).Substring(32);
return true;
}

public static bool TryDetermineRoslynSdkPackageVersion([NotNullWhen(returnValue: true)] out string? version)
{
var packageFileName = Directory.GetFiles(Environment.CurrentDirectory, "Microsoft.CodeAnalysis.Analyzer.Testing.*.nupkg").FirstOrDefault();
if (packageFileName is null)
{
version = null;
return false;
}

version = Path.GetFileNameWithoutExtension(packageFileName).Substring(40);
return true;
}

public static string GetPackageFileName(string packageId, string version) => $"{packageId}.{version}.nupkg";

}
}
26 changes: 21 additions & 5 deletions src/dotnet-roslyn-tools/NuGet/NuGetDependencyFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ where regex.Success

var dependencies = new Dictionary<DependencyResult, List<(PackageDependency Dependency, NuGetVersion? DesiredVersion)>>();

await foreach (var dependency in GetAllDependenciesAsync())
var (foundDependencies, idToDependentsMap) = await GetAllDependenciesAsync().ConfigureAwait(false);
foreach (var dependency in foundDependencies)
{
DependencyResult result;
NuGetVersion? desiredVersion = null;
Expand Down Expand Up @@ -125,6 +126,10 @@ where v.Version > dependency.VersionRange.MinVersion.Version
foreach (var (dependency, _) in releaseUnavailablePackages.OrderBy(x => x.Dependency.Id))
{
logger.LogWarning("{DependencyId}, {DependencyMinVersion}", dependency.Id, dependency.VersionRange.MinVersion);

logger.LogWarning("Dependents:");
foreach (var dependent in idToDependentsMap[dependency.Id])
logger.LogWarning($" {dependent}");
}
}

Expand All @@ -135,6 +140,10 @@ where v.Version > dependency.VersionRange.MinVersion.Version
foreach (var (dependency, _) in missingPackages.OrderBy(x => x.Dependency.Id))
{
logger.LogError("{DependencyId}, {DependencyMinVersion}", dependency.Id, dependency.VersionRange.MinVersion);

logger.LogError("Dependents:");
foreach (var dependent in idToDependentsMap[dependency.Id])
logger.LogError($" {dependent}");
}
}

Expand All @@ -146,11 +155,12 @@ where v.Version > dependency.VersionRange.MinVersion.Version
return 1;
}

async IAsyncEnumerable<PackageDependency> GetAllDependenciesAsync()
async Task<(List<PackageDependency> foundDependencies, Dictionary<string, List<string>> idToDependentsMap)> GetAllDependenciesAsync()
{
var local = Repository.Factory.GetCoreV3(packageFolder);
var localFinder = await local.GetResourceAsync<FindPackageByIdResource>().ConfigureAwait(false);
var foundPackages = new HashSet<string>();
var idToDependentsMap = new Dictionary<string, List<string>>();
var foundDependencies = new List<PackageDependency>();

foreach (var package in packages)
{
Expand All @@ -161,13 +171,19 @@ async IAsyncEnumerable<PackageDependency> GetAllDependenciesAsync()
{
foreach (var dependency in group.Packages)
{
if (foundPackages.Add(dependency.Id))
if (!idToDependentsMap.TryGetValue(dependency.Id, out var dependentsList))
{
yield return dependency;
foundDependencies.Add(dependency);
dependentsList = new List<string>();
idToDependentsMap[dependency.Id] = dependentsList;
}

dependentsList.Add(package);
}
}
}

return (foundDependencies, idToDependentsMap);
}
}
}
Expand Down
45 changes: 5 additions & 40 deletions src/dotnet-roslyn-tools/NuGet/NuGetPrepare.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,20 @@
// See the License.txt file in the project root for more information.

using Microsoft.Extensions.Logging;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using static Microsoft.RoslynTools.NuGet.Helpers;

namespace Microsoft.RoslynTools.NuGet
{
internal class NuGetPrepare
{
private const string NotPublishedDirectoryName = "NotPublished";

private static readonly string[] RoslynPackageIds =
{
"Microsoft.CodeAnalysis",
"Microsoft.CodeAnalysis.Common",
"Microsoft.CodeAnalysis.Compilers",
"Microsoft.CodeAnalysis.CSharp",
"Microsoft.CodeAnalysis.CSharp.CodeStyle",
"Microsoft.CodeAnalysis.CSharp.Features",
"Microsoft.CodeAnalysis.CSharp.Scripting",
"Microsoft.CodeAnalysis.CSharp.Workspaces",
"Microsoft.CodeAnalysis.EditorFeatures.Text",
"Microsoft.CodeAnalysis.Features",
"Microsoft.CodeAnalysis.Scripting",
"Microsoft.CodeAnalysis.Scripting.Common",
"Microsoft.CodeAnalysis.VisualBasic",
"Microsoft.CodeAnalysis.VisualBasic.CodeStyle",
"Microsoft.CodeAnalysis.VisualBasic.Features",
"Microsoft.CodeAnalysis.VisualBasic.Workspaces",
"Microsoft.CodeAnalysis.Workspaces.Common",
"Microsoft.CodeAnalysis.Workspaces.MSBuild",
"Microsoft.Net.Compilers.Toolset",
"Microsoft.VisualStudio.LanguageServices"
};

internal static async Task<int> PrepareAsync(ILogger logger)
{
try
{
string? version;

var determinedVersion = TryDetermineRoslynPackageVersion(out version);

if (!determinedVersion)
Expand All @@ -49,10 +25,12 @@ internal static async Task<int> PrepareAsync(ILogger logger)
return 1;
}

Contract.Assert(version is not null);

logger.LogInformation($"Moving {version} packages...");

var publishedPackages = RoslynPackageIds
.Select(packageId => $"{packageId}.{version}.nupkg")
.Select(packageId => GetPackageFileName(packageId, version))
.ToHashSet();

if (!Directory.Exists(NotPublishedDirectoryName))
Expand Down Expand Up @@ -85,19 +63,6 @@ internal static async Task<int> PrepareAsync(ILogger logger)

return 0;

static bool TryDetermineRoslynPackageVersion([NotNullWhen(returnValue: true)] out string? version)
{
var packageFileName = Directory.GetFiles(Environment.CurrentDirectory, "Microsoft.Net.Compilers.Toolset.*.nupkg").FirstOrDefault();
if (packageFileName is null)
{
version = null;
return false;
}

version = Path.GetFileNameWithoutExtension(packageFileName).Substring(32);
return true;
}

static bool IsPublishedPackage(string packagePath, HashSet<string> publishedPackages)
{
var packageFileName = Path.GetFileName(packagePath);
Expand Down
Loading