Shared helper functions for AshScylla Mix tasks.
Provides resource/repo discovery, CLI option handling, and file scanning
used by ash_scylla.gen, ash_scylla.migrate, ash_scylla.new_template,
ash_scylla.setup, and ash_scylla.gen.repo.
Discovery
Resources are discovered by:
- Reading
:ash_domainsapp env config - Calling
Ash.Domain.Info.resources/1on each domain - Filtering to modules using
AshScylla.DataLayer - Falling back to scanning
lib/**/*.exfiles
Umbrella Support
project_apps/0 returns the current app plus all umbrella children,
enabling resource discovery in umbrella projects.
Summary
Functions
Adds child application paths to the code path.
Returns the application name from Mix config.
Checks if a module is a valid Ash domain.
Checks if a resource module uses AshScylla.DataLayer.
Converts a file path to a module name.
Finds all AshScylla resources via domain config, with file-scan fallback.
Finds and returns the default repo module from AshScylla resources.
Converts a string CLI option value to a module atom, if present.
Returns the glob pattern used to discover generated migration files.
Returns the list of app atoms to scan: the current app + umbrella children.
Discovers Ash domains from the project's app configuration.
Returns the list of lib/ directories to scan (current app + umbrella children).
Scans all .ex files in project lib/ directories for AshScylla resources.
Functions
Adds child application paths to the code path.
This ensures that dependencies (child apps) are available when running migrations or other tasks that need access to compiled modules.
@spec app_name() :: atom()
Returns the application name from Mix config.
Checks if a module is a valid Ash domain.
Verifies the module is compiled and exports domain?/0 (added by
use Ash.Domain), which distinguishes domains from plain modules.
Checks if a resource module uses AshScylla.DataLayer.
Converts a file path to a module name.
Examples
iex> AshScylla.MixHelpers.file_to_module("lib/my_app/resources/user.ex")
:"Elixir.MyApp.Resources.User"
@spec find_all_resources() :: [module()]
Finds all AshScylla resources via domain config, with file-scan fallback.
- Reads configured domains from app env
- Gets each domain's resources via
Ash.Domain.Info.resources/1 - Filters to AshScylla resources
- Falls back to scanning
lib/**/*.exfiles if no domains configured
@spec find_default_repo() :: module()
Finds and returns the default repo module from AshScylla resources.
Extracts the repo from each resource's DSL config and returns the first one.
Converts a string CLI option value to a module atom, if present.
Uses Module.concat/1 to produce a proper module reference (e.g.
"MyApp.User" becomes MyApp.User, not :"MyApp.User").
Returns the glob pattern used to discover generated migration files.
Migration files are written as .exs (matching Ecto's convention for
non-compiled migration files). Keeping this in one place means the writer
(AshScylla.MigrationGenerator) and every reader (AshScylla.SchemaLoader,
Mix.Tasks.AshScylla.Migrate, ...) agree on the extension.
Examples
iex> AshScylla.MixHelpers.migration_glob("priv/repo/migrations")
"priv/repo/migrations/**/*.exs"
@spec project_apps() :: [atom()]
Returns the list of app atoms to scan: the current app + umbrella children.
@spec project_domains() :: [module()]
Discovers Ash domains from the project's app configuration.
Checks each app for :ash_domains config, ensures modules are compiled,
and validates they are actual Ash domains (Spark DSL modules).
@spec project_lib_paths() :: [String.t()]
Returns the list of lib/ directories to scan (current app + umbrella children).
@spec scan_files_for_resources() :: [module()]
Scans all .ex files in project lib/ directories for AshScylla resources.