fs: get file size

fs: add samefile
pull/6150/head
Michael Hirsch, Ph.D 5 years ago
parent 67651271f6
commit a320274179
No known key found for this signature in database
GPG Key ID: 6D23CDADAB0294F9
  1. 20
      docs/markdown/Fs-module.md
  2. 40
      mesonbuild/modules/fs.py
  3. 14
      test cases/common/227 fs module/meson.build

@ -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

@ -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:
@ -73,6 +80,35 @@ class FSModule(ExtensionModule):
h.update(file.read_bytes())
return ModuleReturnValue(h.hexdigest(), [])
@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:

@ -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')

Loading…
Cancel
Save