Functions & API Calls
rebar_prv_app_discovery:do/1
Purpose: Main provider entry point for application discovery
Signature:
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
Arguments:
State(rebar_state:t()): Current state
Returns: {ok, State} with discovered applications
Flow:
- Get
lib_dirsfrom state - Call
rebar_app_discover:do/2 - Install project app plugins
- Return updated state
rebar_app_discover:do/2
Purpose: Main discovery logic
Signature:
-spec do(rebar_state:t(), [file:filename()]) -> rebar_state:t() | no_return().
Arguments:
State(rebar_state:t()): Current stateLibDirs([file:filename()]): Library directories to scan
Returns: Updated state with project apps
Flow:
- Get
src_dirsfrom opts - Call
find_apps/4to discover applications - Call
define_root_app/2to determine project type - Parse dependencies per profile
- For each app, call
merge_opts/3and update state - Return state with
project_appsset
find_apps/4
Purpose: Find all applications in given directories
Signature:
-spec find_apps(LibDirs, SrcDirs, Validate, State) -> [rebar_app_info:t()] when
LibDirs :: [file:filename_all()],
SrcDirs :: [file:filename_all()],
Validate :: valid | invalid | all,
State :: rebar_state:t().
Arguments:
LibDirs: Directories to search (e.g.,["apps"])SrcDirs: Source directories within each lib dir (e.g.,["src"])Validate: Filter criterion (all,valid,invalid)State: Current state
Returns: List of discovered applications
Flow:
- Call
all_app_dirs/3to get app directories - For each app directory, call
find_app/5 - Filter based on validation criterion
- Return list of app info records
all_app_dirs/3
Purpose: Find all directories containing applications
Signature:
-spec all_app_dirs([file:name()], [file:name()], rebar_state:t()) ->
[{file:name(), [file:name()]}].
Arguments:
- Library directories
- Source directories
- State
Returns: List of {AppDir, SrcDirs} tuples
Flow:
- For each lib directory:
- Build file patterns for app resources
- Patterns:
lib_dir/src_dir/*.{app,app.src,app.src.script} - Also:
lib_dir/ebin/*.app,lib_dir/mix.exs
- Use
filelib:wildcard/1to find matching files - Extract app directory from file path
- Return unique app directories with their src dirs
find_app/5
Purpose: Discover and validate a single application
Signature:
-spec find_app(AppInfo, AppDir, SrcDirs, Validate, State) ->
{true, rebar_app_info:t()} | false when
AppInfo :: rebar_app_info:t(),
AppDir :: file:filename_all(),
SrcDirs :: [file:filename_all()],
Validate :: valid | invalid | all,
State :: rebar_state:t().
Arguments:
AppInfo: Empty or partially-filled app infoAppDir: Application directorySrcDirs: Source directoriesValidate: Validation criterionState: Current state
Returns:
{true, AppInfo}if app found and matches validationfalseif app not found or doesn't match validation
Flow:
- Read app's
rebar.config(if exists) - Update app info opts with config
- Call
find_app_/5to locate and parse app resource file - Return result
find_app_/5
Purpose: Internal app discovery with resource file handling
Signature:
-spec find_app_(AppInfo, AppDir, SrcDirs, Validate, State) ->
{true, rebar_app_info:t()} | false when
AppInfo :: rebar_app_info:t(),
AppDir :: file:filename_all(),
SrcDirs :: [file:filename_all()],
Validate :: valid | invalid | all,
State :: rebar_state:t().
Flow:
- Get application resource extensions from state (default:
[".app", ".app.src", ".app.src.script"]) - Search for resource files in:
ebin/*.appsrc_dir/*.app.srcsrc_dir/*.app.src.scriptmix.exs
- Flatten resource files (preferring .app > .script > .app.src)
- Call
try_handle_resource_files/4to parse
try_handle_resource_files/4
Purpose: Parse application resource file and create app info
Signature:
-spec try_handle_resource_files(AppInfo, AppDir, ResourceFiles, Validate) ->
{true, rebar_app_info:t()} | false when
AppInfo :: rebar_app_info:t(),
AppDir :: file:filename_all(),
ResourceFiles :: [{app_resource_type(), file:filename()}],
Validate :: valid | invalid | all.
Flow:
- Select first available resource file
- Based on type:
.app: Callrebar_app_info:discover/1to parse.app.src: Callcreate_app_info_src/3.app.src.script: Evaluate script, then parsemix.exs: Parse Elixir project
- Validate application based on criterion
- Return app info or false
define_root_app/2
Purpose: Determine if project is single-app or umbrella
Signature:
-spec define_root_app([rebar_app_info:t()], rebar_state:t()) -> root | binary().
Arguments:
Apps: Discovered applicationsState: Current state
Returns:
- App name (binary) if single-app project
rootatom if umbrella project
Logic:
- Check if any app's directory equals project root directory
- If match found: single-app (return app name)
- If no match: umbrella (return
root)
parse_profile_deps/5
Purpose: Parse dependencies for a specific profile
Signature:
-spec parse_profile_deps(Profile, Name, Deps, Opts, State) -> [rebar_app_info:t()] when
Profile :: atom(),
Name :: binary() | root,
Deps :: [term()],
Opts :: rebar_dict(),
State :: rebar_state:t().
Arguments:
Profile: Profile name (default, test, etc.)Name: Application name orrootDeps: Dependency specificationsOpts: Application optionsState: Current state
Returns: List of parsed dependency app infos
Flow:
- Get dependency directory for profile
- Get locks from state
- Call
rebar_app_utils:parse_deps/6 - Return list of dependency app info records
merge_opts/3
Purpose: Merge top-level and app-specific configuration
Signature:
-spec merge_opts(root | binary(), rebar_app_info:t(), rebar_state:t()) ->
{rebar_app_info:t(), rebar_state:t()}.
Arguments:
TopLevelApp: Root app name orrootAppInfo: Application to configureState: Current state
Returns: {UpdatedAppInfo, UpdatedState}
Flow:
- Reset hooks/plugins if top-level app
- Apply overrides if not top-level app
- Apply profiles to app opts
- Verify OTP version requirements
- For each profile, handle app dependencies
- Return updated app info and state