-
Notifications
You must be signed in to change notification settings - Fork 1.1k
real structures around package input formats for dotnet new commands #48892
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
base: main
Are you sure you want to change the base?
Conversation
internal interface ITemplateIdentifierArgument; | ||
|
||
#pragma warning disable CS9113 // Parameter is unread. | ||
internal record FileBasedTemplateIdentifier(FileInfo File) : ITemplateIdentifierArgument; | ||
#pragma warning restore CS9113 // Parameter is unread. | ||
|
||
#pragma warning disable CS9113 // Parameter is unread. | ||
internal record PackageIdentifier(PackageIdentity Package) : ITemplateIdentifierArgument; | ||
#pragma warning restore CS9113 // Parameter is unread. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the core logical change - introducing structures to represent the allowed variants of input for package identifiers.
With these defined, we have to then change parsing to create these structures, and change execution to handle the structures potentially-differently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the template engine’s handling of package install inputs to use a unified package@version syntax while updating related user‐facing messages and argument names.
- Updated argument name from NameArgument to PackageIdentifierArgument throughout the codebase.
- Modified string formatting and command examples to replace "::" with "@" for specifying package versions.
- Introduced new parsing logic for template package identifiers, supporting both file paths and package identities.
Reviewed Changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
src/Cli/Microsoft.TemplateEngine.Cli/TemplateSearch/CliTemplateSearchCoordinator.cs | Updated command example argument from NameArgument to PackageIdentifierArgument. |
src/Cli/Microsoft.TemplateEngine.Cli/TemplatePackageDisplay.cs | Changed the string format for package identifiers in display methods. |
src/Cli/Microsoft.TemplateEngine.Cli/TemplatePackageCoordinator.cs | Removed deprecated methods and updated package identifier formatting. |
src/Cli/Microsoft.TemplateEngine.Cli/TemplateInvoker.cs | Updated example usage to reflect the new PackageIdentifierArgument. |
Several xlf files | Updated instruction texts in localized resource files from "::" to "@" with target state changed to needs-review-translation. |
src/Cli/Microsoft.TemplateEngine.Cli/Commands/install/InstallCommandArgs.cs | Modified command argument extraction to use PackageIdentifierArgument and adjusted filtering for LegacyInstallCommand. |
src/Cli/Microsoft.TemplateEngine.Cli/Commands/install/BaseInstallCommand.cs | Replaced NameArgument with PackageIdentifierArgument and added custom parsing logic for template identifiers. |
src/Cli/Microsoft.TemplateEngine.Cli/Commands/SymbolStrings.resx | Updated install command string to use the new package version separator. |
}; | ||
|
||
private static ITemplateIdentifierArgument[]? ParseTemplateIdentifierArguments(ArgumentResult result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider refactoring the inline creation of EngineEnvironmentSettings (line 48–53) by injecting it as a dependency to improve testability and ensure consistency across invocations.
Copilot uses AI. Check for mistakes.
|
||
//workaround for --install source1 --install source2 case | ||
if (installCommand is LegacyInstallCommand && (TemplatePackages.Contains(installCommand.Name) || installCommand.Aliases.Any(alias => TemplatePackages.Contains(alias)))) | ||
if (installCommand is LegacyInstallCommand) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Review the filtering logic for LegacyInstallCommand to ensure that valid file-based identifiers are not unintentionally filtered out, as the current check only applies to PackageIdentifier types.
Copilot uses AI. Check for mistakes.
if (File.Exists(value)) | ||
{ | ||
templateIdentifierArguments.Add(new FileBasedTemplateIdentifier(new FileInfo(value))); | ||
} | ||
else if (Directory.Exists(value) || Directory.Exists(Path.GetDirectoryName(value))) | ||
{ | ||
var environmentSettings = new EngineEnvironmentSettings(new Edge.DefaultTemplateEngineHost("dotnet", "1.0.0"), false, null, null, null, null); | ||
// expand the value pattern to allow for globbing, etc: | ||
foreach (var path in InstallRequestPathResolution.ExpandMaskedPath(value, environmentSettings)) | ||
{ | ||
templateIdentifierArguments.Add(new FileBasedTemplateIdentifier(new FileInfo(path))); | ||
} | ||
} | ||
else if (value.Contains("::") && ParsePackageIdentityWithVersionSeparator(value, "::") is PackageIdentity packageIdentity) | ||
{ | ||
Console.WriteLine(string.Format(LocalizableStrings.Colon_Separator_Deprecated, packageIdentity.Id, packageIdentity.Version is not null ? packageIdentity.Version : string.Empty)); | ||
templateIdentifierArguments.Add(new PackageIdentifier(packageIdentity)); | ||
} | ||
else if (ParsePackageIdentityWithVersionSeparator(value, "@") is PackageIdentity packageIdentityWithAt) | ||
{ | ||
templateIdentifierArguments.Add(new PackageIdentifier(packageIdentityWithAt)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is us pivoting across the different variants - priority is important here to make sure we go 'most selective' to 'least selective'.
one interesting thing to call out is that we're 'expanding' the directory and wildcard scenarios to a list of packages to install directly here - this is a parsing-time operation and gives faster, actionable errors to the user
|
||
if (templateIdentifierArguments.Count == 0) // we have an arity of One or More, so code is expecting that we error before we call the command... | ||
{ | ||
result.AddError("No packages were found for installation. Please provide a valid package identity or path to a template package."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs translation
|
||
if (string.IsNullOrEmpty(packageId)) | ||
{ | ||
throw new ArgumentException("package identity cannot be null or empty", nameof(packageId)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs translation
|
||
if (!NuGetVersion.TryParse(versionString, out var version)) | ||
{ | ||
throw new ArgumentException($"Version {versionString} is not a valid Semantic Version"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs translation
@@ -137,44 +136,6 @@ internal TemplatePackageCoordinator( | |||
return default; | |||
} | |||
|
|||
internal void DisplayUpdateCheckResult(CheckUpdateResult versionCheckResult, ICommandArgs args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleted because it was unused
if (packageIdentifier is PackageIdentifier id) | ||
{ | ||
Reporter.Output.WriteLine(string.Format(LocalizableStrings.Colon_Separator_Deprecated, split[0], split.Length > 1 ? split[1] : string.Empty).Yellow()); | ||
installRequests.Add(new InstallRequest(id.Package.Id, version: id.Package.Version?.ToString(), details: details, force: args.Force)); | ||
} | ||
|
||
foreach (string expandedIdentifier in InstallRequestPathResolution.ExpandMaskedPath(identifier, _engineEnvironmentSettings)) | ||
else if (packageIdentifier is FileBasedTemplateIdentifier fileIdentifier) | ||
{ | ||
installRequests.Add(new InstallRequest(fileIdentifier.File.FullName, version: null, details: details, force: args.Force)); | ||
} | ||
else | ||
{ | ||
installRequests.Add(new InstallRequest(expandedIdentifier, version, details: details, force: args.Force)); | ||
throw new ArgumentException($"Unknown template package identifier type: {packageIdentifier.GetType().Name}"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here's the pivot on the different variants - note that since the C# compiler doesn't do exhaustivity-checks we need a catch-all clause. this clause can be unlocalized because we should only hit it during development time (we shouldn't introduce variants without expanding this)
@@ -314,7 +274,7 @@ internal async Task<NewCommandStatus> EnterUpdateFlowAsync(UpdateCommandArgs com | |||
Reporter.Output.WriteLine(LocalizableStrings.TemplatePackageCoordinator_Update_Info_PackagesToBeUpdated); | |||
foreach (CheckUpdateResult update in updatesToApply) | |||
{ | |||
Reporter.Output.WriteLine($"{update.TemplatePackage!.Identifier}::{update.LatestVersion}".Indent()); | |||
Reporter.Output.WriteLine($"{update.TemplatePackage!.Identifier}@{update.LatestVersion}".Indent()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lots of small updates to use the newer @-based syntax
This is a refactoring for the template engine around the allowed inputs for the package-to-install argument. It also changes some user-facing strings to unify on the
package@version
syntax where appropriate.