aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hirsch, Ph.D <scivision@users.noreply.github.com>2019-11-10 23:38:16 -0500
committerMichael Hirsch, Ph.D <scivision@users.noreply.github.com>2019-11-17 00:17:04 -0500
commita320274179ef36aa5aeb4827f777027c3ab3d785 (patch)
tree00c5df8dc958f0e983b33f39f95477e588a71a9a
parent67651271f60347b2d3cadd235a4abac0b3a1bc16 (diff)
downloadmeson-a320274179ef36aa5aeb4827f777027c3ab3d785.zip
meson-a320274179ef36aa5aeb4827f777027c3ab3d785.tar.gz
meson-a320274179ef36aa5aeb4827f777027c3ab3d785.tar.bz2
fs: get file size
fs: add samefile
-rw-r--r--docs/markdown/Fs-module.md20
-rw-r--r--mesonbuild/modules/fs.py40
-rw-r--r--test cases/common/227 fs module/meson.build14
3 files changed, 71 insertions, 3 deletions
diff --git a/docs/markdown/Fs-module.md b/docs/markdown/Fs-module.md
index 499b8d2..8ce5e32 100644
--- a/docs/markdown/Fs-module.md
+++ b/docs/markdown/Fs-module.md
@@ -36,9 +36,27 @@ by the string is a symbolic link.
### hash
-The `hash` method computes the requested hash sum of a file.
+The `fs.hash(filename)` method computes the requested hash sum of a file.
The available hash methods include: md5, sha1, sha224, sha256, sha384, sha512.
+### samefile
+
+The `fs.samefile(filename1, filename2)` method allows determining if two filenames refer to the same file.
+Perhaps a meson.build file in one place refer to a symlink and in another place a
+relative path and/or absolute path. The `samefile` method allows determining if these
+are the same file.
+
+Examples:
+
+```meson
+x = 'foo.txt'
+y = 'sub/../foo.txt'
+z = 'bar.txt' # a symlink pointing to foo.txt
+
+fs.samefile(x, y) # true
+fs.samefile(x, z) # true
+```
+
## Filename modification
diff --git a/mesonbuild/modules/fs.py b/mesonbuild/modules/fs.py
index 5649625..571fe8a 100644
--- a/mesonbuild/modules/fs.py
+++ b/mesonbuild/modules/fs.py
@@ -31,10 +31,17 @@ class FSModule(ExtensionModule):
super().__init__(interpreter)
self.snippets.add('generate_dub_file')
+ def _resolve_dir(self, state: 'ModuleState', arg: str) -> Path:
+ """
+ resolves (makes absolute) a directory relative to calling meson.build,
+ if not already absolute
+ """
+ return Path(state.source_root) / state.subdir / Path(arg).expanduser()
+
def _check(self, check: str, state: 'ModuleState', args: typing.Sequence[str]) -> ModuleReturnValue:
if len(args) != 1:
MesonException('fs.{} takes exactly one argument.'.format(check))
- test_file = Path(state.source_root) / state.subdir / Path(args[0]).expanduser()
+ test_file = self._resolve_dir(state, args[0])
return ModuleReturnValue(getattr(test_file, check)(), [])
@stringArgs
@@ -62,7 +69,7 @@ class FSModule(ExtensionModule):
def hash(self, state: 'ModuleState', args: typing.Sequence[str], kwargs: dict) -> ModuleReturnValue:
if len(args) != 2:
MesonException('method takes exactly two arguments.')
- file = Path(state.source_root) / state.subdir / Path(args[0]).expanduser()
+ file = self._resolve_dir(state, args[0])
if not file.is_file():
raise MesonException('{} is not a file and therefore cannot be hashed'.format(file))
try:
@@ -75,6 +82,35 @@ class FSModule(ExtensionModule):
@stringArgs
@noKwargs
+ def size(self, state: 'ModuleState', args: typing.Sequence[str], kwargs: dict) -> ModuleReturnValue:
+ if len(args) != 1:
+ MesonException('method takes exactly one argument.')
+ file = self._resolve_dir(state, args[0])
+ if not file.is_file():
+ raise MesonException('{} is not a file and therefore cannot be sized'.format(file))
+ try:
+ return ModuleReturnValue(file.stat().st_size, [])
+ except ValueError:
+ raise MesonException('{} size could not be determined'.format(args[0]))
+
+ @stringArgs
+ @noKwargs
+ def samefile(self, state: 'ModuleState', args: typing.Sequence[str], kwargs: dict) -> ModuleReturnValue:
+ if len(args) != 2:
+ MesonException('method takes exactly two arguments.')
+ file1 = self._resolve_dir(state, args[0])
+ file2 = self._resolve_dir(state, args[1])
+ if not file1.exists():
+ raise MesonException('{} is not a file, symlink or directory and therefore cannot be compared'.format(file1))
+ if not file2.exists():
+ raise MesonException('{} is not a file, symlink or directory and therefore cannot be compared'.format(file2))
+ try:
+ return ModuleReturnValue(file1.samefile(file2), [])
+ except OSError:
+ raise MesonException('{} could not be compared to {}'.format(file1, file2))
+
+ @stringArgs
+ @noKwargs
def with_suffix(self, state: 'ModuleState', args: typing.Sequence[str], kwargs: dict) -> ModuleReturnValue:
if len(args) != 2:
MesonException('method takes exactly two arguments.')
diff --git a/test cases/common/227 fs module/meson.build b/test cases/common/227 fs module/meson.build
index a98ed56..2143699 100644
--- a/test cases/common/227 fs module/meson.build
+++ b/test cases/common/227 fs module/meson.build
@@ -54,5 +54,19 @@ sha256 = fs.hash('subdir/subdirfile.txt', 'sha256')
assert(md5 == 'd0795db41614d25affdd548314b30b3b', 'md5sum did not match')
assert(sha256 == 'be2170b0dae535b73f6775694fffa3fd726a43b5fabea11b7342f0605917a42a', 'sha256sum did not match')
+# -- size
+
+size = fs.size('subdir/subdirfile.txt')
+assert(size == 19, 'file size not found correctly')
+
+# -- are filenames referring to the same file?
+f1 = 'meson.build'
+f2 = 'subdir/../meson.build'
+assert(fs.samefile(f1, f2), 'samefile not realized')
+assert(not fs.samefile(f1, 'subdir/subdirfile.txt'), 'samefile known bad comparison')
+
+if not is_windows and build_machine.system() != 'cygwin'
+ assert(fs.samefile('a_symlink', 'meson.build'), 'symlink samefile fail')
+endif
subdir('subdir')