Skip to content

nautil-utils

neylz's avatar

nautil-utils

by Neylz

Terminal window
pip install nautil-utils
# import actions using (even if your IDE says it is unused):
import nautil_utils.actions
  • source_path: str Templated
    The path to the file or directory to archive, relative to the artifact.
  • output_path: str Templated
    The path to the archive file to create, relative to the artifact.
  • archive_format: str = "zip" Templated
    Archive format to create. Supported: zip, tar, gztar, bztar, xztar.
  • overwrite: bool = True
    Whether to overwrite an existing archive at output_path.

Creates a zip or tar archive from a file or directory inside the artifact workspace.

a = Artifact(env).use(...)
.archive("dist", "dist.zip", archive_format="zip")

  • source_path: str Templated
    The file or directory to copy, relative to the artifact.
  • dest_path: str Templated
    The destination path (file or directory), relative to the artifact.
  • overwrite: bool = True
    Whether to overwrite the destination if it already exists.

Copies a file or directory within the artifact workspace.

a = Artifact(env).use(...)
.cp("assets/logo.png", "static/logo.png")

  • archive_path: str Templated
    The archive file to extract, relative to the artifact.
  • dest_path: str = "." Templated
    The destination directory to extract into, relative to the artifact.
  • overwrite: bool = True
    Whether to overwrite existing files in the destination directory.

Extracts a zip or tar archive into a directory within the artifact workspace.

a = Artifact(env).use(...)
.extract("assets.zip", "assets/")

  • filter_func: FilePredicate
    Predicate called with (file_name, file_path, workspace); return True to delete.
  • root: str = "." Templated
    Root directory to scan inside the workspace.

Deletes files and directories that match the given predicate.

import re
from nautil_utils.filter import make_regex_predicate
a = Artifact(env).use(...)
.filter(make_regex_predicate(re.compile(r".*\\.bak$")), root="build/")

  • filter_func: FilePredicate
    Predicate called with (file_name, file_path, workspace); return True to process.
  • item_action: Callable[..., Any]
    Action callable invoked per match; supports multiple signatures.
  • root: str = "."
    Root directory to scan inside the workspace.
  • files: bool = True
    Whether to include files.
  • dirs: bool = False
    Whether to include directories.
  • recursive: bool = True
    Whether to traverse subdirectories.

Runs an action for each file or directory that matches a predicate.

import os
import re
from nautil_utils.filter import make_regex_predicate
def delete_file(relative_path: str, workspace: str):
os.remove(os.path.join(workspace, relative_path))
a = Artifact(env).use(...)
.foreach(make_regex_predicate(re.compile(r".*\\.tmp$")), delete_file, root="build/")

  • remove_spaces: bool = True
    When true, writes compact JSON using "," and ":" separators.

Minifies all .json files in the artifact workspace.

a = Artifact(env).use(...)
.json_minify(remove_spaces=True)

  • file: PathLike Templated
    The JSON file to modify, relative to the artifact.
  • key: str Templated
    Dot path (supports indices) to set, e.g. parent.child[0].key.
  • value: object Templated*
    Value to set. Templated if a str is passed.
  • cast: type = None
    Optional type to cast the value to before setting.

Sets a value in a JSON file using a dot-path key with optional array indices.

a = Artifact(env).use(...)
.json_set("config.json", "build.targets[0]", "release")

  • relative_paths: list[str] Templated
    Paths to preserve. Subdirectories under these paths are preserved too.
  • root: str = "." Templated
    Root directory to scan inside the workspace.
  • files: bool = True
    Whether to consider files.
  • dirs: bool = True
    Whether to consider directories.

Deletes everything under root except the specified paths.

a = Artifact(env).use(...)
.keep(["dist/", "README.md"], root=".")

  • dir_path: str Templated
    Directory path to create, relative to the artifact.
  • parents: bool = True
    Create parent directories if they do not exist.
  • exist_ok: bool = True
    Ignore if the directory already exists.

Creates a directory inside the artifact workspace.

