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
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
@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.