@ -3,71 +3,76 @@
- module ( rebar_relx ) .
- export ( [ do / 4 ,
- export ( [ do / 2 ,
opt_spec_list / 0 ,
format_error / 1 ] ) .
- ifdef ( TEST ) .
- export ( [ merge_overlays / 1 ] ) .
- endif .
- include_lib ( " providers/include/providers.hrl " ) .
- include ( " rebar.hrl " ) .
% % == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == =
% % Public API
% % == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == =
- spec do ( atom ( ) , string ( ) , atom ( ) , rebar_state : t ( ) ) - > { ok , rebar_state : t ( ) } | { error , string ( ) } .
do ( Module , Command , Provider , State ) - >
% % We set the color mode for relx as a application env
application : set_env ( relx , color_intensity , rebar_log : intensity ( ) ) ,
LogLevel = rebar_log : get_level ( ) ,
Options = rebar_state : command_args ( State ) ,
DepsDir = rebar_dir : deps_dir ( State ) ,
ProjectAppDirs = lists : delete ( " . " , ? DEFAULT_PROJECT_APP_DIRS ) ,
LibDirs = rebar_utils : filtermap ( fun ec_file : exists / 1 ,
[ rebar_dir : checkouts_dir ( State ) , DepsDir | ProjectAppDirs ] ) ,
OutputDir = filename : join ( rebar_dir : base_dir ( State ) , ? DEFAULT_RELEASE_DIR ) ,
- spec do ( atom ( ) , rebar_state : t ( ) ) - > { ok , rebar_state : t ( ) } | { error , string ( ) } .
do ( Provider , State ) - >
{ Opts , _ } = rebar_state : command_parsed_args ( State ) ,
Release = case proplists : get_value ( relname , Opts , undefined ) of
undefined - >
undefined ;
R - >
case proplists : get_value ( relvsn , Opts , undefined ) of
undefined - >
list_to_atom ( R ) ;
RelVsn - >
{ list_to_atom ( R ) , RelVsn }
end
end ,
% % TODO : read in . / relx . config if it exists or -- config value
RelxConfig = rebar_state : get ( State , relx , [ ] ) ,
ProfileString = rebar_dir : profile_dir_name ( State ) ,
AllOptions = rebar_string : join ( [ Command | Options ] , " " ) ,
Cwd = rebar_state : dir ( State ) ,
Providers = rebar_state : providers ( State ) ,
RebarOpts = rebar_state : opts ( State ) ,
ExtraOverlays = [ { profile_string , ProfileString } ] ,
ErlOpts = rebar_opts : erl_opts ( RebarOpts ) ,
DefaultOutputDir = filename : join ( rebar_dir : base_dir ( State ) , ? DEFAULT_RELEASE_DIR ) ,
RelxConfig1 = [ output_dir ( DefaultOutputDir , Opts ) ,
{ overlay_vars_values , ExtraOverlays } ,
{ overlay_vars , [ { base_dir , rebar_dir : base_dir ( State ) } ] }
| merge_overlays ( RelxConfig ) ] ,
{ ok , RelxState } = rlx_config : to_state ( RelxConfig1 ) ,
Providers = rebar_state : providers ( State ) ,
Cwd = rebar_state : dir ( State ) ,
rebar_hooks : run_project_and_app_hooks ( Cwd , pre , Provider , Providers , State ) ,
try
case rebar_state : get ( State , relx , [ ] ) of
[ ] - >
relx : main ( [ { lib_dirs , LibDirs }
, { caller , api }
, { log_level , LogLevel }
, { api_caller_overlays , ExtraOverlays }
| output_dir ( OutputDir , Options ) ] ++ ErlOpts , AllOptions ) ;
Config - >
Config1 = [ { overlay_vars , [ { base_dir , rebar_dir : base_dir ( State ) } ] }
| merge_overlays ( Config ) ] ,
relx : main ( [ { lib_dirs , LibDirs }
, { config , Config1 }
, { caller , api }
, { log_level , LogLevel }
, { api_caller_overlays , ExtraOverlays }
| output_dir ( OutputDir , Options ) ] ++ ErlOpts , AllOptions )
end ,
rebar_hooks : run_project_and_app_hooks ( Cwd , post , Provider , Providers , State ) ,
{ ok , State }
catch
throw : T - >
{ error , { Module , T } }
end .
case Provider of
release - >
relx : build_release ( Release , all_apps ( State ) , RelxState ) ;
tar - >
relx : build_tar ( Release , all_apps ( State ) , RelxState ) ;
relup - >
ToVsn = proplists : get_value ( relvsn , Opts , undefined ) ,
UpFromVsn = proplists : get_value ( upfrom , Opts , undefined ) ,
relx : build_relup ( Release , ToVsn , UpFromVsn , RelxState )
end ,
rebar_hooks : run_project_and_app_hooks ( Cwd , post , Provider , Providers , State ) ,
{ ok , State } .
- spec format_error ( any ( ) ) - > iolist ( ) .
format_error ( Reason ) - >
io_lib : format ( " ~p " , [ Reason ] ) .
format_error ( Error ) - >
io_lib : format ( " ~p " , [ Error ] ) .
% % Don ' t override output_dir if the user passed one on the command line
output_dir ( OutputDir , Options ) - >
[ { output_dir , OutputDir } | | not ( lists : member ( " -o " , Options ) )
andalso not ( lists : member ( " --output-dir " , Options ) ) ] .
output_dir ( DefaultOutputDir , Options ) - >
{ output_dir , proplists : get_value ( output_dir , Options , DefaultOutputDir ) } .
merge_overlays ( Config ) - >
{ Overlays , Others } =
@ -77,3 +82,45 @@ merge_overlays(Config) ->
% % Have profile overlay entries come before others to match how profiles work elsewhere
NewOverlay = lists : flatmap ( fun ( { overlay , Overlay } ) - > Overlay end , lists : reverse ( Overlays ) ) ,
[ { overlay , NewOverlay } | Others ] .
% %
% % Returns a map of all apps that are part of the rebar3 project .
% % This means the project apps and dependencies but not OTP libraries .
- spec all_apps ( rebar_state : t ( ) ) - > #{ atom ( ) = > rlx_app_info : t ( ) } .
all_apps ( State ) - >
lists : foldl ( fun ( AppInfo , Acc ) - >
Acc #{ binary_to_atom ( rebar_app_info : name ( AppInfo ) , utf8 )
= > rebar_app_info : app_to_map ( AppInfo ) }
end , #{ } , rebar_state : project_apps ( State ) ++ rebar_state : all_deps ( State ) ) .
% %
- spec opt_spec_list ( ) - > [ getopt : option_spec ( ) ] .
opt_spec_list ( ) - >
[ { relname , $n , " relname " , string ,
" Specify the name for the release that will be generated " } ,
{ relvsn , $v , " relvsn " , string , " Specify the version for the release " } ,
{ upfrom , $u , " upfrom " , string ,
" Only valid with relup target, specify the release to upgrade from " } ,
{ output_dir , $o , " output-dir " , string ,
" The output directory for the release. This is `./` by default. " } ,
{ help , $h , " help " , undefined ,
" Print usage " } ,
{ lib_dir , $l , " lib-dir " , string ,
" Additional dir that should be searched for OTP Apps " } ,
{ log_level , $V , " verbose " , { integer , 2 } ,
" Verbosity level, maybe between 0 and 3 " } ,
{ dev_mode , $d , " dev-mode " , boolean ,
" Symlink the applications and configuration into the release instead of copying " } ,
{ include_erts , $i , " include-erts " , string ,
" If true include a copy of erts used to build with, if a path include erts at that path. If false, do not include erts " } ,
{ override , $a , " override " , string ,
" Provide an app name and a directory to override in the form <appname>:<app directory> " } ,
{ config , $c , " config " , { string , " " } , " The path to a config file " } ,
{ overlay_vars , undefined , " overlay_vars " , string , " Path to a file of overlay variables " } ,
{ vm_args , undefined , " vm_args " , string , " Path to a file to use for vm.args " } ,
{ sys_config , undefined , " sys_config " , string , " Path to a file to use for sys.config " } ,
{ system_libs , undefined , " system_libs " , string , " Boolean or path to dir of Erlang system libs " } ,
{ version , undefined , " version " , undefined , " Print relx version " } ,
{ root_dir , $r , " root " , string , " The project root directory " } ] .