Skip to content

Commit c898476

Browse files
edvilmekasperk81nagilson
authored
[ADD] dotnet solution migrate (#44419)
Co-authored-by: kasperk81 <[email protected]> Co-authored-by: Noah Gilson <[email protected]>
1 parent a4163c9 commit c898476

20 files changed

+301
-10
lines changed

Directory.Packages.props

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project>
2-
<Import Project="$(RepositoryEngineeringDir)\dependabot\Packages.props" Condition="'$(RepositoryEngineeringDir)' != ''"/>
2+
<Import Project="$(RepositoryEngineeringDir)\dependabot\Packages.props" Condition="'$(RepositoryEngineeringDir)' != ''" />
33
<PropertyGroup>
44
<!-- Using multiple feeds isn't supported by Maestro: https://github.com/dotnet/arcade/issues/14155. -->
55
<NoWarn>$(NoWarn);NU1507</NoWarn>
@@ -12,7 +12,7 @@
1212
<PackageVersion Include="Microsoft.AspNetCore.DeveloperCertificates.XPlat" Version="$(MicrosoftAspNetCoreDeveloperCertificatesXPlatPackageVersion)" />
1313
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal" Version="$(MicrosoftAspNetCoreMvcRazorExtensionsToolingInternalPackageVersion)" />
1414
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreTestHostPackageVersion)" />
15-
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="$(MicrosoftBclAsyncInterfacesPackageVersion)"/>
15+
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="$(MicrosoftBclAsyncInterfacesPackageVersion)" />
1616
<PackageVersion Include="Microsoft.Build.NuGetSdkResolver" Version="$(MicrosoftBuildNuGetSdkResolverPackageVersion)" />
1717
<PackageVersion Include="Microsoft.CodeAnalysis" Version="$(MicrosoftCodeAnalysisPackageVersion)" />
1818
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzer.Testing" Version="$(MicrosoftCodeAnalysisAnalyzerTestingVersion)" />
@@ -43,7 +43,7 @@
4343
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingVersion)" />
4444
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsVersion)" />
4545
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsoleVersion)" />
46-
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="$(MicrosoftExtensionsObjectPoolPackageVersion)"/>
46+
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="$(MicrosoftExtensionsObjectPoolPackageVersion)" />
4747
<PackageVersion Include="Microsoft.FSharp.Compiler" Version="$(MicrosoftFSharpCompilerPackageVersion)" />
4848
<PackageVersion Include="Microsoft.IO.Redist" Version="$(MicrosoftIORedistPackageVersion)" />
4949
<PackageVersion Include="Microsoft.Net.Compilers.Toolset.Framework" Version="$(MicrosoftNetCompilersToolsetFrameworkPackageVersion)" />
@@ -67,6 +67,7 @@
6767
<PackageVersion Include="Microsoft.TestPlatform.CLI" Version="$(MicrosoftTestPlatformCLIPackageVersion)" />
6868
<PackageVersion Include="Microsoft.VisualStudio.Composition" Version="17.4.16" />
6969
<PackageVersion Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="$(MicrosoftVisualStudioSetupConfigurationInteropVersion)" />
70+
<PackageVersion Include="Microsoft.VisualStudio.SolutionPersistence" Version="1.0.9" />
7071
<PackageVersion Include="Microsoft.Web.Deployment" Version="$(WebDeploymentPackageVersion)" />
7172
<PackageVersion Include="Microsoft.Web.Xdt" Version="$(MicrosoftWebXdtPackageVersion)" />
7273
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="$(MicrosoftWin32SystemEventsPackageVersion)" />
@@ -95,11 +96,11 @@
9596
<PackageVersion Include="System.CommandLine" Version="$(SystemCommandLineVersion)" />
9697
<PackageVersion Include="System.CommandLine.Rendering" Version="$(SystemCommandLineRenderingVersion)" />
9798
<PackageVersion Include="System.ComponentModel.TypeConverter" Version="4.3.0" />
98-
<PackageVersion Include="System.Composition.AttributedModel" Version="$(SystemCompositionAttributedModelPackageVersion)"/>
99-
<PackageVersion Include="System.Composition.Convention" Version="$(SystemCompositionConventionPackageVersion)"/>
100-
<PackageVersion Include="System.Composition.Hosting" Version="$(SystemCompositionHostingPackageVersion)"/>
101-
<PackageVersion Include="System.Composition.Runtime" Version="$(SystemCompositionRuntimePackageVersion)"/>
102-
<PackageVersion Include="System.Composition.TypedParts" Version="$(SystemCompositionTypedPartsPackageVersion)"/>
99+
<PackageVersion Include="System.Composition.AttributedModel" Version="$(SystemCompositionAttributedModelPackageVersion)" />
100+
<PackageVersion Include="System.Composition.Convention" Version="$(SystemCompositionConventionPackageVersion)" />
101+
<PackageVersion Include="System.Composition.Hosting" Version="$(SystemCompositionHostingPackageVersion)" />
102+
<PackageVersion Include="System.Composition.Runtime" Version="$(SystemCompositionRuntimePackageVersion)" />
103+
<PackageVersion Include="System.Composition.TypedParts" Version="$(SystemCompositionTypedPartsPackageVersion)" />
103104
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerPackageVersion)" />
104105
<PackageVersion Include="System.Formats.Asn1" Version="$(SystemFormatsAsn1Version)" />
105106
<PackageVersion Include="System.IO.Hashing" Version="$(SystemIOHashingPackageVersion)" />
@@ -120,7 +121,7 @@
120121
<PackageVersion Include="Valleysoft.DockerCredsProvider" Version="2.2.1" />
121122
<PackageVersion Include="xunit" Version="$(XUnitVersion)" />
122123
<PackageVersion Include="Xunit.Combinatorial" Version="$(XunitCombinatorialVersion)" />
123-
<PackageVersion Include="xunit.console" Version="$(XUnitVersion)"/>
124+
<PackageVersion Include="xunit.console" Version="$(XUnitVersion)" />
124125
</ItemGroup>
125126

