Installing template with same identity silently hides previously instaleed template
Background:
When installing new template with the same identity, any previously installed template installed with the same identity (e.g from different location or/and with different name), will be silently hiden - it's not present in dotnet new list and cannot be isntantiated via shortname. It's only present in dotnet new uninstall list
Example:
> dotnet new install templateA
The following template packages will be installed:
C:\tmp\templateA
Success: C:\tmp\templateA installed the following templates:
Template Name Short Name Language Tags
------------- ---------- -------- -------
Name A name-a [C#] Console
> dotnet new list
These templates matched your input:
Template Name Short Name Language Tags
----------------------------------- --------------------------------------- ---------- -------------------------------------
Name A name-a [C#] Console
> dotnet new install templateB
The following template packages will be installed:
C:\tmp\templateB
Success: C:\tmp\templateB installed the following templates:
Template Name Short Name Language Tags
------------- ---------- -------- -------
Name B name-b [C#] Console
> dotnet new list
These templates matched your input:
Template Name Short Name Language Tags
----------------------------------- --------------------------------------- ---------- -------------------------------------
Name B name-b [C#] Console
> dotnet new name-a
No templates found matching: 'name-a'.
To list installed templates, run:
dotnet new list
To search for the templates on NuGet.org, run:
dotnet new search name-a
> dotnet new uninstall
C:\tmp\templateA
Uninstall Command:
dotnet new uninstall C:\tmp\templateA
C:\tmp\templateB
Templates:
Name B (name-b) C#
Uninstall Command:
dotnet new uninstall C:\tmp\templateB
Expected behavior: User is warned and prompted to force the action if needed (or at least to first uninstall the previously installed template).
Agree with the proposed solution, let's make it happen :thumbsup:
There are multiple cases depending on the providers the templates with the same identity are coming from:
- identical templates are coming from unmanaged providers
- identical templates are coming from managed provider
- identical templates are coming from managed and unmanaged providers - was already solved in https://github.com/dotnet/templating/issues/4298
We need to solve other 2:
- for unmanaged providers the best thing we can do is to show warning if it happens
- for managed providers - we should not allow to install the template with identity that is already available.
@vlada-shubina suggested a possible approach for fixing it:
- after the template package is acquired, do a scan of it to identify contained templates, see https://github.com/dotnet/templating/blob/168503eed12ad7b63775256567fe65d85ef52a99/src/Microsoft.TemplateEngine.Edge/Settings/Scanner.cs#L53
- if there are any templates with same identity that already exist, handle this case - report installation error, depends on desired outcome, uninstall the installed template
- likely we want to check the templates within same provider or providers at same priority. It may be a correct case when same templates are coming from different providers, then provider with highest prio wins
@JanKrivanek opinion: I'm bit split on 'silent' win of provider with higher priority - it's probably be good to at least output warning in such case. Requiring to specify force might probably create issues during SDK update if user has custom template with identity that would conflict with identity of some new template in the new SDK version (I guess?) - if that's true, then requiring force is not a good idea.
The current architecture doesn't allow to have the planned fix due to next reasons:
- The atomic nature of the parallel installation can't allow just updating the cache - its state is inconsistent during installation.
- The update operation that happens during installation isn't tracked in the cache immediately too.
- Installation calls uninstall operation when
--forceflag is passed - it also breaks the cache and it can't be trusted anymore.
The fix of the aspects described above requires dramatical changes in GlobalSettingsTemplatePackageProvider.cs - dotnet/templating crucial thing, it was decided to introduce adding a warning message if identities overlap and create a separate story for refactoring installation approach.