dotnet / templating

This repo contains the Template Engine which is used by dotnet new
https://docs.microsoft.com/dotnet/
MIT License
1.64k stars 370 forks source link

Exclude some values from being replaced by the name #5719

Closed manuelelucchi closed 1 year ago

manuelelucchi commented 1 year ago

Hi, I'm currently building a template called generically "Template" (I know, poor choice) where the name is substituted with the chosen name. The problem is, some times there are things that include "Template" in their name, like for example IconTemplate. Is there a way to exclude certain words from being replaced? Also, I noticed that while my template specifies the namespaces the C# 9 way (without the brakets) the project is generated with the brackets on the namespace. Any idea on this? Thanks

yassinebennani commented 1 year ago

Hi

you can use copyOnly to avoid processing a file :

"sources": [ { "modifiers": [ { "copyOnly": [ "IconTemplate" ] } ] } ]

also you can avoid processing a part of the file content by puting it inside

//-:cnd:noEmit

//+:cnd:noEmit

no idea for your last issue

manuelelucchi commented 1 year ago

Thank you!

vlada-shubina commented 1 year ago

@manuelelucchi could you please specify:

Thank you.

On the first question, @yassinebennani 's answer is fully correct, you can check more examples here: https://github.com/dotnet/templating/wiki/Conditional-processing-and-comment-syntax#ignore-conditions-expressions-in-language-files

manuelelucchi commented 1 year ago

Hi @vlada-shubina, I use the dotnet CLI, with the following dotnet --info output

.NET SDK:
 Version:   7.0.100
 Commit:    e12b7af219

Ambiente di runtime:
 OS Name:     Windows
 OS Version:  10.0.22621
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\7.0.100\

Host:
  Version:      7.0.0
  Architecture: x64
  Commit:       d099f075e4

.NET SDKs installed:
  7.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.31 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.31 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.31 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

I have another question: I'm trying to replace some values (particularly, namespaces) with two different constants depending on the boolean value of a parameter: how should I do it? I've seen the constant generator but it doesn't appear to have any type of condition Thank you, Manuele

Edit: the suggestion you gave me above is not quite what I'm searching for. When you generate the template and give it a name, it replaces the default name with the choosen one for each instance. But I want that for a specific word, not file, this rule to not apply

vlada-shubina commented 1 year ago

@manuelelucchi

please refer to https://github.com/dotnet/templating/wiki/Conditional-processing-and-comment-syntax for conditional processing.

For C# the example is here: https://github.com/dotnet/templating/wiki/Conditional-processing-and-comment-syntax#c-sample. if-else syntax is also supported.

#if( useNamespaceA )
namespace A;
#else
namespace B;
#endif  

For disabling the condition processing refer to: https://github.com/dotnet/templating/wiki/Conditional-processing-and-comment-syntax#ignore-conditions-expressions-in-language-files

If those manual doesn't help, please share your template with specific questions. The template might be simplified to reproduce only the issues occurred.

manuelelucchi commented 1 year ago

@vlada-shubina For the first question, the -:cnd:noEmit is not working. I'm not sure if I'm doing it correctly since the documentation uses a lot of time to explain obvious things but completely skips some key informations. I'm currently doing it like this

image

It SHOULD block the template generator to rename IconTemplate to IconWhatever, but it doesn't

For the second question, I know conditional processing exists, but I'm trying to rename part of a namespace to another if a certain parameter is set, so to avoid having to place ifs on every single using or namespace declaration of the template. For example, if I have a boolean parameter, ONLY IF IT'S TRUE, I would want all the text like ".Core." (a typical part of the namespace) to become ".Shared."

Thank you

vlada-shubina commented 1 year ago

@manuelelucchi

Could you please clarify the file type where condition disabling doesn't work? The syntax depends on that.

For the second issue, could you please provide the template reproducing it or at least the parts of configuration you tried here, the expected and actual result.

Thank you.

manuelelucchi commented 1 year ago

@vlada-shubina

The file type is razor as you can see from the screenshot

For the second issue, I attach a repro that doesn't actually reproduce since my problem is that I don't know how to do a certain thing, but I described it the better I can using comments TemplateRepro.zip

vlada-shubina commented 1 year ago

@manuelelucchi

https://github.com/dotnet/templating/issues/5719 showcases solutions for both issues. If you'd like to disable replacements, you'd need to use replacements flag instead of 'cnd` (conditions). Not sure if I understand your idea for the second issue, but the test shows how to achieve behavior from the repro template.

Also worth to mention that Template is not a good choice for source name, due to it creates same values for some of the forms applied to sourceName. My recommendation will be Template.1. See more info in this article.

manuelelucchi commented 1 year ago

@vlada-shubina

For the first problem, replacements works. I don't know where it's documented since only cnd is cited, but it finally works

For the second issue, I really don't get what's difficult to understand. I'll try one last time. On the aspnetcore repo, there are the templates for Blazor projects, that you can choose via a parameter during the project creation. Both Webasm and Server have the same file, WeatherForecast.cs, but in the template, for whatever reason, it's not the same shared file but there are two different files where only the namespace changes

Now, I have basically the same issue, I want the namespace to change based on a parameter, but since this needs to happen on multiple files, I want a way to do it automatically using the template engine So, using again the blazor template as an example ProjectName.Shared should become ProjectName.Data automatically

vlada-shubina commented 1 year ago

Referenced test demonstrated how you can change the namespace based on condition that uses boolean parameter specified by user with part of the namespace being replaced by the name specified by user - the example from the template attached earlier. When using this approach, you'd need to use same condition in all files that need to have the namespace.

Alternative way avoiding conditions in content may be to use join and switch generated symbols to construct the namespace and decide which one to use and perform the replacement.

manuelelucchi commented 1 year ago

I think switch could be the solution. I'll try, thanks

manuelelucchi commented 1 year ago

It works, just a notice that I don't know if you are aware of: if you use in the switch cases conditions a computed property, it doesn't work. Parameters works fine