The code-behind file generation is invoked even if the feature files were not changed #792
Replies: 1 comment 4 replies
-
When you change branch, files are updated. Input newer than output causes targets to be executed.
MSBuild is actually kind-of fantastic in this department. When you declare inputs and map them to outputs, MSBuild will reduce the input batch to just the dirty files so your target's logic is completely unchanged, but will only run for the subset of inputs that need it. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
When you invoke
dotnet buildmultiple times, you would expect that the code-behind file generation is not invoked. Maybe it is surprising but the generation task is still invoked for all feature files currently.It is a bit hard to prove this, but if you add a line
to
Reqnroll/Reqnroll.Tools.MsBuild.Generation/CodeBehindWriter.cs
Line 21 in df77e3b
dotnet buildcommand, it shows each feature file.Note 1: Although the generator is invoked, no actual file write is happening, because the
CodeBehindWriterclass compares the file to be written out with the actual content and it only writes if they are different. This seems to be counter-intuitive, but we have measured it and it provides better performance this way, even on SSD drives.Note 2: There is a
TestUpToDateCheckerclass in the codebase that performs up-to-date checks based on some heuristics, but that functionality is NOT USED, because theGenerationSettings.CheckUpToDateis never set to true, except in tests. So that is actually a dead code, we should remove it once we find a good consensus.Note 3: When you build from Visual Studio, it uses a slightly different build mechanism and if the project was not changed the project build is not even invoked. But once it is invoked, maybe because of an unrelated change, it will invoke the generator even for the unchanged feature files. So to diagnose this issue it is easier to use
dotnet build.When I mentioned this to @Code-Grump on another thread, he made the following comment:
And a little bit of history and background:
A concrete code-behind file depends on:
reqnroll.jsonreqnroll.jsonObviously the most important input is the feature-file content. The others change very rarely, people would probably OK with invoking a re-build (or clean & build) in this case.
Initially we used a simple timestamp-based configuration, similar to what @Code-Grump mentioned, that worked for most of the causes, but caused trouble in the following (not that rare) situation.
Branch Change Situation:
mainbranch, updating a feature file with "change X" and build. The code-behind will be re-generated and it's timestamp will be newer then the feature file timestampfeature1branch. This will restore the feature file to it's previous version, but does not modify the code-behind file, because that is not in the git repo.Because of this situation, we finally decided to disable this up-to-date checking mechanism, this is why
GenerationSettings.CheckUpToDateis never set to true as mentioned above. We kept the basic write-only-if-change check, because it was still beneficial, but obviously that is not very effective, because all the calculations and parsing has to be made still before we can decide that it is up-to-date.Seeing this now, because ~everyone uses git, this disabling seems to be unnecessary and we could enable it again.
End of history.
I would like to think it over once more if we could improve the current behavior, especially with the built-in optimization mechanism from MsBuild. But to move on with that, I have a few questions:
Beta Was this translation helpful? Give feedback.
All reactions