Closed paltherr closed 1 year ago
Note that I found that I could avoid the problem by switching the order of the two merge arguments in the .tmpl
files. However, it still looks wrong that modifying .
in one .tmpl
file may affect the processing of other .tmpl
files.
This is because you are using the merge
template function. According to the documentation:
merge, mustMerge
Merge two or more dictionaries into one, giving precedence to the dest dictionary:
$newdict := merge $dest $source1 $source2
This is a deep merge operation but not a deep copy operation. Nested objects that are merged are the same instance on both dicts. If you want a deep copy along with the merge than use the deepCopy function along with merging. For example,
deepCopy $source | merge $dest
mustMerge will return an error in case of unsuccessful merge.
You need to use deepCopy
.
Sure, that avoids the problem but isn't it problematic that chezmoi generates different results for the same target depending on which files it's applied to? With my example, running chezmoi apply file1.txt file2.txt
generates a file2.txt
that contains file1
and running chezmoi apply file2.txt
generates a file2.txt
that contains file2
. Shouldn't chezmoi always generate the same result for the same target? Couldn't it achieve that by processing each file with a preventive deepCopy
of .
?
Users could still shoot themselves in the foot, for example by calling two templates with .
where the first template modifies .
and thus impacts the second template. But at least chezmoi would then be self-consistent and always generate the same result for a given target.
You're right. The template execution should be independent. Should be fixed with #3129. Thank you for spotting and reporting this :)
Describe the bug
Any modification to the . dictionary done while processing a templated file is visible in the processing of further templated files. The processing of each templated file should start with an unmodified . dictionary.
To reproduce
File
chezmoi/.chezmoitemplates/file.txt
:File
chezmoi/file1.txt.tmpl
:File
chezmoi/file2.txt.tmpl
:Note that
file2.txt
containsfile1
.Now
file2.txt
containsfile2
.And it's back to
file1
!?!Expected behavior
The file
file2.txt
should always containfile2
.Output of
chezmoi doctor