126127
<!-- Use different versions of Microsoft.Build.* depending on whether the output will be used in

src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,10 @@
177177
<data name="SolutionFolderHeader" xml:space="preserve">
178178
<value>Solution Folder(s)</value>
179179
</data>
180-
</root>
180+
<data name="MigrateAppFullName" xml:space="preserve">
181+
<value>Generate a .slnx file from a .sln file.</value>
182+
</data>
183+
<data name="SlnxGenerated" xml:space="preserve">
184+
<value>.slnx file {0} generated.</value>
185+
</data>
186+
</root>

src/Cli/dotnet/commands/dotnet-sln/SlnCommandParser.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.CommandLine;
5+
using Microsoft.DotNet.Cli.Utils;
6+
using Microsoft.DotNet.Tools;
57
using NuGet.Packaging;
68
using LocalizableStrings = Microsoft.DotNet.Tools.Sln.LocalizableStrings;
79

@@ -37,10 +39,33 @@ private static CliCommand ConstructCommand()
3739
command.Subcommands.Add(SlnAddParser.GetCommand());
3840
command.Subcommands.Add(SlnListParser.GetCommand());
3941
command.Subcommands.Add(SlnRemoveParser.GetCommand());
42+
command.Subcommands.Add(SlnMigrateCommandParser.GetCommand());
4043

4144
command.SetAction((parseResult) => parseResult.HandleMissingCommand());
4245

