Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADD] dotnet solution migrate (draft) #44419

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

edvilme
Copy link
Member

@edvilme edvilme commented Oct 23, 2024

Created dotnet solution migrate solutionfile.sln to generate a new solution file with the .slnx extension using https://github.com/microsoft/vs-solutionpersistence

Contributes to #40913 (dotnet sln migrate)

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-CLI untriaged Request triage from a team member labels Oct 23, 2024
@edvilme edvilme changed the title [ADD] dotnet sln: Migrate [ADD] dotnet solution: Migrate Oct 23, 2024
@edvilme edvilme marked this pull request as ready for review October 23, 2024 23:09
@edvilme edvilme requested a review from a team October 23, 2024 23:09
@kasperk81
Copy link
Contributor

kasperk81 commented Oct 24, 2024

unit tests upcoming?

Addresses #40913

I thought addressing that epic also includes:

  • dotnet new solution --format slnx (with alias -f slnx)
  • dotnet sln {add,remove,list} my.slnx my.csproj commands

@edvilme
Copy link
Member Author

edvilme commented Oct 24, 2024

unit tests upcoming?

Hello. Yes, this is still WIP and will have a unit test that verifies if the command work. Additional testing on how the conversion is done, is more related to the https://github.com/microsoft/vs-solutionpersistence project as we just consume their API

@kasperk81
Copy link
Contributor

btw, current main and 9.0.200 branch can "build" .slnx #40913 (comment), so the test can assert on that to cover migration.

you may also consider changing Addresses #40913 to Contributes to #40913 so it doesn't close the issue on merge for additional work (dotnet new sln, dotnet sln {add,remove,list} my.slnx my.csproj), and keep this PR for dotnet sln migrate only.

Directory.Packages.props Outdated Show resolved Hide resolved
Directory.Packages.props Outdated Show resolved Hide resolved
Copy link
Member

@nagilson nagilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks good so far :) I've left some thoughts below. Definitely add some tests like mentioned above. Also, please keep the PR in a draft state if it's still a WIP so it's clear to reviewers.

@@ -177,4 +177,10 @@
<data name="SolutionFolderHeader" xml:space="preserve">
<value>Solution Folder(s)</value>
</data>
</root>
<data name="MigrateAppFullName" xml:space="preserve">
<value>Generate a .slnx solution file from a .sln solution file.</value>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<value>Generate a .slnx solution file from a .sln solution file.</value>
<value>Generate a .slnx file from a .sln file.</value>

I'm not sure whether this makes the wording clearer. @baronfel, thoughts?

<value>Generate a .slnx solution file from a .sln solution file.</value>
</data>
<data name="SlnxGenerated" xml:space="preserve">
<value>Solution file {0} generated.</value>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<value>Solution file {0} generated.</value>
<value>.slnx file {0} generated.</value>

Same here, it would be good to get more feedback on this. I think it should indicate that a slnx file is being produced in particular.


private static CliCommand ConstructCommand()
{
CliCommand command = new("migrate", LocalizableStrings.MigrateAppFullName);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@baronfel I read the spec and this looks good. But I wanted to check if there were any other options/flags you think this command should have?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chatted with @baronfel and he told me that there were no current plans on adding more flags (at least for the time being), though I am happy to modify if needed

throw new GracefulException(CommonLocalizableStrings.CouldNotFindSolutionIn, _slnFileFullPath);
}
string slnxFileFullPath = Path.ChangeExtension(_slnFileFullPath, "slnx");
Task task = ConvertToSlnxAsync(_slnFileFullPath, slnxFileFullPath, CancellationToken.None);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you will want to call RunSynchronously() on this Task. But I haven't used Tasks in eons, so I would check with this.

{
return;
}
SolutionModel solution = await serializer.OpenAsync(filePath, cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should handle the possible SolutionError which this API can throw.

@just-ero
Copy link

Hi, I just want to make sure: this command won't require the solution path to be provided, right? It will take the solution file present in the current directory if no path is specified?

After migrating (I feel like convert would have been a nicer name), does the original solution file get deleted? Renamed? Does it stay?

@edvilme edvilme marked this pull request as draft October 25, 2024 15:18
@edvilme edvilme changed the title [ADD] dotnet solution: Migrate [ADD] dotnet solution migrate (draft) Oct 25, 2024
Copy link
Member

@nagilson nagilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@just-ero raises a great point, many of our commands work if there is only one sln or project file in the directory where you don't need to specify a project or sln to take action on. Some of them even work if there are multiple and just picks one based on some order, like so:

string? potentialSln = Directory.GetFiles(arg, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault();

I don't think this was in the original spec but we should support that. I am very familiar with the code to do that, so if you have questions let me know :)

string slnxFileFullPath = Path.ChangeExtension(_slnFileFullPath, "slnx");
Task task = ConvertToSlnxAsync(_slnFileFullPath, slnxFileFullPath, CancellationToken.None);
_reporter.WriteLine(LocalizableStrings.SlnxGenerated, slnxFileFullPath);
return 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we handle the SolutionError to print a better message, we should handle that and make sure we don't return 0.

@nagilson
Copy link
Member

nagilson commented Oct 25, 2024

After migrating (I feel like convert would have been a nicer name), does the original solution file get deleted? Renamed? Does it stay?

@baronfel? I prefer 'migrate' personally and would keep the original solution file, deleting the file may be unexpected and cause pain there but it could be an option to provide.

@edvilme
Copy link
Member Author

edvilme commented Oct 25, 2024

After migrating (I feel like convert would have been a nicer name), does the original solution file get deleted? Renamed? Does it stay?

@baronfel? I prefer 'migrate' personally and would keep the original solution file, deleting the file may be unexpected and cause pain there but it could be an option to provide.

I also prefer migrate and definitely think we should keep the original solution file at least until the rest of the dotnet sln commands are ready. Otherwise people would run the command with no way of undoing it and things could get messy (?)

I would advocate towards having a --replace flag and additional confirmation from the user if that was the path we wanted to follow

@just-ero
Copy link

string? potentialSln = Directory.GetFiles(arg, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault();

Maybe this command should panic when more than one solution file is found?

@baronfel
Copy link
Member

I've added details to the migration section on the linked issue. We should not delete the pre-existing .sln file, users are free to do that once they have tested and verified the slnx. solves their needs. We should use our existing solution-discovery mechanisms like we do for the other dotnet sln commands. We should error out if there are multiple .sln files in a directory that is used and no explicit sln argument is provided.

@nagilson
Copy link
Member

string? potentialSln = Directory.GetFiles(arg, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault();

Maybe this command should panic when more than one solution file is found?

That is not how other commands behave, so I think its good to be consistent. This is the logic used by other commands.

@edvilme
Copy link
Member Author

edvilme commented Oct 25, 2024

string? potentialSln = Directory.GetFiles(arg, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault();

Maybe this command should panic when more than one solution file is found?

That is not how other commands behave, so I think its good to be consistent. This is the logic used by other commands.

What I've seen so far from SlnFileFactory is that it outputs an error message when two or more are found.

https://github.com/dotnet/sdk/blob/b0bf7b7b4dc36fc8d7b41dac631eced050473870/src/Cli/dotnet/SlnFileFactory.cs#L68C13-L73C14

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-CLI untriaged Request triage from a team member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants