mono / t4

T4 text templating engine
Other
387 stars 101 forks source link

Parameters are not being expanded in includes and assembly references #107

Open ghost opened 3 years ago

ghost commented 3 years ago

On the visual studio version of t4, includes and assembly references could make use of parameters. This was especially useful when loading assemblies via some msbuild variable that specified an absolute path on the host system, or when many .tt files wanted to refer to a common shared include folder without using the include search path mechanism.

Repro

  1. https://microsoft-my.sharepoint.com/:u:/p/erinlah/EebAQNmLvi5EqvL6OcYN9Q4B5df3E08XrHPxSxMK2lBbcw (only visible to microsoft users)
    • file.tt -- this file includes a reference to <#@ include file="$(SharedIncludes)\shared.ttinclude" #>
    • folder\shared.ttinclude
    • t4 is invoked with -p:SharedIncludes=folder
  2. dotnet tool restore
  3. dotnet restore
  4. dotnet build

[expected] succeeds, produced file.txt

[actual] build fails, error : Could not read included file '$(SharedIncludes)\shared.ttinclude'

paul-michalik commented 2 years ago

It seems that you can use the (Windows) environment variable syntax, this is the closest thing to what I was able to figure out as a compatibility thing: <#@ include file="%SolutionDir%my-template.ttinclude" #>. The run as SolutionDir="$(pwd)/" t4 .... However, the downside is that in order to use this in Visual Studio, you have to set the environment variables at start time, they are not picked up from the MSBuild variables, if you run it via "Run Custom Tool" command.

ghost commented 2 years ago

Thanks for the feedback @paul-michalik. My team has since moved entirely over to the dotnet-t4 implementation, where we can solve this problem by using the EnvironmentVariables option on the Exec msbuild task.

paul-michalik commented 2 years ago

@erinlah-ms How exactly have you solved it?

ghost commented 2 years ago

Hmm, I can't find any of examples at the moment. We went through some back and forth, and the templates blocked on this point, we ended up migrating off of t4 for the time being -- that was before we discovered that dotnet-t4 was still active though; we mistakenly thought this project was dead, but it had just been renamed.

I can't say we have a solution, but if you needed to get it up and running, I'd recommend trying environment variables with t4. Use <Exec Command="dotnet t4 ...." EnvironmentVariables="MyVar=..." /> to pass the values across. Just be careful of the nasty unescaping that the EnvironmentVariables parameter does on the Exec task -- IIRC, it treats both comma and semicolon as special characters, so you can't have either of those in the value you pass through.

paul-michalik commented 2 years ago

Ah, I see hat you mean. It's a pity that such a valuable feature as a built in templating engine is not really supported well across platforms and environments. For now I am trying to set up something which works across platforms and IDEs and that is definitely harder than it should be. What I am trying to figure out is how and where the 'include' directive is exactly implemented in Mono/t4 - there are some nasty differences between the implementation of the Visual Studio host, the one used with MSBuild and Mono/t4... 🤦🏻