Drizin / CodegenCS

C# Toolkit for Code Generation (T4 alternative!)
MIT License
223 stars 30 forks source link

Execute extension if output file is missing #31

Open uholeschak opened 1 week ago

uholeschak commented 1 week ago

At the moment the extension is only execute when source the file is saved. If the output file is missing, you have to call the extension manually from the VS context menu one time. Is there is way to execute the extension if the output file is missing?

Drizin commented 1 week ago

Currently, the VS Extension just adds those context-menus and sets the CustomTool property of the script, which retriggers the execution whenever the file is modified/saved. In order to get that I can think of a few solutions:

uholeschak commented 1 week ago

The second solutions seems to be most elegant. How could I call it from the prebuild event if only the extension is installed? What ist the path to dotnet-codegencs?

Drizin commented 5 days ago

Install: dotnet tool install --global dotnet-codegencs

If dotnet-codegencs doesn't get added to your path, you can find it here:

uholeschak commented 5 days ago

Thanks for the info. When calling it with: dotnet-codegencs.exe template run "$(ProjectDir)User" -r:System.Xml.dll I get the error:

1>  CS0246: Line 25 Der Typ- oder Namespacename "VSExecutionContext" wurde nicht gefunden (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis).
1>  CS1069: Line 56 Der Typname "XmlDocument" konnte nicht im Namespace "System.Xml" gefunden werden. Dieser Typ wurde an Assembly "System.Xml.ReaderWriter, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" weitergeleitet. Sie sollten einen Verweis auf die Assembly hinzufügen.
1>  CS1069: Line 56 Der Typname "XmlDocument" konnte nicht im Namespace "System.Xml" gefunden werden. Dieser Typ wurde an Assembly "System.Xml.ReaderWriter, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" weitergeleitet. Sie sollten einen Verweis auf die Assembly hinzufügen.
1>  CS1069: Line 58 Der Typname "XmlNode" konnte nicht im Namespace "System.Xml" gefunden werden. Dieser Typ wurde an Assembly "System.Xml.ReaderWriter, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" weitergeleitet. Sie sollten einen Verweis auf die Assembly hinzufügen.
1>  CS1069: Line 61 Der Typname "XmlAttribute" konnte nicht im Namespace "System.Xml" gefunden werden. Dieser Typ wurde an Assembly "System.Xml.ReaderWriter, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" weitergeleitet. Sie sollten einen Verweis auf die Assembly hinzufügen.
1>  CS1069: Line 67 Der Typname "XmlAttribute" konnte nicht im Namespace "System.Xml" gefunden werden. Dieser Typ wurde an Assembly "System.Xml.ReaderWriter, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" weitergeleitet. Sie sollten einen Verweis auf die Assembly hinzufügen.

What can I do to fix this?

Drizin commented 5 days ago

Try adding the missing assemblies.

https://github.com/Drizin/CodegenCS/blob/bf70ba6af23f108074ec94d038a31278d42d1dcb/src/Tools/CodegenCS.Tools.CliTool.Tests/BasicTests.cs#L153

Drizin commented 5 days ago

But VSExecutionContext is only available from inside Visual Studio. If you're running from command-line you can't inject that type.

uholeschak commented 4 days ago

Thanks with -r:System.Xml.dll -r:System.Xml.ReaderWriter.dll -r:System.Private.Xml.dll this is working. The VSExecutionContext I have replaced now by using information from the executing assembly.

uholeschak commented 4 days ago

But I think using a NuGet package as in option 2 would be the best solution. In this case you don't have to install extra tools or extensions before the building.

Drizin commented 3 days ago

I've just published a nuget package with a source generator. Check latest commit (including the updates to the README doc) and let me know how it goes.

In my experience source generators are very troublesome, so unless you're extending on top of the syntax tree I'd assume that just calling dotnet-codegencs in prebuild event is more stable.

uholeschak commented 3 days ago

Thanks, basically this is working great! The generated output file is also updated in the VS project. I am only generating a file the should be copied to the output directory. If the output file is missing before the build, have to build twice to get it copied to the output directory. Is this also generating a log file our is the log written to the VS console? At least have found nothing.

uholeschak commented 2 days ago

I have tested it now with a .NET Framework ASP.NET Project, but this is not working. .NET Framework ASP.NET still requires to old NuGet package style.

uholeschak commented 1 day ago

I expect that the ILogger interface is not usable in this case. I am creating now my own log file using StreamWriter(). How can I get the location of the source .csx file? A the moment I use Directory.GetCurrentDirectory() for storing the log file. Is this directory stable?

uholeschak commented 1 day ago

I have now a better concept for logging. I simply create a: ICodegenTextWriter logWriter = context[templateName + ".log"]; With that I could write a log file to the correct output directory.

Drizin commented 10 minutes ago

I have tested it now with a .NET Framework ASP.NET Project, but this is not working. .NET Framework ASP.NET still requires to old NuGet package style.

Interesting. I thought they should work with any framework, maybe that's not the case.

Anyway, I expect that CodegenCS.SourceGenenerator will remove some of the complexities of manually writing a source generator, but I still think that the CLI tools is still more reliable. For an example of how to put the CLI into your prebuild events, check this sample

Drizin commented 3 minutes ago

I have now a better concept for logging. I simply create a: ICodegenTextWriter logWriter = context[templateName + ".log"]; With that I could write a log file to the correct output directory.

Nice solution.

The current ILogger is actually more like a IConsoleOutput, or ITemplateProgress - it's not really about logging to file (although he VSExtension saves it to file). Probably I should refactor that at some point. Especially because there's a bunch of support for colors which in the end of the day only work in the CLI dotnet-codegencs.

Drizin commented 1 minute ago

How can I get the location of the source .csx file?

Inject ExecutionContext.

A the moment I use Directory.GetCurrentDirectory() for storing the log file. Is this directory stable?

Yes, it should always start from the same folder where the template is (except for the CLI dotnet-codegencs where it makes sense to really capture and use the current shell folder)