# FS (filesystem) module

This module provides functions to inspect the file system. It is
available starting with version 0.53.0.

Since 0.59.0, all functions accept `files()` objects if they can do something
useful with them (this excludes `exists`, `is_dir`, `is_file`, `is_absolute`
since a `files()` object is always the absolute path to an existing file).

## Usage

The module may be imported as follows:

``` meson
fs = [[#import]]('fs')
```

## File lookup rules

Non-absolute paths are looked up relative to the directory where the
current `meson.build` file is.

If specified, a leading `~` is expanded to the user home directory.
Environment variables are not available as is the rule throughout Meson.
That is, $HOME, %USERPROFILE%, $MKLROOT, etc. have no meaning to the Meson
filesystem module. If needed, pass such variables into Meson via command
line options in `meson.options`, native-file or cross-file.

Where possible, symlinks and parent directory notation are resolved to an
absolute path.

### exists

Takes a single string argument and returns true if an entity with that
name exists on the file system. This can be a file, directory or a
special entry such as a device node.

### is_dir

Takes a single string argument and returns true if a directory with
that name exists on the file system.

### is_file

Takes a single string argument and returns true if an file with that
name exists on the file system.

### is_symlink

Takes a single string or (since 0.59.0) `files()` argument and returns true if
the path pointed to by the string is a symbolic link.

## File Parameters

### is_absolute

*since 0.54.0*

Return a boolean indicating if the path string or (since 0.59.0) `files()`
specified is absolute, WITHOUT expanding `~`.

Examples:

```meson
fs.is_absolute('~')   # false

home = fs.expanduser('~')
fs.is_absolute(home)  # true

fs.is_absolute(home / 'foo')  # true, even if ~/foo doesn't exist

fs.is_absolute('foo/bar')  # false, even if ./foo/bar exists
```

### hash

The `fs.hash(filename, hash_algorithm)` method returns a string containing
the hexadecimal `hash_algorithm` digest of a file.
`hash_algorithm` is a string; the available hash algorithms include:
md5, sha1, sha224, sha256, sha384, sha512.

### size

The `fs.size(filename)` method returns the size of the file in integer bytes.

### is_samepath

The `fs.is_samepath(path1, path2)` returns boolean `true` if both
paths resolve to the same path. For example, suppose path1 is a
symlink and path2 is a relative path. If `path1` can be resolved to
`path2`, then `true` is returned. If `path1` is not resolved to
`path2`, `false` is returned. If `path1` or `path2` do not exist,
`false` is returned.

Examples:

```meson
x = 'foo.txt'
y = 'sub/../foo.txt'
z = 'bar.txt'  # a symlink pointing to foo.txt
j = 'notafile.txt'  # nonexistent file

fs.is_samepath(x, y)  # true
fs.is_samepath(x, z)  # true
fs.is_samepath(x, j)  # false

p = 'foo/bar'
q = 'foo/bar/baz/..'
r = 'buz'  # a symlink pointing to foo/bar
s = 'notapath'  # nonexistent directory

fs.is_samepath(p, q)  # true
fs.is_samepath(p, r)  # true
fs.is_samepath(p, s)  # false
```

## Filename modification

The files need not actually exist yet for these path string
manipulation methods.

### expanduser

*since 0.54.0*

A path string with a leading `~` is expanded to the user home
directory

Examples:

```meson
fs.expanduser('~')  # user home directory

fs.expanduser('~/foo')  # <homedir>/foo
```

### as_posix

*since 0.54.0*

`fs.as_posix(path)` assumes a Windows path, even if on a Unix-like
system. Thus, all `'\'` or `'\\'` are turned to '/', even if you meant
to escape a character.

Examples

```meson
fs.as_posix('\\') == '/'  # true
fs.as_posix('\\\\') == '/'  # true

fs.as_posix('foo\\bar/baz') == 'foo/bar/baz'  # true
```

### replace_suffix

The `replace_suffix` method is a *string manipulation* convenient for
filename modifications. It allows changing the filename suffix like:

#### swap suffix

```meson
original = '/opt/foo.ini'
new = fs.replace_suffix(original, '.txt')  # /opt/foo.txt
```

#### add suffix

```meson
original = '/opt/foo'
new = fs.replace_suffix(original, '.txt')  # /opt/foo.txt
```

#### compound suffix swap

```meson
original = '/opt/foo.dll.a'
new = fs.replace_suffix(original, '.so')  # /opt/foo.dll.so
```

#### delete suffix

```meson
original = '/opt/foo.dll.a'
new = fs.replace_suffix(original, '')  # /opt/foo.dll
```

### parent

Returns the parent directory (i.e., dirname).

```meson
new = fs.parent('foo/bar')  # foo
new = fs.parent('foo/bar/baz.dll')  # foo/bar
```

### name

Returns the last component of the path (i.e., basename).

```meson
fs.name('foo/bar/baz.dll.a')  # baz.dll.a
```

### stem

*since 0.54.0*

Returns the last component of the path, dropping the last part of the
suffix.

```meson
fs.stem('foo/bar/baz.dll')  # baz
fs.stem('foo/bar/baz.dll.a')  # baz.dll
```

### suffix

*since 1.9.0*

Returns the last dot-separated portion of the final component of the path
including the dot, if any.

```meson
fs.suffix('foo/bar/baz.dll')  # .dll
fs.suffix('foo/bar/baz.dll.a')  # .a
fs.suffix('foo/bar')  # (empty)
```

### read
- `read(path, encoding: 'utf-8')` *(since 0.57.0)*:
   return a [string](Syntax.md#strings) with the contents of the given `path`.
   If the `encoding` keyword argument is not specified, the file specified by
   `path` is assumed to be utf-8 encoded. Binary files are not supported. The
   provided paths should be relative to the current `meson.current_source_dir()`
   or an absolute path outside the build directory is accepted. If the file
   specified by `path` changes, this will trigger Meson to reconfigure the
   project. If the file specified by `path` is a `files()` object it
   cannot refer to a built file.

### relative_to

*Since 1.3.0*

Return a relative filepath. In the event a relative path could not be found, the
absolute path of `to` is returned. Relative path arguments will be assumed to be
relative to `meson.current_source_dir()`.

Has the following positional arguments:
   - to `str | file | custom_tgt | custom_idx | build_tgt`: end path
   - from `str | file | custom_tgt | custom_idx | build_tgt`: start path

returns:
   - a string

### copyfile

*Since 0.64.0*

Copy a file from the source directory to the build directory at build time.

Has the following positional arguments:
   - src `File | str`: the file to copy

Has the following optional arguments:
   - dest `str`: the name of the output file. If unset will be the basename of
     the src argument (i.e., the last component of its path).

Has the following keyword arguments:
   - install `bool`: Whether to install the copied file, defaults to false
   - install_dir `str`: Where to install the file to
   - install_tag: `str`: the install tag to assign to this target
   - install_mode `array[str | int]`: the mode to install the file with
   - build_subdir `str`: *since 1.12.0*.  Places the build results in a subdirectory
     of the given name rather than directly into the build directory.
     For more information, see [[custom_target]].

returns:
   - a [[custom_target]] object

```meson
copy = fs.copyfile('input-file', 'output-file')
```
