diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-09 05:00:12 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-09 05:00:12 -0400 |
| commit | 319d4306b585569d198a6e0ac268c009eb63705a (patch) | |
| tree | 1106f4721d56a2b30bfd7069813e37b4c2d42002 | |
| parent | 0b441054b3a73f243f0602e62f5484a2cded3f95 (diff) | |
Add paths docs
| -rw-r--r-- | docs/README.md | 1 | ||||
| -rw-r--r-- | docs/paths.md | 579 |
2 files changed, 580 insertions, 0 deletions
diff --git a/docs/README.md b/docs/README.md index 03c90596..b3e82772 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,6 +25,7 @@ Information about Tomo's built-in types can be found here: - [Integer Ranges](ranges.md) - [Integers](integers.md) - [Languages](langs.md) +- [Paths](paths.md) - [Sets](sets.md) - [Structs](structs.md) - [Tables](tables.md) diff --git a/docs/paths.md b/docs/paths.md new file mode 100644 index 00000000..f4cdb1f4 --- /dev/null +++ b/docs/paths.md @@ -0,0 +1,579 @@ +# Paths and Files + +Tomo supports a built-in syntax for file and directory paths, with some logic +to help prevent or mitigate the risks of errors caused by string manipulations +of file paths. Tomo does not have a built-in datatype to represent files +specifically, but instead relies on Paths as the API to do filesystem +operations. + +## Syntax + +Paths are [domain-specific languages](langs.md) that have their own dedicated +syntax. A path literal begins with either `(/`, `(./`, `(../`, or `(~/` and continues +until a matching closing parenethesis: + +```tomo +>> (/tmp) += (/tmp) +>> (~/path with/(parens) is/ok/) += (~/path with/(parens) is/ok/) +``` + +### Interpolation + +Paths can contain interpolations using `$`, just like strings. However, there are +certain values that _cannot_ be interpolated: + +- The literal string `.` +- The literal string `..` +- Any text that contains a forward slash (`/`) + +The intended use for path interpolation is to take user input which may or may +not be trustworthy and interpret that value as a single path component name, +i.e. the name of a directory or file. If a user were to supply a value like +`..` or `foo/baz`, it would risk navigating into a directory other than +intended. Paths can be created from text with slashes using +`Path.from_unsafe_text(text)` if you need to use arbitrary text as a file path. + +## Path Methods + +### `append` + +**Description:** +Appends the given text to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error. + +**Usage:** +```markdown +append(path: Path, text: Text, permissions: Int32 = 0o644_i32) -> Void +``` + +**Parameters:** + +- `path`: The path of the file to append to. +- `text`: The text to append to the file. +- `permissions` (optional): The permissions to set on the file if it is being created (default is `0o644`). + +**Returns:** +Nothing. + +**Example:** +```markdown +(./log.txt):append("extra line$(\n)") +``` + +--- + +### `base_name` + +**Description:** +Returns the base name of the file or directory at the specified path. + +**Usage:** +```markdown +base_name(path: Path) -> Text +``` + +**Parameters:** + +- `path`: The path of the file or directory. + +**Returns:** +The base name of the file or directory. + +**Example:** +```markdown +>> (./path/to/file.txt):base_name() += "file.txt" +``` + +--- + +### `children` + +**Description:** +Returns a list of children (files and directories) within the directory at the specified path. Optionally includes hidden files. + +**Usage:** +```markdown +children(path: Path, include_hidden=no) -> [Path] +``` + +**Parameters:** + +- `path`: The path of the directory. +- `include_hidden` (optional): Whether to include hidden files, which start with a `.` (default is `no`). + +**Returns:** +A list of paths for the children. + +**Example:** +```markdown +>> (./directory):children(include_hidden=yes) += [".git", "foo.txt"] +``` + +--- + +### `create_directory` + +**Description:** +Creates a new directory at the specified path with the given permissions. + +**Usage:** +```markdown +create_directory(path: Path, permissions=0o644_i32) -> Void +``` + +**Parameters:** + +- `path`: The path of the directory to create. +- `permissions` (optional): The permissions to set on the new directory (default is `0o644`). + +**Returns:** +Nothing. + +**Example:** +```markdown +(./new_directory):create_directory() +``` + +--- + +### `exists` + +**Description:** +Checks if a file or directory exists at the specified path. + +**Usage:** +```markdown +exists(path: Path) -> Bool +``` + +**Parameters:** + +- `path`: The path to check. + +**Returns:** +`True` if the file or directory exists, `False` otherwise. + +**Example:** +```markdown +>> (/):exists() += yes +``` + +--- + +### `extension` + +**Description:** +Returns the file extension of the file at the specified path. Optionally returns the full extension. + +**Usage:** +```markdown +extension(path: Path, full=yes) -> Text +``` + +**Parameters:** + +- `path`: The path of the file. +- `full` (optional): Whether to return everything after the first `.` in the + base name, or only the last part of the extension (default is `yes`). + +**Returns:** +The file extension (not including the leading `.`) or an empty text if there is +no file extension. + +**Example:** +```markdown +>> (./file.tar.gz):extension() += "tar.gz" +>> (./file.tar.gz):extension(full=no) += "gz" +>> (/foo):extension() += "" +>> (./.git):extension() += "" +``` + +--- + +### `files` + +**Description:** +Returns a list of files within the directory at the specified path. Optionally includes hidden files. + +**Usage:** +```markdown +files(path: Path, include_hidden=no) -> [Path] +``` + +**Parameters:** + +- `path`: The path of the directory. +- `include_hidden` (optional): Whether to include hidden files (default is `no`). + +**Returns:** +A list of file paths. + +**Example:** +```markdown +>> (./directory):files(include_hidden=yes) += [(./directory/file1.txt), (./directory/file2.txt)] +``` + +--- + +### `is_directory` + +**Description:** +Checks if the path represents a directory. Optionally follows symbolic links. + +**Usage:** +```markdown +is_directory(path: Path, follow_symlinks=yes) -> Bool +``` + +**Parameters:** + +- `path`: The path to check. +- `follow_symlinks` (optional): Whether to follow symbolic links (default is `yes`). + +**Returns:** +`True` if the path is a directory, `False` otherwise. + +**Example:** +```markdown +>> (./directory/):is_directory() += yes + +>> (./file.txt):is_directory() += no +``` + +--- + +### `is_file` + +**Description:** +Checks if the path represents a file. Optionally follows symbolic links. + +**Usage:** +```markdown +is_file(path: Path, follow_symlinks=yes) -> Bool +``` + +**Parameters:** + +- `path`: The path to check. +- `follow_symlinks` (optional): Whether to follow symbolic links (default is `yes`). + +**Returns:** +`True` if the path is a file, `False` otherwise. + +**Example:** +```markdown +>> (./file.txt):is_file() += yes + +>> (./directory/):is_file() += no +``` + +--- + +### `is_socket` + +**Description:** +Checks if the path represents a socket. Optionally follows symbolic links. + +**Usage:** +```markdown +is_socket(path: Path, follow_symlinks=yes) -> Bool +``` + +**Parameters:** + +- `path`: The path to check. +- `follow_symlinks` (optional): Whether to follow symbolic links (default is `yes`). + +**Returns:** +`True` if the path is a socket, `False` otherwise. + +**Example:** +```markdown +>> (./socket):is_socket() += yes +``` + +--- + +### `is_symlink` + +**Description:** +Checks if the path represents a symbolic link. + +**Usage:** +```markdown +is_symlink(path: Path) -> Bool +``` + +**Parameters:** + +- `path`: The path to check. + +**Returns:** +`True` if the path is a symbolic link, `False` otherwise. + +**Example:** +```markdown +>> (./link):is_symlink() += yes +``` + +--- + +### `parent` + +**Description:** +Returns the parent directory of the file or directory at the specified path. + +**Usage:** +```markdown +parent(path: Path) -> Path +``` + +**Parameters:** + +- `path`: The path of the file or directory. + +**Returns:** +The path of the parent directory. + +**Example:** +```markdown +>> (./path/to/file.txt):parent() += (./path/to/) +``` + +--- + +### `read` + +**Description:** +Reads the contents of the file at the specified path. + +**Usage:** +```markdown +read(path: Path) -> Text +``` + +**Parameters:** + +- `path`: The path of the file to read. + +**Returns:** +The contents of the file. If the file does not exist, an error will be raised. + +**Example:** +```markdown +content := (./file.txt):read() +``` + +--- + +### `relative` + +**Description:** +Returns the path relative to a given base path. By default, the base path is the current directory. + +**Usage:** +```markdown +relative(path: Path, relative_to=(./)) -> Path +``` + +**Parameters:** + +- `path`: The path to convert. +- `relative_to` (optional): The base path for the relative path (default is `./`). + +**Returns:** +The relative path. + +**Example:** +```markdown +>> (./path/to/file.txt):relative(relative_to=(./path)) += (./to/file.txt) +``` + +--- + +### `remove` + +**Description:** +Removes the file or directory at the specified path. A runtime error is raised if something goes wrong. + +**Usage:** +```markdown +remove(path: Path, ignore_missing=no) -> Void +``` + +**Parameters:** + +- `path`: The path to remove. +- `ignore_missing` (optional): Whether to ignore errors if the file or directory does not exist (default is `no`). + +**Returns:** +Nothing. + +**Example:** +```markdown +(./file.txt):remove() +``` + +--- + +### `resolved` + +**Description:** +Resolves the absolute path of the given path relative to a base path. By default, the base path is the current directory. + +**Usage:** +```markdown +resolved(path: Path, relative_to=(./)) -> Path +``` + +**Parameters:** + +- `path`: The path to resolve. +- `relative_to` (optional): The base path for resolution (default is `./`). + +**Returns:** +The resolved absolute path. + +**Example:** +```markdown +>> (~/foo):resolved() += (/home/user/foo) + +>> (./path/to/file.txt):resolved(relative_to=(/foo)) += (/foo/path/to/file.txt) +``` + +--- + +### `subdirectories` + +**Description:** +Returns a list of subdirectories within the directory at the specified path. Optionally includes hidden subdirectories. + +**Usage:** +```markdown +subdirectories(path: Path, include_hidden=no) -> [Path] +``` + +**Parameters:** + +- `path`: The path of the directory. +- `include_hidden` (optional): Whether to include hidden subdirectories (default is `no`). + +**Returns:** +A list of subdirectory paths. + +**Example:** +```markdown +>> (./directory):subdirectories() += [(./directory/subdir1), (./directory/subdir2)] + +>> (./directory):subdirectories(include_hidden=yes) += [(./directory/.git), (./directory/subdir1), (./directory/subdir2)] +``` + +--- + +### `unique_directory` + +**Description:** +Generates a unique directory path based on the given path. Useful for creating temporary directories. + +**Usage:** +```markdown +unique_directory(path: Path) -> Path +``` + +**Parameters:** + +- `path`: The base path for generating the unique directory. The last six letters of this path must be `XXXXXX`. + +**Returns:** +A unique directory path after creating the directory. + +**Example:** + +``` +>> created := (/tmp/my-dir.XXXXXX):unique_directory() += (/tmp/my-dir-AwoxbM/) +>> created:is_directory() += yes +created:remove() +``` + +--- + +### `write` + +**Description:** +Writes the given text to the file at the specified path, creating the file if +it doesn't already exist. Sets the file permissions as specified. If the file +writing cannot be successfully completed, a runtime error is raised. + +**Usage:** +```markdown +write(path: Path, text: Text, permissions=0o644_i32) -> Void +``` + +**Parameters:** + +- `path`: The path of the file to write to. +- `text`: The text to write to the file. +- `permissions` (optional): The permissions to set on the file if it is created (default is `0o644`). + +**Returns:** +Nothing. + +**Example:** +```markdown +(./file.txt):write("Hello, world!") +``` + +--- + +### `write_unique` + +**Description:** +Writes the given text to a unique file path based on the specified path. The +file is created if it doesn't exist. This is useful for creating temporary +files. + +**Usage:** +```markdown +write_unique(path: Path, text: Text) -> Path +``` + +**Parameters:** + +- `path`: The base path for generating the unique file. This path must include + the string `XXXXXX` in the file base name. +- `text`: The text to write to the file. + +**Returns:** +The path of the newly created unique file. + +**Example:** +```markdown +>> created := (./file-XXXXXX.txt):write_unique("Hello, world!") += (./file-27QHtq.txt) +>> created:read() += "Hello, world!" +created:remove() +``` |