4346
return command;
4447
}
48+
49+
internal static string GetSlnFileFullPath(string slnFileOrDirectory)
50+
{
51+
if (File.Exists(slnFileOrDirectory))
52+
{
53+
return slnFileOrDirectory;
54+
}
55+
if (Directory.Exists(slnFileOrDirectory))
56+
{
57+
var files = Directory.GetFiles(slnFileOrDirectory, "*.sln", SearchOption.TopDirectoryOnly);
58+
if (files.Length == 0)
59+
{
60+
throw new GracefulException(CommonLocalizableStrings.CouldNotFindSolutionIn, slnFileOrDirectory);
61+
}
62+
if (files.Length > 1)
63+
{
64+
throw new GracefulException(CommonLocalizableStrings.MoreThanOneSolutionInDirectory, slnFileOrDirectory);
65+
}
66+
return files.Single().ToString();
67+
}
68+
throw new GracefulException(CommonLocalizableStrings.CouldNotFindSolutionOrDirectory, slnFileOrDirectory);
69+
}
4570
}
4671
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.CommandLine;
7+
using System.Linq;
8+
using System.Text;
9+
using System.IO;
10+
using System.Threading.Tasks;
11+
using Microsoft.DotNet.Cli.Utils;
12+
using Microsoft.DotNet.Tools;
13+
using Microsoft.VisualStudio.SolutionPersistence;
14+
using Microsoft.VisualStudio.SolutionPersistence.Model;
15+
using Microsoft.VisualStudio.SolutionPersistence.Serializer;
16+
using LocalizableStrings = Microsoft.DotNet.Tools.Sln.LocalizableStrings;
17+
18+
namespace Microsoft.DotNet.Cli
19+
{
20+
internal class SlnMigrateCommand : CommandBase
21+
{
22+
private readonly string _slnFileOrDirectory;
23+
private readonly IReporter _reporter;
24+
public SlnMigrateCommand(
25+
ParseResult parseResult,
26+
IReporter reporter = null)
27+
: base(parseResult)
28+
{
29+
_slnFileOrDirectory = Path.GetFullPath(parseResult.GetValue(SlnCommandParser.SlnArgument));
30+
_reporter = reporter ?? Reporter.Output;
31+
}
32+
33+
public override int Execute()
34+
{
35+
string slnFileFullPath = SlnCommandParser.GetSlnFileFullPath(_slnFileOrDirectory);
36+
string slnxFileFullPath = Path.ChangeExtension(slnFileFullPath, "slnx");
37+
try
38+
{
39+
ConvertToSlnxAsync(slnFileFullPath, slnxFileFullPath, CancellationToken.None).Wait();
40+
return 0;
41+
} catch (Exception ex) {
42+
throw new GracefulException(ex.Message, ex);
43+
}
44+
}
45+
46+
private async Task ConvertToSlnxAsync(string filePath, string slnxFilePath, CancellationToken cancellationToken)
47+
{
48+
// See if the file is a known solution file.
49+
ISolutionSerializer? serializer = SolutionSerializers.GetSerializerByMoniker(filePath);
50+
if (serializer is null)
51+
{
52+
throw new GracefulException("Could not find serializer for file {0}", filePath);
53+
}
54+
SolutionModel solution = await serializer.OpenAsync(filePath, cancellationToken);
55+
await SolutionSerializers.SlnXml.SaveAsync(slnxFilePath, solution, cancellationToken);
56+
_reporter.WriteLine(LocalizableStrings.SlnxGenerated, slnxFilePath);
57+
}
58+
}
59+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.CommandLine;
5+
using Microsoft.DotNet.Tools.Sln.Add;
6+
using LocalizableStrings = Microsoft.DotNet.Tools.Sln.LocalizableStrings;
7+
8+
namespace Microsoft.DotNet.Cli
9+
{
10+
public static class SlnMigrateCommandParser
11+
{
12+
private static readonly CliCommand Command = ConstructCommand();
13+
14+
public static CliCommand GetCommand()
15+
{
16+
return Command;
17+
}
18+
19+
private static CliCommand ConstructCommand()
20+
{
21+
CliCommand command = new("migrate", LocalizableStrings.MigrateAppFullName);
22+
23+
command.Arguments.Add(SlnCommandParser.SlnArgument);
24+
25+
command.SetAction((parseResult) => new SlnMigrateCommand(parseResult).Execute());
26+
27+
return command;
28+
}
29+
}
30+
}

src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)