a = Artifact(env).use(...)
.mkdir("build/output", parents=True)

  • source_path: str Templated
    The file or directory to move, relative to the artifact.
  • dest_path: str Templated
    The destination path, relative to the artifact.

Moves a file or directory within the artifact workspace.

a = Artifact(env).use(...)
.move("staging/app.jar", "release/app.jar")

  • script_path: str Templated
    Python script to execute, relative to the artifact.
  • execution_location: str | None = None Templated
    Working directory for the script, relative to the artifact.

Executes a Python script from the artifact workspace.

a = Artifact(env).use(...)
.py("scripts/build.py", execution_location="scripts")

  • relative_paths: list[str] = [] Templated
    Paths to scan. When empty, the entire workspace is scanned.
  • files: bool = True
    Whether to remove empty files.
  • dirs: bool = True
    Whether to remove empty directories.

Removes empty files and/or directories in the artifact workspace.

a = Artifact(env).use(...)
.remove_empty(["build/", "dist/"])

  • target_path: str Templated
    File or directory to remove, relative to the artifact.
  • recursive: bool = True
    Whether to remove directories recursively.
  • missing_ok: bool = True
    Whether to ignore missing paths.

Removes a file or directory from the artifact workspace.

a = Artifact(env).use(...)
.rm("build/tmp", recursive=True)

  • file_path: str Templated
    File to create or update, relative to the artifact.
  • create_parents: bool = True
    Whether to create parent directories if needed.

Creates an empty file or updates its modification time.

a = Artifact(env).use(...)
.touch("build/.keep")

  • artifact: Artifact
    An existing artifact to use as a source.
  • root: PathLike = "."
    Root path inside the artifact to copy from.
  • compressed_format: str | None = None
    Optional archive format. Supported: zip, tar, gztar.

Copies files from another artifact. When compressed_format is set, the source is archived before copying.

from nautil_utils.source import ArtifactSource
base = Artifact(env).use(...)
pack = Artifact(env)
pack.use(ArtifactSource(base, root="dist"), dest=".")

  • git_url: str
    Git repository URL to clone.
  • branch: str = "main"
    Branch to clone.
  • specific_commit: str | None = None
    Optional commit hash to checkout after cloning.
  • depth: int = 1
    Clone depth for shallow clones.

Clones a Git repository and exposes files as a source.

from nautil_utils.source import GitSource
a = Artifact(env).use(
GitSource("https://github.com/neylz/nautil-utils"),
dest="vendor/nautil-utils",
src_path="nautil_utils"
)

  • path: PathLike
    Local directory or file system root path to use as the source.

Copies files from a local path into the artifact.

from nautil_utils.source import LocalSource
# Copying a directory
a = Artifact(env).use(
LocalSource("C:/assets"),
dest="assets",
src_path="icons"
)
# Copying a single file
a = Artifact(env).use(
LocalSource("C:/assets"),
dest="static/logo.png",
src_path="icons/logo_512x512.png"
)

Filters are using predicates. Below are some utilities to build common predicates. You can of course write your own predicate function.

To write a custom predicate, you must input a nautil_utils.types.FilePredicate, which is a callable with the signature (file_name: str, file_path: str, workspace: str) -> bool (Callable[[str, str, str], bool]). The predicate should return True for paths that should be matched (e.g. deleted by the filter action).

  • ignore_file_name: str
    The name (or path) of the .ignore file to read, for example .gitignore.
  • workspace_relative: bool = True
    When true, resolves ignore_file_name relative to the workspace root.

Builds a predicate that follows .ignore-style rules. The returned predicate matches paths that should be ignored.

from nautil_utils.filter import make_dotignore_predicate
ignore_predicate = make_dotignore_predicate(".packignore")
a = Artifact(env).use(...)
.filter(ignore_predicate)

  • pattern: re.Pattern
    Compiled regex used to test relative paths.

Builds a predicate that matches paths using a regular expression.

import re
from nautil_utils.filter import make_regex_predicate
a = Artifact(env).use(...)
.filter(make_regex_predicate(re.compile(r".*\.bak$")))