If a depends on b depends on c, and c is dirty but b uses redo-stamp checksums, then 'redo-ifchange a' is indeterminate: we won't know if we need to run a.do unless we first build b, but the script that *normally* runs 'redo-ifchange b' is a.do, and we don't want to run that yet, because we don't know for sure if b is dirty, and we shouldn't build a unless one of its dependencies is dirty. Eek! Luckily, there's a safe solution. If we *know* a is dirty - eg. because a.do or one of its children has definitely changed - then we can just run a.do immediately and there's no problem, even if b is indeterminate, because we were going to run a.do anyhow. If a's dependencies are *not* definitely dirty, and all we have is indeterminate ones like b, then that means a's build process *hasn't changed*, which means its tree of dependencies still includes b, which means we can deduce that if we *did* run a.do, it would end up running b.do. Since we know that anyhow, we can safely just run b.do, which will either b.set_checked() or b.set_changed(). Once that's done, we can re-parse a's dependencies and this time conclusively tell if it needs to be redone or not. Even if it does, b is already up-to-date, so the 'redo-ifchange b' line in a.do will be fast. ...now take all the above and do it recursively to handle nested dependencies, etc, and you're done.
40 lines
1,006 B
Text
40 lines
1,006 B
Text
rm -f stampy usestamp stampy.log usestamp.log
|
|
echo one >inp
|
|
|
|
../flush-cache.sh
|
|
redo stampy
|
|
[ "$(wc -l <stampy.log)" -eq 1 ] || exit 11
|
|
|
|
redo-ifchange usestamp
|
|
[ "$(wc -l <stampy.log)" -eq 1 ] || exit 21
|
|
[ "$(wc -l <usestamp.log)" -eq 1 ] || exit 12
|
|
|
|
../flush-cache.sh
|
|
redo stampy
|
|
[ "$(wc -l <stampy.log)" -eq 2 ] || exit 31
|
|
[ "$(wc -l <usestamp.log)" -eq 1 ] || exit 32
|
|
|
|
redo-ifchange usestamp
|
|
[ "$(wc -l <stampy.log)" -eq 2 ] || exit 41
|
|
[ "$(wc -l <usestamp.log)" -eq 1 ] || exit 42
|
|
|
|
../flush-cache.sh
|
|
redo bob
|
|
redo-ifchange usestamp
|
|
[ "$(wc -l <stampy.log)" -eq 3 ] || exit 43
|
|
[ "$(wc -l <usestamp.log)" -eq 1 ] || exit 44
|
|
|
|
../flush-cache.sh
|
|
redo-ifchange usestamp
|
|
[ "$(wc -l <stampy.log)" -eq 3 ] || exit 45
|
|
[ "$(wc -l <usestamp.log)" -eq 1 ] || exit 46
|
|
|
|
../flush-cache.sh
|
|
echo two >inp
|
|
redo stampy
|
|
[ "$(wc -l <stampy.log)" -eq 4 ] || exit 51
|
|
[ "$(wc -l <usestamp.log)" -eq 1 ] || exit 52
|
|
|
|
redo-ifchange usestamp
|
|
[ "$(wc -l <stampy.log)" -eq 4 ] || exit 61
|
|
[ "$(wc -l <usestamp.log)" -eq 2 ] || exit 62
|