DalaDev.Utils (dala_dev v0.4.0)

Copy Markdown View Source

Shared utility functions used across the dala_dev codebase.

This module centralizes common operations to reduce duplication and ensure consistent behavior across modules.

Summary

Functions

Checks if ADB is available in the system PATH.

Checks if a command is available in the system PATH.

Compiles a regex pattern with the given options.

Ensures a directory exists, creating it if necessary.

Formats a byte size into a human-readable string.

Normalizes CLI arguments so underscored long flags keep working.

Parses ADB devices output into a list of device identifiers.

Runs an ADB command for a specific device with timeout.

Safely runs ADB with timeout protection.

Functions

adb_available?()

@spec adb_available?() :: boolean()

Checks if ADB is available in the system PATH.

command_available?(cmd)

@spec command_available?(String.t()) :: boolean()

Checks if a command is available in the system PATH.

compile_regex(pattern, opts \\ "")

@spec compile_regex(String.t(), String.t()) :: Regex.t()

Compiles a regex pattern with the given options.

Centralizes regex compilation to avoid duplicating Regex.compile!/2 calls and provides a single place to handle compilation errors.

Examples

iex> DalaDev.Utils.compile_regex("hello\s+world")
~r/hello\s+world/

ensure_dir(path)

@spec ensure_dir(String.t()) :: :ok | {:error, term()}

Ensures a directory exists, creating it if necessary.

Returns :ok on success, {:error, reason} on failure.

format_bytes(bytes)

@spec format_bytes(non_neg_integer()) :: String.t()

Formats a byte size into a human-readable string.

normalize_cli_args(args)

@spec normalize_cli_args([String.t()]) :: [String.t()]

Normalizes CLI arguments so underscored long flags keep working.

OptionParser only recognizes hyphenated long options (--dry-run); passing the documented --dry_run spelling is silently dropped on current Elixir releases. Rewrites every argv token that looks like a flag (starts with --, including --flag=value form) so both spellings parse identically. Non-flag values are passed through.

Examples

iex> DalaDev.Utils.normalize_cli_args(["a.txt", "--on_conflict", "skip"])
["a.txt", "--on-conflict", "skip"]

iex> DalaDev.Utils.normalize_cli_args(["--dry_run=true"])
["--dry-run=true"]

parse_adb_devices_output(output)

@spec parse_adb_devices_output(String.t()) :: [String.t()]

Parses ADB devices output into a list of device identifiers.

Expects output from adb devices command.

run_adb_for_device(serial, args, opts \\ [])

@spec run_adb_for_device(String.t(), [String.t()], keyword()) ::
  {:ok, String.t()} | {:error, term()}

Runs an ADB command for a specific device with timeout.

Convenience wrapper that prepends -s <serial> to the arguments.

run_adb_with_timeout(args, opts \\ [])

@spec run_adb_with_timeout(
  [String.t()],
  keyword()
) :: {:ok, String.t()} | {:error, term()}

Safely runs ADB with timeout protection.

Runs adb directly (no shell involved), and kills the process if it exceeds the timeout. Works identically on macOS, Linux, and Windows — no external timeout binary required.

Returns {:ok, output} on success, {:error, reason} on failure where reason is trimmed output text or :timeout.

Options

  • :timeout - timeout in milliseconds (default: 8000)
  • :stderr_to_stdout - whether to merge stderr (default: true)
  • :exec - optional 2-arity fun (args, opts) :: {output, exit_code} overriding execution (test seam)