add Filesystem::writeFileIfChanged
Summary:
porting this from FB to libphutil. We've been using this
internally for a couple of months. The intention is to ensure that
build steps atomically write the entire contents from the perspective
of readers.
For example, we had cases where reasonably large PHP source files were
being generated concurrently with another process attempting to read
the file. Since the file was in the middle of being re-written, the
reader hit a parse error.
While this doesn't guarantee consistency from an overall code-base
perspective, it does mean that the contents of the file are internally
consistent.
Since we use this method in build steps, we only replace the file if
its contents are different. This avoids touching the file and causing
a false rebuild of the dependents. In this scenario, we assume that
some other mechanism exists to ensure that there is only one writer
(such as locking in the build scripts), and that it is "OK" for there
to be concurrent readers.
Test Plan:
It's a port from our Filesystem library. I tried it out
from our build workflow. We already found and fixed the umask bug ;-)
Reviewers: nh, epriestley
Reviewed By: epriestley
CC: aran, Korvin
Differential Revision: https://secure.phabricator.com/D5523