Functions & API Calls
maybe_fetch/5
Purpose: Determine if dependency needs fetching and fetch if necessary
Signature:
-spec maybe_fetch(AppInfo, Profile, Upgrade, Seen, State) -> {Cached | false, AppInfo} when
AppInfo :: rebar_app_info:t(),
Profile :: atom(),
Upgrade :: boolean(),
Seen :: sets:set(),
State :: rebar_state:t(),
Cached :: boolean().
Arguments:
AppInfo: Dependency application infoProfile: Current profileUpgrade: Whether in upgrade modeSeen: Set of already-seen dependenciesState: Current rebar state
Returns: {Cached, UpdatedAppInfo}
Flow:
- Check if checkout dependency → skip fetch
- Check if already exists locally
- If exists and not upgrade mode → check if needs update
- If needs fetch/update → call
rebar_fetch:download_source/2 - Return updated app info
rebar_fetch:download_source/2
Purpose: Main entry point for downloading any dependency
Signature:
-spec download_source(rebar_app_info:t(), rebar_state:t()) ->
rebar_app_info:t() | {error, any()}.
Arguments:
AppInfo(rebar_app_info:t()): Dependency to downloadState(rebar_state:t()): Current state
Returns:
- Updated
AppInfowith dependency downloaded {error, Reason}if download failed
Flow:
- Check offline mode → error if offline and not cached
- Call
download_source_online/2 - After download: read dependency's
rebar.config - Update app info opts with dependency's config
- Discover application with
rebar_app_discover:find_app/4 - Mark as available
- Return updated app info
Example Usage:
AppInfo1 = rebar_fetch:download_source(AppInfo, State)
download_source_online/2
Purpose: Perform actual download operation
Signature:
-spec download_source_online(rebar_app_info:t(), rebar_state:t()) -> ok | {error, term()}.
Arguments:
AppInfo: Dependency to downloadState: Current state
Returns: ok or {error, Reason}
Flow:
- Get app directory from app info
- Create temporary directory with
ec_file:insecure_mkdtemp/0 - Call
rebar_resource_v2:download/3with TmpDir - Resource module downloads to TmpDir
- Ensure app directory exists
- Remove old version from code path
- Remove old fetch directory
- Move TmpDir to final location (FetchDir)
rebar_resource_v2:download/3
Purpose: Dispatch to appropriate resource module for download
Signature:
-spec download(TmpDir, AppInfo, State) -> ok | {error, term()} when
TmpDir :: file:filename(),
AppInfo :: rebar_app_info:t(),
State :: rebar_state:t().
Arguments:
TmpDir: Temporary directory for downloadAppInfo: Dependency info with sourceState: Current state
Returns: ok or {error, Reason}
Flow:
- Determine resource type from source
- Call appropriate resource module's
download/4:rebar_pkg_resource:download/4for Hex packagesrebar_git_resource:download/4for Git reposrebar_hg_resource:download/4for Mercurial repos
rebar_pkg_resource:download/4
Purpose: Download Hex package
Signature:
-spec download(TmpDir, AppInfo, State, ResourceState) -> ok | {error, term()} when
TmpDir :: file:name(),
AppInfo :: rebar_app_info:t(),
State :: rebar_state:t(),
ResourceState :: rebar_resource_v2:resource_state().
Arguments:
TmpDir: Temporary directoryAppInfo: Package infoState: Current stateResourceState: Resource-specific state (repos config)
Returns: ok or {error, Reason}
Flow:
- Get package cache directory
- Build cache path:
~/.cache/rebar3/hex/default/packages/name-version.tar - Build ETag file path:
~/.cache/rebar3/hex/default/packages/name-version.etag - Call
cached_download/7with cache info - Extract tarball contents to TmpDir
cached_download/7
Purpose: Download package with caching and ETag support
Signature:
-spec cached_download(TmpDir, CachePath, Pkg, State, ETag, ETagPath, UpdateETag) ->
ok | {error, term()} when
TmpDir :: file:name(),
CachePath :: file:name(),
Pkg :: package(),
State :: rebar_state:t(),
ETag :: binary() | undefined,
ETagPath :: file:name(),
UpdateETag :: boolean().
Flow:
- Check if cached tarball exists
- If exists: read ETag from ETag file
- Request package from Hex with ETag (If-None-Match header)
- If 304 Not Modified: use cached tarball
- If 200 OK: download new tarball
- Verify checksum:
calc_checksum(Tarball)vs registry checksum - If valid: store tarball and ETag in cache
- Extract tarball to TmpDir
r3_hex_repo:get_tarball/3
Purpose: HTTP request to Hex for package tarball
Signature:
-spec get_tarball(Config, Name, Version) ->
{ok, {StatusCode, Headers, Body}} | {error, Reason} when
Config :: map(),
Name :: binary(),
Version :: binary(),
StatusCode :: integer(),
Headers :: map(),
Body :: binary(),
Reason :: term().
Arguments:
Config: Hex repo configuration (includes ETag)Name: Package nameVersion: Package version
Returns:
{ok, {200, Headers, Tarball}}: New tarball downloaded{ok, {304, Headers, _}}: Cached version still valid{ok, {Code, _, _}}: Other HTTP status{error, Reason}: Network/HTTP error
Headers:
<<"etag">>: ETag value for caching
rebar_git_resource:download/4
Purpose: Clone Git repository
Signature:
-spec download(TmpDir, AppInfo, State, ResourceState) -> ok | {error, term()} when
TmpDir :: file:name(),
AppInfo :: rebar_app_info:t(),
State :: rebar_state:t(),
ResourceState :: rebar_resource_v2:resource_state().
Arguments:
TmpDir: Temporary directory for cloneAppInfo: Git source infoState: Current stateResourceState: Resource state
Returns: ok or {error, Reason}
Flow:
- Ensure TmpDir exists
- Detect Git version with
git_vsn/0 - Parse source ref spec (branch/tag/ref)
- Call appropriate
git_clone/5variant - Clone to
TmpDir/basename
git_clone/5
Purpose: Execute git clone with appropriate options
Signature:
-spec git_clone(Type, GitVersion, Url, Dir, RefSpec) -> ok | {error, term()} when
Type :: branch | tag | ref | rev,
GitVersion :: {Major, Minor, Patch} | undefined,
Url :: string(),
Dir :: file:name(),
RefSpec :: string().
Arguments:
Type: Type of ref (branch, tag, ref, rev)GitVersion: Detected Git versionUrl: Git repository URLDir: Target directoryRefSpec: Specific branch/tag/ref value
Commands Based on Git Version:
Branch (Git >= 2.3.0):
git clone [options] URL DIR -b BRANCH --single-branch
Branch (Git < 2.3.0):
git clone [options] URL DIR
cd DIR && git checkout -b BRANCH origin/BRANCH
Tag (Git >= 2.3.0):
git clone [options] URL DIR -b TAG --single-branch
Tag (Git < 2.3.0):
git clone [options] URL DIR
cd DIR && git checkout TAG
Ref:
git clone [options] URL DIR
cd DIR && git checkout REF
Environment:
GIT_TERMINAL_PROMPT=0: Disable interactive prompts
rebar_git_resource:lock/2
Purpose: Get current commit ref for locking
Signature:
-spec lock(AppInfo, ResourceState) -> {git, Url, {ref, Ref}} when
AppInfo :: rebar_app_info:t(),
ResourceState :: rebar_resource_v2:resource_state(),
Url :: string(),
Ref :: string().
Arguments:
AppInfo: Dependency app infoResourceState: Resource state
Returns: Lock source tuple with commit ref
Command:
git -C DIR rev-parse --verify HEAD
Result: Full commit SHA (40 characters)
rebar_git_resource:needs_update/2
Purpose: Check if Git dependency needs updating
Signature:
-spec needs_update(AppInfo, ResourceState) -> boolean() when
AppInfo :: rebar_app_info:t(),
ResourceState :: rebar_resource_v2:resource_state().
Arguments:
AppInfo: Dependency infoResourceState: Resource state
Returns: true if update needed, false otherwise
Logic by Type:
Tag:
git describe --tags --exact-match
Compare with specified tag and URL
Branch:
git fetch origin BRANCH
git log HEAD..origin/BRANCH --oneline
Update needed if new commits exist
Ref:
git rev-parse --short=7 -q HEAD
Compare with specified ref (truncated to same length)
rebar_hg_resource:download/4
Purpose: Clone Mercurial repository
Signature:
-spec download(TmpDir, AppInfo, State, ResourceState) -> ok | {error, term()} when
TmpDir :: file:name(),
AppInfo :: rebar_app_info:t(),
State :: rebar_state:t(),
ResourceState :: rebar_resource_v2:resource_state().
Commands:
hg clone URL DIR
cd DIR && hg update -r REVISION
Or for tags:
hg clone URL DIR
cd DIR && hg update TAG