aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/wrap
diff options
context:
space:
mode:
authorDaniel Carson <danielcarson271@gmail.com>2022-06-27 16:04:48 -0400
committerEli Schwartz <eschwartz93@gmail.com>2022-09-18 22:48:50 -0400
commit004575874ffdb77ee997f9c19e0a041d144994d6 (patch)
tree939353cff137c4718bbf19d7756f0c040c9bc5a9 /mesonbuild/wrap
parent97f248db24fe88495dbe35bbae6eafd643c0c94b (diff)
downloadmeson-004575874ffdb77ee997f9c19e0a041d144994d6.zip
meson-004575874ffdb77ee997f9c19e0a041d144994d6.tar.gz
meson-004575874ffdb77ee997f9c19e0a041d144994d6.tar.bz2
Warn if wrap file changes
Save off the hash of the wrap file when first configuring a subproject. When reconfiguring a subproject, check the hash of the wrap file against the stored hash. If they don't match then warn the user.
Diffstat (limited to 'mesonbuild/wrap')
-rw-r--r--mesonbuild/wrap/wrap.py38
1 files changed, 37 insertions, 1 deletions
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index 34249d5..25e96e6 100644
--- a/mesonbuild/wrap/wrap.py
+++ b/mesonbuild/wrap/wrap.py
@@ -132,7 +132,9 @@ class PackageDefinition:
self.redirected = False
if self.has_wrap:
self.parse_wrap()
- self.directory = self.values.get('directory', self.name)
+ self.directory = self.values.get('directory', self.name)
+ with open(fname, 'r', encoding='utf-8') as file:
+ self.wrapfile_hash = hashlib.sha256(file.read().encode('utf-8')).hexdigest()
if os.path.dirname(self.directory):
raise WrapException('Directory key must be a name and not a path')
if self.type and self.type not in ALL_TYPES:
@@ -221,6 +223,14 @@ class PackageDefinition:
except KeyError:
raise WrapException(f'Missing key {key!r} in {self.basename}')
+ def get_hashfile(self, subproject_directory: str) -> str:
+ return os.path.join(subproject_directory, '.meson-subproject-wrap-hash.txt')
+
+ def update_hash_cache(self, subproject_directory: str) -> None:
+ if self.has_wrap:
+ with open(self.get_hashfile(subproject_directory), 'w', encoding='utf-8') as file:
+ file.write(self.wrapfile_hash + '\n')
+
def get_directory(subdir_root: str, packagename: str) -> str:
fname = os.path.join(subdir_root, packagename + '.wrap')
if os.path.isfile(fname):
@@ -367,6 +377,7 @@ class Resolver:
# The directory is there and has meson.build? Great, use it.
if method == 'meson' and os.path.exists(meson_file):
+ self.validate()
return rel_path
if method == 'cmake' and os.path.exists(cmake_file):
return rel_path
@@ -403,6 +414,11 @@ class Resolver:
if method == 'cmake' and not os.path.exists(cmake_file):
raise WrapException('Subproject exists but has no CMakeLists.txt file')
+ # At this point, the subproject has been successfully resolved for the
+ # first time so save off the hash of the entire wrap file for future
+ # reference.
+ self.wrap.update_hash_cache(self.dirname)
+
return rel_path
def check_can_download(self) -> None:
@@ -504,6 +520,26 @@ class Resolver:
if push_url:
verbose_git(['remote', 'set-url', '--push', 'origin', push_url], self.dirname, check=True)
+ def validate(self) -> None:
+ # This check is only for subprojects with wraps.
+ if not self.wrap.has_wrap:
+ return
+
+ # Retrieve original hash, if it exists.
+ hashfile = self.wrap.get_hashfile(self.dirname)
+ if os.path.isfile(hashfile):
+ with open(hashfile, 'r', encoding='utf-8') as file:
+ expected_hash = file.read().strip()
+ else:
+ # If stored hash doesn't exist then don't warn.
+ return
+
+ actual_hash = self.wrap.wrapfile_hash
+
+ # Compare hashes and warn the user if they don't match.
+ if expected_hash != actual_hash:
+ mlog.warning(f'Subproject {self.wrap.name}\'s revision may be out of date; its wrap file has changed since it was first configured')
+
def is_git_full_commit_id(self, revno: str) -> bool:
result = False
if len(revno) in (40, 64): # 40 for sha1, 64 for upcoming sha256