0

make build/util/version.py restat friendly

build/util/version.py's WriteIfChanged didn't work as expected,
and always update the output file, even if contents is the same.
So, restat=1 doesn't work and always output file is considered
as dirty.

This is because st_mode includes file type bits, but mode
only includes permission bits.

Use stat.S_IMODE to compare permission bits with mode.

Bug: b/314726036
Change-Id: I7cf42944533179c39d4472918d954e7780d77429
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5133019
Reviewed-by: Takuto Ikuta <tikuta@chromium.org>
Auto-Submit: Fumitoshi Ukai <ukai@google.com>
Commit-Queue: Fumitoshi Ukai <ukai@google.com>
Cr-Commit-Position: refs/heads/main@{#1239085}
This commit is contained in:
Fumitoshi Ukai
2023-12-19 12:53:32 +00:00
committed by Chromium LUCI CQ
parent 8a8ba3e1c0
commit 90083ae0ac
2 changed files with 49 additions and 1 deletions

@ -10,6 +10,7 @@ version.py -- Chromium version string substitution utility.
import argparse
import os
import stat
import sys
import android_chrome_version
@ -112,7 +113,8 @@ def WriteIfChanged(file_name, contents, mode):
except EnvironmentError:
pass
else:
if contents == old_contents and mode == os.lstat(file_name).st_mode:
if contents == old_contents and mode == stat.S_IMODE(
os.lstat(file_name).st_mode):
return
os.unlink(file_name)
with open(file_name, 'w') as f:

@ -4,6 +4,7 @@
import os
import tempfile
import time
import unittest
import mock
@ -177,6 +178,51 @@ class _VersionTest(unittest.TestCase):
os.chmod(in_file, 0o755) # On Windows, this sets in_file to 0o666.
self.assertEqual(os.lstat(in_file).st_mode, os.lstat(out_file).st_mode)
def testWriteIfChangedUpdateWhenContentChanged(self):
"""Assert it updates mtime of file when content is changed."""
with tempfile.TemporaryDirectory() as tmpdir:
file_name = os.path.join(tmpdir, "version.h")
old_contents = "old contents"
with open(file_name, "w") as f:
f.write(old_contents)
os.chmod(file_name, 0o644)
mtime = os.lstat(file_name).st_mtime
time.sleep(0.1)
contents = "new contents"
version.WriteIfChanged(file_name, contents, 0o644)
with open(file_name) as f:
self.assertEqual(contents, f.read())
self.assertNotEqual(mtime, os.lstat(file_name).st_mtime)
def testWriteIfChangedUpdateWhenModeChanged(self):
"""Assert it updates mtime of file when mode is changed."""
with tempfile.TemporaryDirectory() as tmpdir:
file_name = os.path.join(tmpdir, "version.h")
contents = "old contents"
with open(file_name, "w") as f:
f.write(contents)
os.chmod(file_name, 0o644)
mtime = os.lstat(file_name).st_mtime
time.sleep(0.1)
version.WriteIfChanged(file_name, contents, 0o755)
with open(file_name) as f:
self.assertEqual(contents, f.read())
self.assertNotEqual(mtime, os.lstat(file_name).st_mtime)
def testWriteIfChangedNoUpdate(self):
"""Assert it does not update mtime of file when nothing is changed."""
with tempfile.TemporaryDirectory() as tmpdir:
file_name = os.path.join(tmpdir, "version.h")
contents = "old contents"
with open(file_name, "w") as f:
f.write(contents)
os.chmod(file_name, 0o644)
mtime = os.lstat(file_name).st_mtime
time.sleep(0.1)
version.WriteIfChanged(file_name, contents, 0o644)
with open(file_name) as f:
self.assertEqual(contents, f.read())
self.assertEqual(mtime, os.lstat(file_name).st_mtime)
if __name__ == '__main__':
unittest.main()