diff options
-rw-r--r-- | docs/markdown/Fs-module.md | 20 | ||||
-rw-r--r-- | mesonbuild/modules/fs.py | 40 | ||||
-rw-r--r-- | test cases/common/227 fs module/meson.build | 14 |
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') |