aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml23
-rw-r--r--.gitignore4
-rw-r--r--.travis.yml42
-rw-r--r--README.md3
-rw-r--r--examples/relx.config2
-rw-r--r--priv/templates/bin_windows17
-rwxr-xr-xpriv/templates/extended_bin178
-rw-r--r--priv/templates/extended_bin_windows155
-rw-r--r--priv/templates/nodetool49
-rw-r--r--rebar.config3
-rw-r--r--src/relx.app.src18
-rw-r--r--src/relx.erl3
-rw-r--r--src/rlx_cmd_args.erl13
-rw-r--r--src/rlx_config.erl38
-rw-r--r--src/rlx_depsolver.erl2
-rw-r--r--src/rlx_depsolver_culprit.erl2
-rw-r--r--src/rlx_prv_archive.erl3
-rw-r--r--src/rlx_prv_assembler.erl4
-rw-r--r--src/rlx_prv_overlay.erl21
-rw-r--r--src/rlx_string.erl10
-rw-r--r--src/rlx_util.erl120
-rw-r--r--test/rlx_archive_SUITE.erl22
-rw-r--r--test/rlx_command_SUITE.erl16
-rw-r--r--test/rlx_depsolver_tester.erl500
-rw-r--r--test/rlx_depsolver_tests.erl2
-rw-r--r--test/rlx_discover_SUITE.erl2
-rw-r--r--test/rlx_eunit_SUITE.erl2
-rw-r--r--test/rlx_extended_bin_SUITE.erl152
-rw-r--r--test/rlx_prv_release_alias.erl27
-rw-r--r--test/rlx_release_SUITE.erl124
30 files changed, 999 insertions, 558 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
new file mode 100644
index 0000000..8e693dd
--- /dev/null
+++ b/.cirrus.yml
@@ -0,0 +1,23 @@
+test_task:
+ use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true'
+ container:
+ matrix:
+ - image: erlang:22
+ - image: erlang:21
+ - image: erlang:20
+ - image: erlang:19
+ - image: erlang:18
+ test_script: |
+ rebar3 eunit && rebar3 ct
+ always:
+ junit_artifacts:
+ path: "_build/test/logs/ct_run.*/junit_report.xml"
+
+osx_check_task:
+ osx_instance:
+ image: mojave-base
+ install_script: brew install erlang
+ test_script: |
+ wget https://s3.amazonaws.com/rebar3/rebar3
+ chmod +x rebar3
+ ./rebar3 eunit && ./rebar3 ct
diff --git a/.gitignore b/.gitignore
index f04f7d2..64d4e0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,5 +13,9 @@ logs
test/*_data
_rel/*
.*
+!.circleci
+!.cirrus.yml
erl_crash.dump
rebar
+TEST-*
+tags
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index ed0f025..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-language: erlang
-matrix:
- include:
- - os: linux
- sudo: required
- otp_release: 17.5
- - os: linux
- sudo: required
- otp_release: 18.3
- - os: linux
- sudo: required
- otp_release: 19.3
- - os: linux
- sudo: required
- otp_release: 20.0
- - os: linux
- sudo: required
- otp_release: 21.0
- - os: osx
- sudo: required
- language: generic
-before_script:
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- ## should eventually use a tap that has previous erlang versions here
- ## as this only uses the latest erlang available via brew
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install erlang; fi
- - wget https://s3.amazonaws.com/rebar3/rebar3
- - chmod +x rebar3
-script: "./rebar3 update && ./rebar3 ct"
-branches:
- only:
- - master
-addons:
- hostname: travis.dev
-notifications:
- email:
- irc:
- channels:
- - "irc.freenode.org#erlware"
- use_notice: true
- skip_join: true
diff --git a/README.md b/README.md
index 728a210..2cd3b42 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/erlware/relx.png?branch=master)](https://travis-ci.org/erlware/relx)
+[![Build Status](https://api.cirrus-ci.com/github/erlware/relx.svg)](https://cirrus-ci.com/github/erlware/relx)
Relx
=======
@@ -81,6 +81,7 @@ Options
| | --sys_config | string | | Path to a file to use for sys.config |
| -d | --dev-mode | boolean | false | Symlink all applications and configuration into the release instead of copying|
| -i | --include-erts | boolean/string | true | 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 |
+| | --provider | string | | Specify an additional relx provider |
Wiki
----
diff --git a/examples/relx.config b/examples/relx.config
index b19042b..3622d01 100644
--- a/examples/relx.config
+++ b/examples/relx.config
@@ -45,7 +45,7 @@
%% When we have multiple releases relx needs to know which one to build. You
%% can specify that on the command line with the `-n` and `-v` arguments to
%% relx. However, it is often more convenient to do it in the config.
-{default_release, sexpr, "0.0.2"}.
+{default_release, {sexpr, "0.0.2"}}.
{release, {sexpr, "0.0.1"},
[sexpr,
diff --git a/priv/templates/bin_windows b/priv/templates/bin_windows
index b3ce796..19c0d2d 100644
--- a/priv/templates/bin_windows
+++ b/priv/templates/bin_windows
@@ -73,6 +73,23 @@ cd %rootdir%
@set "possible_sys=%rel_dir%\sys.config"
@if exist "%possible_sys%" (
set sys_config=-config "%possible_sys%"
+) else (
+ @if exist "%possible_sys%.orig" (
+ ren "%possible_sys%.orig" sys.config
+ set sys_config=-config "%possible_sys%"
+ )
+)
+
+:: Find the vm.args file
+:find_vm_args
+@set "possible_vm_args=%rel_dir%\vm.args"
+@if exist "%possible_vm_args%" (
+ set vm_args="%possible_vm_args%"
+) else (
+ @if exist "%possible_vm_args%.orig" (
+ ren "%possible_vm_args%.orig" vm.args
+ set vm_args="%possible_vm_args%"
+ )
)
@goto :eof
diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin
index 11a0abc..a4cba4a 100755
--- a/priv/templates/extended_bin
+++ b/priv/templates/extended_bin
@@ -19,7 +19,7 @@ fi
# OSX does not support readlink '-f' flag, work
# around that
-case $OSTYPE in
+case $OSTYPE in
darwin*)
SCRIPT=$(readlink $0 || true)
;;
@@ -150,10 +150,19 @@ relx_get_pid() {
relx_get_nodename() {
id="longname$(relx_gen_id)-${NAME}"
- "$BINDIR/erl" -boot start_clean \
- -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
- -eval '[_,H]=re:split(atom_to_list(node()),"@",[unicode,{return,list}]), io:format("~s~n",[H]), halt()' \
- -noshell ${NAME_TYPE} $id
+ if [ -z "$COOKIE" ]; then
+ "$BINDIR/erl" -boot start_clean \
+ -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
+ -eval '[_,H]=re:split(atom_to_list(node()),"@",[unicode,{return,list}]), io:format("~s~n",[H]), halt()' \
+ -noshell ${NAME_TYPE} $id
+ else
+ # running with setcookie prevents a ~/.erlang.cookie from being created
+ "$BINDIR/erl" -boot start_clean \
+ -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
+ -eval '[_,H]=re:split(atom_to_list(node()),"@",[unicode,{return,list}]), io:format("~s~n",[H]), halt()' \
+ -setcookie ${COOKIE} \
+ -noshell ${NAME_TYPE} $id
+ fi
}
# Connect to a remote node
@@ -167,8 +176,8 @@ relx_rem_sh() {
# Setup remote shell command to control node
exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \
- -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
- -setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME $VM_ARGS
+ -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" $MAYBE_DIST_ARGS \
+ -setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME
}
# Generate a random id
@@ -180,15 +189,27 @@ relx_gen_id() {
relx_nodetool() {
command="$1"; shift
- escript_emulator_args $ROOTDIR/bin/nodetool
+ # Generate a unique id used to allow multiple nodetool calls to the
+ # same node transparently
+ nodetool_id="maint$(relx_gen_id)-${NAME}"
- "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
- -setcookie "$COOKIE" "$command" $@
+ if [ -z "${START_EPMD}" ]; then
+ ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS} ${NAME_TYPE} $nodetool_id -setcookie ${COOKIE}" \
+ "$ERTS_DIR/bin/escript" \
+ "$ROOTDIR/bin/nodetool" \
+ "$NAME_TYPE" "$NAME" \
+ "$command" $@
+ else
+ ERL_FLAGS="${ERL_FLAGS} ${MAYBE_DIST_ARGS} ${NAME_TYPE} $nodetool_id -setcookie ${COOKIE}" \
+ "$ERTS_DIR/bin/escript" \
+ "$ROOTDIR/bin/nodetool" \
+ $START_EPMD "$NAME_TYPE" "$NAME" "$command" $@
+ fi
}
# Run an escript in the node's environment
relx_escript() {
- shift; scriptpath="$1"; shift
+ scriptpath="$1"; shift
export RELEASE_ROOT_DIR
"$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
@@ -231,23 +252,6 @@ replace_os_vars() {
}1' < "$1" > "$2"
}
-escript_emulator_args() {
- if [ -n "${VM_ARGS}" ]; then
- if grep -q '%%!' $1; then
- cmd=$(echo sed -i"'.prev'" "'/%%!.*/ s| ${VM_ARGS}||'" $1)
- eval "$cmd"
- cmd=$(echo sed -i"'.prev'" "'/%%!.*/ s|$| ${VM_ARGS}|'" $1)
- eval "$cmd"
- rm ${1}.prev
- else
- cmd=$(echo sed -i"'.prev'" "'/#!.*/ a \\
-%%! ${VM_ARGS}\n'" $1)
- eval "$cmd"
- rm ${1}.prev
- fi
- fi
-}
-
add_path() {
# Use $CWD/$1 if exists, otherwise releases/VSN/$1
IN_FILE_PATH=$2
@@ -267,9 +271,9 @@ check_replace_os_vars() {
SRC_FILE_PATH="$IN_FILE_PATH.src"
ORIG_FILE_PATH="$IN_FILE_PATH.orig"
if [ -f "$SRC_FILE_PATH" ]; then
+ OUT_FILE_PATH=$(make_out_file_path $IN_FILE_PATH)
replace_os_vars "$SRC_FILE_PATH" "$OUT_FILE_PATH"
elif [ $RELX_REPLACE_OS_VARS ]; then
- # Create a new file in the same location as original
OUT_FILE_PATH=$(make_out_file_path $IN_FILE_PATH)
# If vm.args.orig or sys.config.orig is present then use that
if [ -f "$ORIG_FILE_PATH" ]; then
@@ -289,7 +293,8 @@ check_replace_os_vars() {
else
# If vm.arg.orig or sys.config.orig is present then use that
if [ -f "$ORIG_FILE_PATH" ]; then
- cp "$ORIG_FILE_PATH" "$OUT_FILE_PATH"
+ OUT_FILE_PATH=$(make_out_file_path $IN_FILE_PATH)
+ cp "$ORIG_FILE_PATH" "$OUT_FILE_PATH"
fi
fi
echo $OUT_FILE_PATH
@@ -312,14 +317,24 @@ relx_run_hooks() {
done
}
+relx_disable_hooks() {
+ PRE_START_HOOKS=""
+ POST_START_HOOKS=""
+ PRE_STOP_HOOKS=""
+ POST_STOP_HOOKS=""
+ PRE_INSTALL_UPGRADE_HOOKS=""
+ POST_INSTALL_UPGRADE_HOOKS=""
+ STATUS_HOOK=""
+}
+
relx_is_extension() {
EXTENSION=$1
case "$EXTENSION" in
{{{ extensions }}})
- echo "1"
+ echo "1"
;;
*)
- echo "0"
+ echo "0"
;;
esac
}
@@ -330,7 +345,7 @@ relx_get_extension_script() {
# of the form:
# foo_extension="path/to/foo_script";bar_extension="path/to/bar_script"
{{{extension_declarations}}}
- # get the command extension (eg. foo) and
+ # get the command extension (eg. foo) and
# obtain the actual script filename that it
# refers to (eg. "path/to/foo_script"
eval echo "$"${EXTENSION}_extension""
@@ -343,9 +358,29 @@ relx_run_extension() {
shift
# all extension script locations are expected to be
# relative to the start script location
- [ "$SCRIPT_DIR/$EXTENSION_SCRIPT" ] && . "$SCRIPT_DIR/$EXTENSION_SCRIPT" $@
+ [ "$SCRIPT_DIR/$EXTENSION_SCRIPT" ] && . "$SCRIPT_DIR/$EXTENSION_SCRIPT" "$@"
+}
+
+# given a list of arguments, identify the internal ones
+# --relx-disable-hooks
+# and process them accordingly
+process_internal_args() {
+ for arg in $@
+ do
+ shift
+ case "$arg" in
+ --relx-disable-hooks)
+ relx_disable_hooks
+ ;;
+ *)
+ ;;
+ esac
+ done
}
+# process internal arguments
+process_internal_args $@
+
find_erts_dir
export ROOTDIR="$RELEASE_ROOT_DIR"
export BINDIR="$ERTS_DIR/bin"
@@ -433,39 +468,49 @@ NAME_ARG=$(eval echo "${NAME_ARG}")
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"
-# User can specify an sname without @hostname
-# This will fail when creating remote shell
-# So here we check for @ and add @hostname if missing
-case "${NAME}" in
- *@*) ;; # Nothing to do
- *) NAME=${NAME}@$(relx_get_nodename);; # Add @hostname
-esac
-
-# Export the variable so that it's available in the 'eval' calls
-export NAME
-
-# Make sure log directory exists
-mkdir -p "$RUNNER_LOG_DIR"
-
-test -z "$PIPE_DIR" && PIPE_BASE_DIR='/tmp/erl_pipes/'
-PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}"
+# Extract dist arguments
+MAYBE_DIST_ARGS=""
+PROTO_DIST="$(grep '^-proto_dist' "$VMARGS_PATH" || true)"
+if [ "$PROTO_DIST" ]; then
+ MAYBE_DIST_ARGS="${PROTO_DIST}"
+fi
+START_EPMD="$(grep '^-start_epmd' "$VMARGS_PATH" || true)"
+if [ "$START_EPMD" ]; then
+ MAYBE_DIST_ARGS="${MAYBE_DIST_ARGS} ${START_EPMD}"
+fi
+EPMD_MODULE="$(grep '^-epmd_module' "$VMARGS_PATH" || true)"
+if [ "$EPMD_MODULE" ]; then
+ MAYBE_DIST_ARGS="${MAYBE_DIST_ARGS} ${EPMD_MODULE}"
+fi
# Extract the target cookie
+# Do this before relx_get_nodename so we can use it and not create a ~/.erlang.cookie
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)"
DEFAULT_COOKIE_FILE="$HOME/.erlang.cookie"
if [ -z "$COOKIE_ARG" ]; then
if [ -f "$DEFAULT_COOKIE_FILE" ]; then
COOKIE="$(cat $DEFAULT_COOKIE_FILE)"
else
- echo "vm.args needs to have a -setcookie, or $DEFAULT_COOKIE_FILE (its permission must be 400) is required."
- exit 1
+ echo "No cookie is set or found. This limits the scripts functionality, installing, upgrading, rpc and getting a list of versions will not work."
fi
else
# Extract cookie name from COOKIE_ARG
COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
fi
-VM_ARGS="$(grep -v -E '^#|^-name|^-sname|^-setcookie|^-heart|^-args_file' "$VMARGS_PATH" | xargs | sed -e 's/ / /g')"
+# User can specify an sname without @hostname
+# This will fail when creating remote shell
+# So here we check for @ and add @hostname if missing
+case "${NAME}" in
+ *@*) ;; # Nothing to do
+ *) NAME=${NAME}@$(relx_get_nodename);; # Add @hostname
+esac
+
+# Export the variable so that it's available in the 'eval' calls
+export NAME
+
+test -z "$PIPE_DIR" && PIPE_BASE_DIR='/tmp/erl_pipes/'
+PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}"
cd "$ROOTDIR"
@@ -492,10 +537,18 @@ case "$1" in
test -z "$PIPE_BASE_DIR" || mkdir -m 1777 -p "$PIPE_BASE_DIR"
mkdir -p "$PIPE_DIR"
+ if [ ! -w "$PIPE_DIR" ]
+ then
+ echo "failed to start, user '$USER' does not have write privileges on '$PIPE_DIR', either delete it or run node as a different user"
+ exit 1
+ fi
+
+ # Make sure log directory exists
+ mkdir -p "$RUNNER_LOG_DIR"
relx_run_hooks "$PRE_START_HOOKS"
"$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
- "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" $ARGS"
+ "exec \"$RELEASE_ROOT_DIR/bin/$REL_NAME\" \"$START_OPTION\" $ARGS --relx-disable-hooks"
relx_run_hooks "$POST_START_HOOKS"
;;
@@ -543,6 +596,7 @@ case "$1" in
escript)
## Run an escript under the node's environment
+ shift
if ! relx_escript $@; then
exit 1
fi
@@ -555,6 +609,12 @@ case "$1" in
exit 1
fi
+ if [ ! -w "$PIPE_DIR" ]
+ then
+ echo "failed to attach, user '$USER' does not have sufficient privileges on '$PIPE_DIR', please run node as a different user"
+ exit 1
+ fi
+
shift
exec "$BINDIR/to_erl" "$PIPE_DIR"
;;
@@ -587,8 +647,6 @@ case "$1" in
relx_run_hooks "$PRE_INSTALL_UPGRADE_HOOKS"
- escript_emulator_args $ROOTDIR/bin/install_upgrade.escript
-
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
"$COMMAND" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@"
@@ -603,8 +661,6 @@ case "$1" in
fi
COMMAND="$1"; shift
-
- escript_emulator_args $ROOTDIR/bin/install_upgrade.escript
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
"versions" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@"
@@ -664,6 +720,7 @@ case "$1" in
echo "$RELEASE_ROOT_DIR"
logger -t "$REL_NAME[$$]" "Starting up"
+ relx_run_hooks "$PRE_START_HOOKS"
# Start the VM
exec "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
-boot "$BOOTFILE" -mode "$CODE_LOADING_MODE" \
@@ -671,6 +728,9 @@ case "$1" in
-config "$RELX_CONFIG_PATH" \
-args_file "$VMARGS_PATH" \
-pa ${__code_paths} -- "$@"
+ # exec will replace the current image and nothing else gets
+ # executed from this point on, this explains the absence
+ # of the pre start hook
;;
rpc)
# Make sure a node IS running
@@ -728,7 +788,7 @@ case "$1" in
if [ "$IS_EXTENSION" = "1" ]; then
EXTENSION_SCRIPT=$(relx_get_extension_script $1)
shift
- relx_run_extension $EXTENSION_SCRIPT $@
+ relx_run_extension $EXTENSION_SCRIPT "$@"
# all extension scripts are expected to exit
else
relx_usage $1
diff --git a/priv/templates/extended_bin_windows b/priv/templates/extended_bin_windows
index d30d78d..16e3d96 100644
--- a/priv/templates/extended_bin_windows
+++ b/priv/templates/extended_bin_windows
@@ -37,14 +37,18 @@
@set vm_args=%rel_dir%\vm.args
@set progname=erl.exe
@set clean_boot_script=%release_root_dir%\bin\start_clean
-@set erlsrv="%bindir%\erlsrv.exe"
-@set epmd="%bindir%\epmd.exe"
-@set escript="%bindir%\escript.exe"
-@set werl="%bindir%\werl.exe"
-@set nodetool="%release_root_dir%\bin\nodetool"
+@set "erlsrv=%bindir%\erlsrv.exe"
+@set "epmd=%bindir%\epmd.exe"
+@set "escript=%bindir%\escript.exe"
+@set "werl=%bindir%\werl.exe"
+@set "erl=%bindir%\erl.exe"
+@set "nodetool=%release_root_dir%\bin\nodetool"
+@set "extensions0={{ extensions }}"
+@set "extensions1=%extensions0:|= %"
+@set "extensions=%extensions1: undefined=%"
:: Extract node type and name from vm.args
-@for /f "usebackq tokens=1-2" %%I in (`findstr /b "\-name \-sname" "%vm_args%"`) do @(
+@for /f "usebackq tokens=1-2" %%I in ('findstr /b "\-name \-sname" "%vm_args%"') do @(
set node_type=%%I
set node_name=%%J
)
@@ -73,9 +77,18 @@
set "hostname=@%hostname%"
)
-:: Extract cookie from vm.args
-@for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do @(
- set cookie=%%J
+:: Extract the target cookie
+:: Do this before relx_get_nodename so we can use it and not create a ~/.erlang.cookie
+@for /f "usebackq tokens=1-2" %%I in ('findstr /b \-setcookie "%vm_args%"') do @(
+ set "cookie=%%J"
+)
+@set "default_cookie_file=%USERPROFILE%\.erlang.cookie"
+@if "%cookie%" == "" @(
+ if exist "%default_cookie_file%" (
+ set /p cookie=<%default_cookie_file%
+ ) else (
+ echo No cookie is set or found. This limits the scripts functionality, installing, upgrading, rpc and getting a list of versions will not work.
+ )
)
:: Write the erl.ini file to set up paths relative to this script
@@ -83,7 +96,7 @@
:: Collect any additional VM args into erl_opts
@setlocal EnableDelayedExpansion
-@for /f "usebackq tokens=1-2" %%I in (`findstr /r "^[^#]" "%vm_args%"`) do @(
+@for /f "usebackq tokens=1-2" %%I in ('findstr /r "^[^#]" "%vm_args%"') do @(
if not "%%I" == "-name" (
if not "%%I" == "-sname" (
if not "%%I" == "-setcookie" (
@@ -99,6 +112,7 @@
copy "%rel_dir%\%rel_name%.boot" "%rel_dir%\start.boot" >nul
)
+@if "%1"=="help" @goto usage
@if "%1"=="install" @goto install
@if "%1"=="uninstall" @goto uninstall
@if "%1"=="start" @goto start
@@ -112,6 +126,10 @@
@if "%1"=="attach" @goto attach
@if "%1"=="remote_console" @goto attach
@if "%1"=="" @goto usage
+
+@call :is_extension "%1"
+@if "%ERRORLEVEL%"=="0" @goto run_extension
+
@echo Unknown command: "%1"
@goto :eof
@@ -135,11 +153,10 @@
:: Set the ERTS dir from erl
:set_erts_dir_from_erl
@for /f "delims=" %%i in ('where erl') do @(
- set erl=%%i
+ set "erl=%%i"
)
-@set dir_cmd="%erl%" -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop
-@for /f "delims=" %%i in ('%%dir_cmd%%') do @(
- set erl_root=%%i
+@for /f "delims=" %%i in ('"%erl%" -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop') do @(
+ set "erl_root=%%i"
)
@set "erts_dir=%erl_root%\erts-%erts_vsn%"
@set "rootdir=%erl_root%"
@@ -148,8 +165,22 @@
:: Find the sys.config file
:find_sys_config
@set "possible_sys=%rel_dir%\sys.config"
-@if exist %possible_sys% (
+@if exist "%possible_sys%" (
set sys_config=-config "%possible_sys%"
+) else (
+ @if exist "%possible_sys%.orig" (
+ ren "%possible_sys%.orig" sys.config
+ set sys_config=-config "%possible_sys%"
+ )
+)
+@goto :eof
+
+:: Find the vm.args file
+:find_vm_args
+@if not exist "%vm_args%" (
+ @if exist "%vm_args%.orig" (
+ ren "%vm_args%.orig" vm.args
+ )
)
@goto :eof
@@ -175,7 +206,63 @@
:: Display usage information
:usage
-@echo usage: %~n0 ^(install^|uninstall^|start^|stop^|restart^|upgrade^|downgrade^|console^|ping^|list^|attach^|remote_console^)
+@if "%2"=="install" (
+ @echo "Usage: %rel_name% install [VERSION]"
+ @echo "Installs a release package VERSION, it assumes that this"
+ @echo "release package tarball has already been deployed at one"
+ @echo "of the following locations:"
+ @echo " releases/<relname>-<version>.tar.gz"
+ @echo " releases/<version>/<relname>-<version>.tar.gz"
+ @echo " releases/<version>/<relname>.tar.gz"
+ @echo ""
+ @echo " --no-permanent Install release package VERSION but"
+ @echo " don't make it permanent"
+ @goto :eof
+)
+@if "%2"=="uninstall" (
+ @echo "Usage: %rel_name% uninstall [VERSION]"
+ @echo "Uninstalls a release VERSION, it will only accept"
+ @echo "versions that are not currently in use"
+ @goto :eof
+)
+@if "%2"=="upgrade" (
+ @echo "Usage: %rel_name% upgrade [VERSION]"
+ @echo "Upgrades the currently running release to VERSION, it assumes"
+ @echo "that a release package tarball has already been deployed at one"
+ @echo "of the following locations:"
+ @echo " releases/<relname>-<version>.tar.gz"
+ @echo " releases/<version>/<relname>-<version>.tar.gz"
+ @echo " releases/<version>/<relname>.tar.gz"
+ @echo ""
+ @echo " --no-permanent Install release package VERSION but"
+ @echo " don't make it permanent"
+ @goto :eof
+)
+@if "%2"=="downgrade" (
+ @echo "Usage: %rel_name% downgrade [VERSION]"
+ @echo "Downgrades the currently running release to VERSION, it assumes"
+ @echo "that a release package tarball has already been deployed at one"
+ @echo "of the following locations:"
+ @echo " releases/<relname>-<version>.tar.gz"
+ @echo " releases/<version>/<relname>-<version>.tar.gz"
+ @echo " releases/<version>/<relname>.tar.gz"
+ @echo ""
+ @echo " --no-permanent Install release package VERSION but"
+ @echo " don't make it permanent"
+ @goto :eof
+)
+@call :is_extension "%2"
+@if "%ERRORLEVEL%"=="0" (
+ @if exist "%script_dir%\extensions\%2.cmd" (
+ call "%script_dir%\extensions\%2.cmd" help
+ @goto :eof
+ )
+)
+set commands=install uninstall start stop restart upgrade downgrade console ping list attach remote_console
+if not "%extensions%"=="" (
+ set "commands=%commands% %extensions%"
+)
+@echo Usage: %~n0 ^(%commands: =^|%^)
@goto :eof
:: Install the release as a Windows service
@@ -183,10 +270,10 @@
:install
set args=%erl_opts% -setcookie %cookie% ++ -rootdir \"%rootdir%\"
set start_erl=%erts_dir%\bin\start_erl.exe
-set description=Erlang node %node_name% in %rootdir%
+set description=Erlang node %node_name%%hostname% in %rootdir%
@if "" == "%2" (
:: Install the service
- %erlsrv% add %service_name% %node_type% "%node_name%" -c "%description%" -w "%rootdir%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()."
+ %erlsrv% add %service_name% %node_type% "%node_name%%hostname%" -c "%description%" -w "%rootdir%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()."
) else (
:: relup and reldown
goto relup
@@ -243,3 +330,35 @@ set description=Erlang node %node_name% in %rootdir%
@start "%node_name% attach" %werl% %boot% ^
-remsh %node_name%%hostname% %node_type% console -setcookie %cookie%
@goto :eof
+
+:: Run extension script
+:run_extension
+@if exist "%script_dir%\extensions\%1.cmd" (
+ set _extension_params=%*
+ call set _extension_params=%%_extension_params:*%1=%%
+ call "%script_dir%\extensions\%1.cmd" %%_extension_params%%
+)
+
+@goto :eof
+
+:: Local Functions
+
+:is_extension
+
+@set "ext=%~1"
+
+:: Check for entries in the list, not at the ends
+@call set "ext_test_1=x%%extensions: %ext% =%%"
+
+:: Check for entry at the start of the list
+@call set "ext_test_2=x%%extensions:%ext% =%%"
+
+:: Check for entry at the end of the list
+@call set "ext_test_3=x%%extensions: %ext%=%%"
+
+@if not "%ext_test_1%"=="x%extensions%" exit /b 0
+@if not "%ext_test_2%"=="x%extensions%" exit /b 0
+@if not "%ext_test_3%"=="x%extensions%" exit /b 0
+
+@exit /b 1
+
diff --git a/priv/templates/nodetool b/priv/templates/nodetool
index 816be9c..9e24f32 100644
--- a/priv/templates/nodetool
+++ b/priv/templates/nodetool
@@ -8,9 +8,10 @@
%% -------------------------------------------------------------------
main(Args) ->
- ok = start_epmd(),
%% Extract the args
- {RestArgs, TargetNode} = process_args(Args, [], undefined),
+ {RestArgs, TargetNode, StartEpmd} = process_args(Args, [], undefined, true),
+
+ ok = start_epmd(StartEpmd),
%% See if the node is currently running -- if it's not, we'll bail
case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of
@@ -87,25 +88,35 @@ main(Args) ->
end,
net_kernel:stop().
-process_args([], Acc, TargetNode) ->
- {lists:reverse(Acc), TargetNode};
-process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) ->
+process_args([], Acc, TargetNode, StartEpmd) ->
+ {lists:reverse(Acc), TargetNode, StartEpmd};
+process_args(["-setcookie", Cookie | Rest], Acc, TargetNode, StartEpmd) ->
erlang:set_cookie(node(), list_to_atom(Cookie)),
- process_args(Rest, Acc, TargetNode);
-process_args(["-name", TargetName | Rest], Acc, _) ->
- ThisNode = append_node_suffix(TargetName, "_maint_"),
- {ok, _} = net_kernel:start([ThisNode, longnames]),
- process_args(Rest, Acc, nodename(TargetName));
-process_args(["-sname", TargetName | Rest], Acc, _) ->
- ThisNode = append_node_suffix(TargetName, "_maint_"),
- {ok, _} = net_kernel:start([ThisNode, shortnames]),
- process_args(Rest, Acc, nodename(TargetName));
-process_args([Arg | Rest], Acc, Opts) ->
- process_args(Rest, [Arg | Acc], Opts).
-
-
-start_epmd() ->
+ process_args(Rest, Acc, TargetNode, StartEpmd);
+process_args(["-start_epmd", StartEpmd | Rest], Acc, TargetNode, _StartEpmd) ->
+ process_args(Rest, Acc, TargetNode, list_to_atom(StartEpmd));
+process_args(["-name", TargetName | Rest], Acc, _, StartEpmd) ->
+ maybe_start_node(TargetName, longnames),
+ process_args(Rest, Acc, nodename(TargetName), StartEpmd);
+process_args(["-sname", TargetName | Rest], Acc, _, StartEpmd) ->
+ maybe_start_node(TargetName, shortnames),
+ process_args(Rest, Acc, nodename(TargetName), StartEpmd);
+process_args([Arg | Rest], Acc, Opts, StartEpmd) ->
+ process_args(Rest, [Arg | Acc], Opts, StartEpmd).
+
+maybe_start_node(TargetName, Names) ->
+ case erlang:node() of
+ 'nonode@nohost' ->
+ ThisNode = append_node_suffix(TargetName, "_maint_"),
+ {ok, _} = net_kernel:start([ThisNode, Names]);
+ _ ->
+ ok
+ end.
+
+start_epmd(true) ->
[] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"),
+ ok;
+start_epmd(_) ->
ok.
epmd_path() ->
diff --git a/rebar.config b/rebar.config
index d7f5312..285b1ce 100644
--- a/rebar.config
+++ b/rebar.config
@@ -69,7 +69,8 @@
{override, providers, [{erl_opts, [no_debug_info]}]}
]}.
-{ct_opts, [{cover_spec, "cover.spec"}]}.
+{ct_opts, [{cover_spec, "cover.spec"},
+ {ct_hooks, [cth_surefire]}]}.
{cover_enabled, true}.
{cover_print_enabled, true}.
diff --git a/src/relx.app.src b/src/relx.app.src
index c8915d5..c845982 100644
--- a/src/relx.app.src
+++ b/src/relx.app.src
@@ -1,11 +1,9 @@
{application,relx,
- [{description,"Release assembler for Erlang/OTP Releases"},
- {vsn,"git"},
- {modules,[]},
- {registered,[]},
- {applications,[kernel,stdlib,getopt,erlware_commons,bbmustache,
- providers]},
- {maintainers,["Eric Merritt","Tristan Sloughter",
- "Jordan Wilberding"]},
- {licenses,["Apache"]},
- {links,[{"Github","https://github.com/erlware/relx"}]}]}.
+ [{description,"Release assembler for Erlang/OTP Releases"},
+ {vsn,"git"},
+ {modules,[]},
+ {registered,[]},
+ {applications,[kernel,stdlib,getopt,erlware_commons,bbmustache,
+ providers]},
+ {licenses,["Apache"]},
+ {links,[{"Github","https://github.com/erlware/relx"}]}]}.
diff --git a/src/relx.erl b/src/relx.erl
index 8027fd4..b5c3ec5 100644
--- a/src/relx.erl
+++ b/src/relx.erl
@@ -214,7 +214,8 @@ opt_spec_list() ->
{sys_config, undefined, "sys_config", string, "Path to a file to use for sys.config"},
{system_libs, undefined, "system_libs", string, "Path to dir of Erlang system libs"},
{version, undefined, "version", undefined, "Print relx version"},
- {root_dir, $r, "root", string, "The project root directory"}].
+ {root_dir, $r, "root", string, "The project root directory"},
+ {provider, undefined, "provider", atom, "Specify an additional relx provider"}].
-spec format_error(Reason::term()) -> string().
format_error({invalid_return_value, Provider, Value}) ->
diff --git a/src/rlx_cmd_args.erl b/src/rlx_cmd_args.erl
index b20344c..4f5e9da 100644
--- a/src/rlx_cmd_args.erl
+++ b/src/rlx_cmd_args.erl
@@ -285,6 +285,19 @@ create(include_erts, Opts) ->
create(warnings_as_errors, Opts) ->
WarningsAsErrors = proplists:get_value(warnings_as_errors, Opts, false),
{warnings_as_errors, WarningsAsErrors};
+create(provider, Opts) ->
+ case proplists:get_all_values(provider, Opts) of
+ [] ->
+ [];
+ Providers ->
+ {add_providers, Providers}
+ end;
+create(add_providers, Opts) ->
+ Providers = proplists:get_value(add_providers, Opts, []),
+ {add_providers, Providers};
+create(providers, Opts) ->
+ Providers = proplists:get_value(providers, Opts, []),
+ {providers, Providers};
create(_, _) ->
[].
diff --git a/src/rlx_config.erl b/src/rlx_config.erl
index c67bf16..90cfe7c 100644
--- a/src/rlx_config.erl
+++ b/src/rlx_config.erl
@@ -333,8 +333,9 @@ list_of_overlay_vars_files(undefined) ->
[];
list_of_overlay_vars_files([]) ->
[];
-list_of_overlay_vars_files([H | _]=FileNames) when erlang:is_list(H) ->
- FileNames;
+list_of_overlay_vars_files([H | _]=Vars) when erlang:is_list(H) ;
+ is_tuple(H) ->
+ Vars;
list_of_overlay_vars_files(FileName) when is_list(FileName) ->
[FileName].
@@ -358,7 +359,8 @@ merge_configs([{Key, Value} | CliTerms], ConfigTerms) ->
end;
overlay_vars ->
case lists:keyfind(overlay_vars, 1, ConfigTerms) of
- {_, [H | _] = Vars} when is_list(H) ->
+ {_, [H | _] = Vars} when is_list(H) ;
+ is_tuple(H) ->
MergedValue = Vars ++ Value,
merge_configs(CliTerms, lists:keyreplace(overlay_vars, 1, ConfigTerms, {Key, MergedValue}));
{_, Vars} when is_list(Vars) ->
@@ -367,10 +369,23 @@ merge_configs([{Key, Value} | CliTerms], ConfigTerms) ->
false ->
merge_configs(CliTerms, ConfigTerms++[{Key, Value}])
end;
+ default_release when Value =:= {undefined, undefined} ->
+ %% No release specified in cli. Prevent overwriting default_release in ConfigTerms.
+ merge_configs(CliTerms, lists:keymerge(1, ConfigTerms, [{Key, Value}]));
_ ->
merge_configs(CliTerms, lists:reverse(lists:keystore(Key, 1, lists:reverse(ConfigTerms), {Key, Value})))
end.
+parse_vsn(Vsn) when Vsn =:= git ; Vsn =:= "git" ->
+ {ok, V} = ec_git_vsn:vsn(ec_git_vsn:new()),
+ V;
+parse_vsn({git, short}) ->
+ git_ref("--short");
+parse_vsn({git, long}) ->
+ git_ref("");
+parse_vsn({file, File}) ->
+ {ok, Vsn} = file:read_file(File),
+ binary_to_list(rlx_string:trim(Vsn, both, "\n"));
parse_vsn(Vsn) when Vsn =:= semver ; Vsn =:= "semver" ->
{ok, V} = ec_git_vsn:vsn(ec_git_vsn:new()),
V;
@@ -382,3 +397,20 @@ parse_vsn({cmd, Command}) ->
V;
parse_vsn(Vsn) ->
Vsn.
+
+git_ref(Arg) ->
+ case os:cmd("git rev-parse " ++ Arg ++ " HEAD") of
+ String ->
+ Vsn = rlx_string:trim(String, both, "\n"),
+ case length(Vsn) =:= 40 orelse length(Vsn) =:= 7 of
+ true ->
+ Vsn;
+ false ->
+ %% if the result isn't exactly either 40 or 7 characters then
+ %% it must have failed
+ {ok, Dir} = file:get_cwd(),
+ ec_cmd_log:warn("Getting ref of git repo failed in ~ts. "
+ "Falling back to version 0", [Dir]),
+ {plain, "0"}
+ end
+ end.
diff --git a/src/rlx_depsolver.erl b/src/rlx_depsolver.erl
index 88f2da4..0bde8c7 100644
--- a/src/rlx_depsolver.erl
+++ b/src/rlx_depsolver.erl
@@ -1,5 +1,5 @@
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
-%% ex: ts=4 sx=4 et
+%% ex: ts=4 sw=4 et
%%
%% Copyright 2012 Opscode, Inc. All Rights Reserved.
%%
diff --git a/src/rlx_depsolver_culprit.erl b/src/rlx_depsolver_culprit.erl
index cf6dcb2..6368d24 100644
--- a/src/rlx_depsolver_culprit.erl
+++ b/src/rlx_depsolver_culprit.erl
@@ -1,5 +1,5 @@
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
-%% ex: ts=4 sx=4 et
+%% ex: ts=4 sw=4 et
%%
%% @author Eric Merritt <[email protected]>
%%
diff --git a/src/rlx_prv_archive.erl b/src/rlx_prv_archive.erl
index e1735d1..8fd03c1 100644
--- a/src/rlx_prv_archive.erl
+++ b/src/rlx_prv_archive.erl
@@ -141,9 +141,10 @@ update_tar(State, TempDir, OutputDir, Name, Vsn, ErtsVersion) ->
config_files(Vsn, OutputDir) ->
VMArgs = {filename:join(["releases", Vsn, "vm.args"]), filename:join([OutputDir, "releases", Vsn, "vm.args"])},
+ VMArgsSrc = {filename:join(["releases", Vsn, "vm.args.src"]), filename:join([OutputDir, "releases", Vsn, "vm.args.src"])},
VMArgsOrig = {filename:join(["releases", Vsn, "vm.args.orig"]), filename:join([OutputDir, "releases", Vsn, "vm.args.orig"])},
SysConfigOrig = {filename:join(["releases", Vsn, "sys.config.orig"]), filename:join([OutputDir, "releases", Vsn, "sys.config.orig"])},
- [{NameInArchive, Filename} || {NameInArchive, Filename} <- [VMArgs, VMArgsOrig, SysConfigOrig], filelib:is_file(Filename)].
+ [{NameInArchive, Filename} || {NameInArchive, Filename} <- [VMArgsSrc, VMArgs, VMArgsOrig, SysConfigOrig], filelib:is_file(Filename)].
overlay_files(_, undefined, _) ->
diff --git a/src/rlx_prv_assembler.erl b/src/rlx_prv_assembler.erl
index cb5bbed..4f9a41e 100644
--- a/src/rlx_prv_assembler.erl
+++ b/src/rlx_prv_assembler.erl
@@ -433,13 +433,13 @@ write_bin_file(State, Release, OutputDir, RelDir) ->
win32 -> rlx_string:concat(VsnRel, ".cmd")
end,
ok = file:write_file(VsnRelStartFile, StartFile),
- ok = file:change_mode(VsnRelStartFile, 8#777),
+ ok = file:change_mode(VsnRelStartFile, 8#755),
BareRelStartFile = case OsFamily of
unix -> BareRel;
win32 -> rlx_string:concat(BareRel, ".cmd")
end,
ok = file:write_file(BareRelStartFile, StartFile),
- ok = file:change_mode(BareRelStartFile, 8#777)
+ ok = file:change_mode(BareRelStartFile, 8#755)
end,
ReleasesDir = filename:join(OutputDir, "releases"),
generate_start_erl_data_file(Release, ReleasesDir),
diff --git a/src/rlx_prv_overlay.erl b/src/rlx_prv_overlay.erl
index 645f691..516d238 100644
--- a/src/rlx_prv_overlay.erl
+++ b/src/rlx_prv_overlay.erl
@@ -145,7 +145,8 @@ get_overlay_vars_from_file(State, OverlayVars) ->
OverlayVars;
[] ->
OverlayVars;
- [H | _]=FileNames when is_list(H) ->
+ [H | _]=FileNames when is_list(H) ;
+ is_tuple(H) ->
read_overlay_vars(State, OverlayVars, FileNames);
FileName when is_list(FileName) ->
read_overlay_vars(State, OverlayVars, [FileName])
@@ -181,30 +182,24 @@ check_overlay_inclusion(_State, _RelativeRoot, [], Terms) ->
proplists:proplist().
merge_overlay_vars(State, FileNames) ->
RelativeRoot = get_relative_root(State),
- lists:foldl(fun(FileName, Acc) ->
- RelativePath = filename:join(RelativeRoot, erlang:iolist_to_binary(FileName)),
+ lists:foldl(fun(FileName, Acc) when is_list(FileName) ->
+ RelativePath = filename:join(RelativeRoot, iolist_to_binary(FileName)),
case file:consult(RelativePath) of
- %% {ok, [Terms]} ->
- %% lists:ukeymerge(1, lists:ukeysort(1, Terms), Acc);
- %% % the location of the included overlay files will be relative
- %% %% to the current one being read
- %% %% OverlayRelativeRoot = filename:dirname(FileName),
- %% %% NewTerms = check_overlay_inclusion(State, OverlayRelativeRoot, Terms),
-
- %% %% lists:ukeymerge(1, lists:ukeysort(1, NewTerms), Acc);
{ok, Terms} ->
%% the location of the included overlay files will be relative
%% to the current one being read
OverlayRelativeRoot = filename:dirname(FileName),
NewTerms = check_overlay_inclusion(State, OverlayRelativeRoot, Terms),
lists:foldl(fun(NewTerm, A) ->
- lists:keystore(element(1, NewTerm), 1, A, NewTerm)
+ lists:keystore(element(1, NewTerm), 1, A, NewTerm)
end, Acc, NewTerms);
{error, Reason} ->
ec_cmd_log:warn(rlx_state:log(State),
format_error({unable_to_read_varsfile, FileName, Reason})),
Acc
- end
+ end;
+ (Var, Acc) ->
+ lists:keystore(element(1, Var), 1, Acc, Var)
end, [], FileNames).
-spec render_overlay_vars(proplists:proplist(), proplists:proplist(),
diff --git a/src/rlx_string.erl b/src/rlx_string.erl
index 1f9cc0c..d5f5046 100644
--- a/src/rlx_string.erl
+++ b/src/rlx_string.erl
@@ -2,14 +2,22 @@
%% OTP-19 and OTP-21, where Unicode support means the deprecation
%% of a lot of string functions.
-module(rlx_string).
--export([concat/2, lexemes/2, join/2]).
+-export([concat/2, lexemes/2, join/2, trim/3]).
-ifdef(unicode_str).
concat(Str1, Str2) -> unicode:characters_to_list([Str1,Str2]).
lexemes(Str, Separators) -> string:lexemes(Str, Separators).
+trim(Str, Direction, Cluster=[_]) -> string:trim(Str, Direction, Cluster).
-else.
concat(Str1, Str2) -> string:concat(Str1, Str2).
lexemes(Str, Separators) -> string:tokens(Str, Separators).
+trim(Str, Direction, [Char]) ->
+ Dir = case Direction of
+ both -> both;
+ leading -> left;
+ trailing -> right
+ end,
+ string:strip(Str, Dir, Char).
-endif.
%% string:join/2 copy; string:join/2 is getting obsoleted
diff --git a/src/rlx_util.erl b/src/rlx_util.erl
index b3fc2b7..5d3744d 100644
--- a/src/rlx_util.erl
+++ b/src/rlx_util.erl
@@ -45,6 +45,8 @@
-define(DFLT_INTENSITY, high).
-define(ONE_LEVEL_INDENT, " ").
+
+-include_lib("kernel/include/file.hrl").
%%============================================================================
%% types
%%============================================================================
@@ -233,81 +235,65 @@ symlink_or_copy(Source, Target) ->
ok;
{error, eexist} ->
{error, eexist};
- {error, _} ->
- case os:type() of
- {win32, _} ->
- S = unicode:characters_to_list(Source),
- T = unicode:characters_to_list(Target),
- win32_symlink(filename:nativename(S), filename:nativename(T));
+ {error, Err} ->
+ case {os:type(), Err} of
+ {{win32, _}, eperm} ->
+ % We get eperm on Windows if we do not have
+ % SeCreateSymbolicLinkPrivilege
+ % Try the next alternative
+ win32_make_junction_or_copy(Source, Target);
_ ->
- case filelib:is_dir(Target) of
- true -> ok;
- false ->
- cp_r([Source], Target)
- end
+ % On other systems we try to copy next
+ cp_r(Source, Target)
end
end.
+cp_r(Source, Target) ->
+ ec_file:copy(Source, Target, [{recursive, true}, {fileinfo, [mode, time, owner, group]}]).
-win32_symlink(Source, Target) ->
- os:cmd("cmd /c mklink /j " ++ Target ++ " " ++ Source),
- ok.
-
--spec cp_r(list(string()), file:filename()) -> 'ok'.
-cp_r(Sources, Dest) ->
- case os:type() of
- {unix, _} ->
- ok;
- {win32, _} ->
- lists:foreach(fun(Src) -> ok = cp_r_win32(Src,Dest) end, Sources),
- ok
+win32_make_junction_or_copy(Source, Target) ->
+ case filelib:is_dir(Source) of
+ true ->
+ win32_make_junction(Source, Target);
+ _ ->
+ cp_r(Source, Target)
end.
-xcopy_win32(Source,Dest)->
- %% "xcopy \"~s\" \"~s\" /q /y /e 2> nul", Chanegd to robocopy to
- %% handle long names. May have issues with older windows.
- os:cmd("robocopy " ++ Source ++ " " ++ Dest ++ " /e /is"),
- ok.
-
-cp_r_win32({true, SourceDir}, {true, DestDir}) ->
- %% from directory to directory
- ok = case file:make_dir(DestDir) of
- {error, eexist} -> ok;
- Other -> Other
- end,
- ok = xcopy_win32(SourceDir, DestDir);
-cp_r_win32({false, Source} = S,{true, DestDir}) ->
- %% from file to directory
- cp_r_win32(S, {false, filename:join(DestDir, filename:basename(Source))});
-cp_r_win32({false, Source},{false, Dest}) ->
- %% from file to file
- {ok,_} = file:copy(Source, Dest),
- ok;
-cp_r_win32({true, SourceDir}, {false, DestDir}) ->
- case filelib:is_regular(DestDir) of
- true ->
- %% From directory to file? This shouldn't happen
- {error, lists:flatten(
- io_lib:format("Cannot copy dir (~p) to file (~p)\n",
- [SourceDir, DestDir]))};
- false ->
- %% Specifying a target directory that doesn't currently exist.
- %% So let's attempt to create this directory
- case filelib:ensure_dir(filename:join(DestDir, "dummy")) of
- ok ->
- ok = xcopy_win32(SourceDir, DestDir);
+win32_make_junction(Source, Target) ->
+ % The mklink will fail if the target already exists, check for that first
+ case file:read_link_info(Target) of
+ {error, enoent} ->
+ win32_make_junction_cmd(Source, Target);
+ {ok, #file_info{type = symlink}} ->
+ case file:read_link(Target) of
+ {ok, Source} ->
+ ok;
+ {ok, _} ->
+ ok = file:del_dir(Target),
+ win32_make_junction_cmd(Source, Target);
{error, Reason} ->
- {error, lists:flatten(
- io_lib:format("Unable to create dir ~p: ~p\n",
- [DestDir, Reason]))}
- end
- end;
-cp_r_win32(Source,Dest) ->
- Dst = {filelib:is_dir(Dest), Dest},
- lists:foreach(fun(Src) ->
- ok = cp_r_win32({filelib:is_dir(Src), Src}, Dst)
- end, filelib:wildcard(Source)),
- ok.
+ {error, {readlink, Reason}}
+ end;
+ {ok, #file_info{type = _Type}} ->
+ % Directory already exists, so we overwrite the copy
+ cp_r(Source, Target);
+ Error ->
+ Error
+ end.
+
+win32_make_junction_cmd(Source, Target) ->
+ S = unicode:characters_to_list(Source),
+ T = unicode:characters_to_list(Target),
+ Cmd = "cmd /c mklink /j " ++ filename:nativename(T) ++ " " ++ filename:nativename(S),
+ case os:cmd(Cmd) of
+ "Junction created " ++ _ ->
+ ok;
+ [] ->
+ % When mklink fails it prints the error message to stderr which
+ % is not picked up by os:cmd() hence this case switch is for
+ % an empty message
+ cp_r(Source, Target)
+ end.
%% @doc Returns the color intensity, we first check the application envorinment
%% if that is not set we check the environment variable RELX_COLOR.
diff --git a/test/rlx_archive_SUITE.erl b/test/rlx_archive_SUITE.erl
index 5122c11..8d30915 100644
--- a/test/rlx_archive_SUITE.erl
+++ b/test/rlx_archive_SUITE.erl
@@ -18,7 +18,7 @@
-include_lib("kernel/include/file.hrl").
suite() ->
- [{timetrap, {seconds, 30}}].
+ [{timetrap, {seconds, 120}}].
init_per_suite(Config) ->
Config.
@@ -55,11 +55,19 @@ basic_tar(Config) ->
rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
+ SysConfigSrc = filename:join([LibDir1, "config", "sys.config.src"]),
+ rlx_test_utils:write_config(SysConfigSrc, [{this_is_a_test, "yup it is"}]),
+
+ VmArgsSrc = filename:join([LibDir1, "config", "vm.args.src"]),
+ ec_file:write(VmArgsSrc, ""),
+
ConfigFile = filename:join([LibDir1, "relx.config"]),
rlx_test_utils:write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1,
- goal_app_2]}]),
+ goal_app_2]},
+ {sys_config_src, SysConfigSrc},
+ {vm_args_src, VmArgsSrc}]),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
rlx_test_utils:create_random_name("relx-output")]),
{ok, State} = relx:do([{relname, foo},
@@ -84,6 +92,16 @@ basic_tar(Config) ->
{ok, Files} = erl_tar:table(TarFile, [compressed]),
?assert(lists:any(fun(X) -> re:run(X, "lib/stdlib-.*/ebin/.*") =/= nomatch end, Files)),
?assert(lists:any(fun(X) -> re:run(X, "lib/kernel-.*/ebin/.*") =/= nomatch end, Files)),
+
+ %% only works in otp-21 and above
+ case erlang:system_info(otp_release) of
+ R when R =:= "21" orelse R =:= "22" ->
+ ?assert(lists:member("releases/0.0.1/vm.args.src", Files)),
+ ?assert(lists:member("releases/0.0.1/sys.config.src", Files));
+ _ ->
+ ok
+ end,
+
?assert(filelib:is_regular(TarFile)).
exclude_erts(Config) ->
diff --git a/test/rlx_command_SUITE.erl b/test/rlx_command_SUITE.erl
index e0beec1..8dd2da8 100644
--- a/test/rlx_command_SUITE.erl
+++ b/test/rlx_command_SUITE.erl
@@ -27,13 +27,14 @@
lib_expansion_case/1,
lib_fail_case/1,
spec_parse_fail_case/1,
- config_fail_case/1]).
+ config_fail_case/1,
+ provider_case/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
suite() ->
- [{timetrap,{seconds,30}}].
+ [{timetrap,{seconds,120}}].
init_per_suite(Config) ->
Config.
@@ -42,7 +43,7 @@ end_per_suite(_Config) ->
ok.
all() ->
- [normal_passing_case, lib_expansion_case, lib_fail_case, config_fail_case].
+ [normal_passing_case, lib_expansion_case, lib_fail_case, config_fail_case, provider_case].
normal_passing_case(Config) ->
DataDir = filename:join(proplists:get_value(priv_dir, Config), ?MODULE),
@@ -111,3 +112,12 @@ config_fail_case(_Config) ->
{ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
?assertMatch({error, {_, {invalid_config_file, ConfigFile}}},
rlx_cmd_args:args2state(Opts, Targets)).
+
+provider_case(_Config) ->
+ CmdLine = ["--provider", "relx_provider_1",
+ "--provider", "relx_provider_2"],
+ {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
+ {ok, State} = rlx_cmd_args:args2state(Opts, Targets),
+ ?assertEqual(
+ [relx_provider_1, relx_provider_2],
+ proplists:get_value(add_providers, rlx_state:cli_args(State))).
diff --git a/test/rlx_depsolver_tester.erl b/test/rlx_depsolver_tester.erl
index 9defd91..b3bc146 100644
--- a/test/rlx_depsolver_tester.erl
+++ b/test/rlx_depsolver_tester.erl
@@ -1,5 +1,5 @@
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 92 -*-
-%% ex: ts=4 sx=4 et
+%% ex: ts=4 sw=4 et
%%-------------------------------------------------------------------
%%
%% Copyright 2012 Opscode, Inc. All Rights Reserved.
@@ -49,153 +49,167 @@ run_log(FileName) ->
run_log_file(Device).
data1_test() ->
- ExpectedResult = versionify([{"app6","0.0.1"},
- {"dep_pkg13","0.0.2"},
- {"app13","0.0.1"},
- {"dep_pkg2","0.0.5"},
- {"dep_pkg1","0.0.2"},
+ ExpectedResult = versionify([
+ {"app9","0.0.1"},
{"dep_pkg7","0.1.2"},
- {"app9","0.0.1"}]),
+ {"dep_pkg1","0.0.2"},
+ {"dep_pkg2","0.0.5"},
+ {"app13","0.0.1"},
+ {"dep_pkg13","0.0.2"},
+ {"app6","0.0.1"}
+ ]),
?assertMatch({ok, ExpectedResult},
run_data(fix_rebar_brokenness("data1.txt"))).
data2_test() ->
- ExpectedResult = versionify([{"app18","0.0.1"},
- {"app4","0.0.7"},
- {"app1","0.0.1"},
- {"app6","0.0.1"},
- {"dep_pkg13","0.0.2"},
- {"app13","0.0.1"},
- {"dep_pkg5","0.0.3"},
- {"dep_pkg1","0.0.2"},
- {"dep_pkg2","0.0.5"},
- {"dep_pkg7","0.1.2"},
+ ExpectedResult = versionify([
+ {"dep_pkg16","1.0.2"},
{"app9","0.0.1"},
- {"dep_pkg16","1.0.2"}]),
+ {"dep_pkg7","0.1.2"},
+ {"dep_pkg2","0.0.5"},
+ {"dep_pkg1","0.0.2"},
+ {"dep_pkg5","0.0.3"},
+ {"app13","0.0.1"},
+ {"dep_pkg13","0.0.2"},
+ {"app6","0.0.1"},
+ {"app1","0.0.1"},
+ {"app4","0.0.7"},
+ {"app18","0.0.1"}
+ ]),
?assertMatch({ok, ExpectedResult},
run_data(fix_rebar_brokenness("data2.txt"))).
-
+
data3_test() ->
- ExpectedResult = versionify([{"app68","0.0.1"},
- {"app58","0.0.1"},
- {"app48","0.0.7"},
- {"app38","0.0.1"},
- {"app28","0.0.1"},
- {"app18","0.0.1"},
- {"app4","0.0.7"},
- {"app1","0.0.1"},
- {"app6","0.0.1"},
- {"dep_pkg13","0.0.2"},
- {"app13","0.0.1"},
- {"dep_pkg5","0.0.3"},
- {"dep_pkg1","0.0.2"},
- {"dep_pkg2","0.0.5"},
- {"dep_pkg7","0.1.2"},
+ ExpectedResult = versionify([
+ {"dep_pkg16","1.0.2"},
{"app9","0.0.1"},
- {"dep_pkg16","1.0.2"}]),
+ {"dep_pkg7","0.1.2"},
+ {"dep_pkg2","0.0.5"},
+ {"dep_pkg1","0.0.2"},
+ {"dep_pkg5","0.0.3"},
+ {"app13","0.0.1"},
+ {"dep_pkg13","0.0.2"},
+ {"app6","0.0.1"},
+ {"app1","0.0.1"},
+ {"app4","0.0.7"},
+ {"app18","0.0.1"},
+ {"app28","0.0.1"},
+ {"app38","0.0.1"},
+ {"app48","0.0.7"},
+ {"app58","0.0.1"},
+ {"app68","0.0.1"}
+ ]),
?assertMatch({ok,ExpectedResult}, run_data(fix_rebar_brokenness("data3.txt"))).
data4_test() ->
- ExpectedResult = versionify([{"dep_pkg20","0.0.2"},
- {"app78","0.0.1"},
- {"app68","0.0.1"},
- {"app58","0.0.1"},
- {"app48","0.0.7"},
- {"app38","0.0.1"},
- {"app28","0.0.1"},
- {"app18","0.0.1"},
- {"app4","0.0.7"},
- {"app1","0.0.1"},
- {"app6","0.0.1"},
- {"dep_pkg13","0.0.2"},
- {"app13","0.0.1"},
- {"dep_pkg5","0.0.3"},
- {"dep_pkg1","0.0.2"},
- {"dep_pkg2","0.0.5"},
- {"dep_pkg7","0.1.2"},
+ ExpectedResult = versionify([
+ {"dep_pkg16","1.0.2"},
{"app9","0.0.1"},
- {"dep_pkg16","1.0.2"}]),
+ {"dep_pkg7","0.1.2"},
+ {"dep_pkg2","0.0.5"},
+ {"dep_pkg1","0.0.2"},
+ {"dep_pkg5","0.0.3"},
+ {"app13","0.0.1"},
+ {"dep_pkg13","0.0.2"},
+ {"app6","0.0.1"},
+ {"app1","0.0.1"},
+ {"app4","0.0.7"},
+ {"app18","0.0.1"},
+ {"app28","0.0.1"},
+ {"app38","0.0.1"},
+ {"app48","0.0.7"},
+ {"app58","0.0.1"},
+ {"app68","0.0.1"},
+ {"app78","0.0.1"},
+ {"dep_pkg20","0.0.2"}
+ ]),
?assertMatch({ok, ExpectedResult},
run_data(fix_rebar_brokenness("data4.txt"))).
data5_test() ->
- ExpectedResult = versionify([{"dep_pkg14","0.0.2"},
- {"dep_pkg22","0.0.2"},
- {"dep_pkg20","0.0.2"},
- {"app78","0.0.1"},
- {"app68","0.0.1"},
- {"app58","0.0.1"},
- {"app48","0.0.7"},
- {"app38","0.0.1"},
- {"app28","0.0.1"},
- {"app18","0.0.1"},
- {"app4","0.0.7"},
- {"app1","0.0.1"},
- {"app6","0.0.1"},
- {"dep_pkg13","0.0.2"},
- {"app13","0.0.1"},
- {"dep_pkg5","0.0.3"},
- {"dep_pkg1","0.0.2"},
- {"dep_pkg2","0.0.5"},
- {"dep_pkg7","0.1.2"},
+ ExpectedResult = versionify([
+ {"dep_pkg16","1.0.2"},
{"app9","0.0.1"},
- {"dep_pkg16","1.0.2"}]),
+ {"dep_pkg7","0.1.2"},
+ {"dep_pkg2","0.0.5"},
+ {"dep_pkg1","0.0.2"},
+ {"dep_pkg5","0.0.3"},
+ {"app13","0.0.1"},
+ {"dep_pkg13","0.0.2"},
+ {"app6","0.0.1"},
+ {"app1","0.0.1"},
+ {"app4","0.0.7"},
+ {"app18","0.0.1"},
+ {"app28","0.0.1"},
+ {"app38","0.0.1"},
+ {"app48","0.0.7"},
+ {"app58","0.0.1"},
+ {"app68","0.0.1"},
+ {"app78","0.0.1"},
+ {"dep_pkg20","0.0.2"},
+ {"dep_pkg22","0.0.2"},
+ {"dep_pkg14","0.0.2"}
+ ]),
?assertMatch({ok, ExpectedResult},
run_data(fix_rebar_brokenness("data5.txt"))).
data6_test() ->
- ExpectedResult = versionify([{"app108","0.0.1"},
- {"app98","0.0.1"},
- {"app88","0.0.1"},
- {"dep_pkg14","0.0.2"},
- {"dep_pkg22","0.0.2"},
- {"dep_pkg20","0.0.2"},
- {"app78","0.0.1"},
- {"app68","0.0.1"},
- {"app58","0.0.1"},
- {"app48","0.0.7"},
- {"app38","0.0.1"},
- {"app28","0.0.1"},
- {"app18","0.0.1"},
- {"app4","0.0.7"},
- {"app1","0.0.1"},
- {"app6","0.0.1"},
- {"dep_pkg13","0.0.2"},
- {"app13","0.0.1"},
- {"dep_pkg5","0.0.3"},
- {"dep_pkg1","0.0.2"},
- {"dep_pkg2","0.0.5"},
- {"dep_pkg7","0.1.2"},
+ ExpectedResult = versionify([
+ {"dep_pkg16","1.0.2"},
{"app9","0.0.1"},
- {"dep_pkg16","1.0.2"}]),
+ {"dep_pkg7","0.1.2"},
+ {"dep_pkg2","0.0.5"},
+ {"dep_pkg1","0.0.2"},
+ {"dep_pkg5","0.0.3"},
+ {"app13","0.0.1"},
+ {"dep_pkg13","0.0.2"},
+ {"app6","0.0.1"},
+ {"app1","0.0.1"},
+ {"app4","0.0.7"},
+ {"app18","0.0.1"},
+ {"app28","0.0.1"},
+ {"app38","0.0.1"},
+ {"app48","0.0.7"},
+ {"app58","0.0.1"},
+ {"app68","0.0.1"},
+ {"app78","0.0.1"},
+ {"dep_pkg20","0.0.2"},
+ {"dep_pkg22","0.0.2"},
+ {"dep_pkg14","0.0.2"},
+ {"app88","0.0.1"},
+ {"app98","0.0.1"},
+ {"app108","0.0.1"}
+ ]),
?assertMatch({ok, ExpectedResult},
run_data(fix_rebar_brokenness("data6.txt"))).
log_07be9e47_test() ->
Data = run_log(fix_rebar_brokenness("log-07be9e47-6f42-4a5d-b8b5-1d2eae1ad83b.txt")),
- ExpectedResult = versionify([{"0","0"},
- {"1","0"},
- {"3","0"},
- {"4","0"},
- {"5","0"},
- {"6","0"},
- {"7","0"},
- {"8","0"},
- {"9","0"},
- {"10","0"},
- {"11","0"},
- {"12","0"},
- {"13","0"},
- {"14","0"},
- {"15","0"},
- {"16","0"},
- {"18","0"},
- {"19","0"},
- {"21","0"},
- {"22","0"},
- {"23","0"},
+ ExpectedResult = versionify([
+ {"25","0"},
{"24","0"},
- {"25","0"}]),
+ {"23","0"},
+ {"22","0"},
+ {"21","0"},
+ {"19","0"},
+ {"18","0"},
+ {"16","0"},
+ {"15","0"},
+ {"14","0"},
+ {"13","0"},
+ {"12","0"},
+ {"11","0"},
+ {"10","0"},
+ {"9","0"},
+ {"8","0"},
+ {"7","0"},
+ {"6","0"},
+ {"5","0"},
+ {"4","0"},
+ {"3","0"},
+ {"1","0"},
+ {"0","0"}
+ ]),
?assertMatch({ok, ExpectedResult},
Data).
@@ -206,144 +220,152 @@ log_183998c1_test() ->
log_311a15e7_test() ->
{ok, Data} = run_log(fix_rebar_brokenness("log-311a15e7-3378-4c5b-beb7-86a1b9cf0ea9.txt")),
- ExpectedResult = lists:sort(versionify([{"45", "22"},
- {"40","1"},
- {"3","5"},
- {"9","0"},
- {"8","0"},
- {"7","0"},
- {"6","2"},
- {"1","5"},
- {"0","2"},
- {"61","1"},
- {"60","0"},
- {"35","4"},
- {"39","0"},
- {"38","2"},
- {"37","2"},
- {"36","3"},
- {"32","24"},
- {"30","0"},
- {"19","1"},
- {"18","0"},
- {"17","2"},
- {"16","0"},
- {"15","0"},
- {"14","1"},
- {"13","0"},
- {"12","1"},
- {"11","0"},
- {"10","1"},
- {"59","0"},
- {"58","1"},
- {"57","0"},
- {"56","0"},
- {"55","4"},
- {"29","2"},
- {"27","2"},
- {"26","0"},
- {"25","5"},
- {"24","3"},
- {"23","1"},
- {"22","3"},
+ ExpectedResult = lists:sort(versionify([
+ {"20","0"},
{"21","2"},
- {"20","0"}])),
+ {"22","3"},
+ {"23","1"},
+ {"24","3"},
+ {"25","5"},
+ {"26","0"},
+ {"27","2"},
+ {"29","2"},
+ {"55","4"},
+ {"56","0"},
+ {"57","0"},
+ {"58","1"},
+ {"59","0"},
+ {"10","1"},
+ {"11","0"},
+ {"12","1"},
+ {"13","0"},
+ {"14","1"},
+ {"15","0"},
+ {"16","0"},
+ {"17","2"},
+ {"18","0"},
+ {"19","1"},
+ {"30","0"},
+ {"32","24"},
+ {"36","3"},
+ {"37","2"},
+ {"38","2"},
+ {"39","0"},
+ {"35","4"},
+ {"60","0"},
+ {"61","1"},
+ {"0","2"},
+ {"1","5"},
+ {"6","2"},
+ {"7","0"},
+ {"8","0"},
+ {"9","0"},
+ {"3","5"},
+ {"40","1"},
+ {"45", "22"}
+ ])),
?assertMatch(ExpectedResult, lists:sort(Data)).
log_382cfe5b_test() ->
{ok, Data} =
run_log(fix_rebar_brokenness("log-382cfe5b-0ac2-48b8-83d1-717cb4620990.txt")),
- ExpectedResult = lists:sort(versionify([{"18","0"},
- {"17","0"},
- {"15","1"},
- {"14","0"},
- {"10","0"},
- {"7","0"},
- {"6","0"},
- {"5","0"},
- {"4","0"},
- {"3","0"},
- {"2","1"},
+ ExpectedResult = lists:sort(versionify([
+ {"0","0"},
{"1","0"},
- {"0","0"}])),
+ {"2","1"},
+ {"3","0"},
+ {"4","0"},
+ {"5","0"},
+ {"6","0"},
+ {"7","0"},
+ {"10","0"},
+ {"14","0"},
+ {"15","1"},
+ {"17","0"},
+ {"18","0"}
+ ])),
?assertMatch(ExpectedResult, lists:sort(Data)).
log_d3564ef6_test() ->
{ok, Data} = run_log(fix_rebar_brokenness("log-d3564ef6-6437-41e7-90b6-dbdb849551a6_mod.txt")),
- ExpectedResult = lists:sort(versionify([{"57","5"},
- {"56","3"},
- {"55","4"},
- {"54","0"},
- {"53","1"},
- {"82","0"},
- {"81","0"},
- {"80","1"},
- {"29","0"},
- {"28","5"},
- {"27","3"},
- {"26","1"},
- {"25","3"},
- {"24","2"},
- {"23","0"},
- {"22","1"},
- {"21","0"},
- {"20","2"},
- {"75","32"},
- {"79","2"},
- {"78","4"},
- {"74","7"},
- {"73","11"},
- {"72","0"},
- {"70","1"},
- {"47","4"},
- {"45","1"},
- {"44","1"},
- {"43","7"},
- {"42","1"},
- {"41","2"},
- {"40","2"},
- {"19","0"},
- {"18","0"},
- {"17","1"},
- {"16","0"},
- {"15","1"},
- {"14","0"},
- {"13","1"},
- {"12","0"},
- {"11","0"},
- {"10","0"},
- {"9","2"},
- {"4","5"},
- {"3","2"},
- {"0","3"},
- {"69","0"},
- {"68","1"},
- {"67","7"},
- {"39","3"},
- {"35","24"},
- {"33","0"},
+ ExpectedResult = lists:sort(versionify([
+ {"30","2"},
{"32","2"},
- {"30","2"}])),
+ {"33","0"},
+ {"35","24"},
+ {"39","3"},
+ {"67","7"},
+ {"68","1"},
+ {"69","0"},
+ {"0","3"},
+ {"3","2"},
+ {"4","5"},
+ {"9","2"},
+ {"10","0"},
+ {"11","0"},
+ {"12","0"},
+ {"13","1"},
+ {"14","0"},
+ {"15","1"},
+ {"16","0"},
+ {"17","1"},
+ {"18","0"},
+ {"19","0"},
+ {"40","2"},
+ {"41","2"},
+ {"42","1"},
+ {"43","7"},
+ {"44","1"},
+ {"45","1"},
+ {"47","4"},
+ {"70","1"},
+ {"72","0"},
+ {"73","11"},
+ {"74","7"},
+ {"78","4"},
+ {"79","2"},
+ {"75","32"},
+ {"20","2"},
+ {"21","0"},
+ {"22","1"},
+ {"23","0"},
+ {"24","2"},
+ {"25","3"},
+ {"26","1"},
+ {"27","3"},
+ {"28","5"},
+ {"29","0"},
+ {"80","1"},
+ {"81","0"},
+ {"82","0"},
+ {"53","1"},
+ {"54","0"},
+ {"55","4"},
+ {"56","3"},
+ {"57","5"}
+ ])),
?assertMatch(ExpectedResult, lists:sort(Data)).
log_ea2d264b_test() ->
{ok, Data} = run_log(fix_rebar_brokenness("log-ea2d264b-003e-4611-94ed-14efc7732083.txt")),
- ExpectedResult = lists:sort(versionify([{"18","1"},
- {"17","0"},
- {"16","0"},
- {"15","0"},
- {"14","0"},
- {"13","1"},
- {"10","1"},
- {"9","1"},
- {"8","2"},
- {"6","0"},
- {"5","0"},
- {"4","0"},
- {"3","0"},
- {"2","0"},
+ ExpectedResult = lists:sort(versionify([
+ {"0","1"},
{"1","0"},
- {"0","1"}])),
+ {"2","0"},
+ {"3","0"},
+ {"4","0"},
+ {"5","0"},
+ {"6","0"},
+ {"8","2"},
+ {"9","1"},
+ {"10","1"},
+ {"13","1"},
+ {"14","0"},
+ {"15","0"},
+ {"16","0"},
+ {"17","0"},
+ {"18","1"}
+ ])),
?assertMatch(ExpectedResult, lists:sort(Data)).
%%============================================================================
diff --git a/test/rlx_depsolver_tests.erl b/test/rlx_depsolver_tests.erl
index 206bad4..b1c8228 100644
--- a/test/rlx_depsolver_tests.erl
+++ b/test/rlx_depsolver_tests.erl
@@ -1,5 +1,5 @@
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
-%% ex: ts=4 sx=4 et
+%% ex: ts=4 sw=4 et
%%
%%-------------------------------------------------------------------
%% Copyright 2012 Opscode, Inc. All Rights Reserved.
diff --git a/test/rlx_discover_SUITE.erl b/test/rlx_discover_SUITE.erl
index 36d77ae..9385229 100644
--- a/test/rlx_discover_SUITE.erl
+++ b/test/rlx_discover_SUITE.erl
@@ -34,7 +34,7 @@
-include_lib("eunit/include/eunit.hrl").
suite() ->
- [{timetrap,{seconds,30}}].
+ [{timetrap,{seconds,120}}].
init_per_suite(Config) ->
Config.
diff --git a/test/rlx_eunit_SUITE.erl b/test/rlx_eunit_SUITE.erl
index 874e5a6..c7c0751 100644
--- a/test/rlx_eunit_SUITE.erl
+++ b/test/rlx_eunit_SUITE.erl
@@ -30,7 +30,7 @@
-include_lib("eunit/include/eunit.hrl").
suite() ->
- [{timetrap,{seconds,30}}].
+ [{timetrap,{seconds,120}}].
init_per_suite(Config) ->
Config.
diff --git a/test/rlx_extended_bin_SUITE.erl b/test/rlx_extended_bin_SUITE.erl
index 86a9d23..8444cb4 100644
--- a/test/rlx_extended_bin_SUITE.erl
+++ b/test/rlx_extended_bin_SUITE.erl
@@ -49,6 +49,7 @@
replace_os_vars_dev_mode/1,
replace_os_vars_twice/1,
custom_start_script_hooks/1,
+ custom_start_script_hooks_console/1,
builtin_wait_for_vm_start_script_hook/1,
builtin_pid_start_script_hook/1,
builtin_wait_for_process_start_script_hook/1,
@@ -62,8 +63,10 @@
-include_lib("eunit/include/eunit.hrl").
-include_lib("kernel/include/file.hrl").
+-define(SLEEP_TIME, 2500).
+
suite() ->
- [{timetrap,{seconds,30}}].
+ [{timetrap,{seconds,300}}].
init_per_suite(Config) ->
Config.
@@ -83,12 +86,13 @@ init_per_testcase(_, Config) ->
all() ->
[start_sname_in_other_argsfile, start_preserves_arguments, start_nodetool_with_data_from_argsfile,
start_upgrade_escript_with_argsfile_data, start_fail_when_no_name, start_fail_when_multiple_names,
- start_fail_when_missing_argsfile, start_fail_when_nonreadable_argsfile,
+ start_fail_when_missing_argsfile, %% start_fail_when_nonreadable_argsfile,
start_fail_when_relative_argsfile, start_fail_when_circular_argsfiles,
ping, shortname_ping, longname_ping, attach, pid, restart, reboot, escript,
remote_console, shortname_remote_console, replace_os_vars, replace_os_vars_sys_config_vm_args_src, replace_os_vars_multi_node,
replace_os_vars_included_config,
- replace_os_vars_custom_location, replace_os_vars_dev_mode, replace_os_vars_twice, custom_start_script_hooks,
+ replace_os_vars_custom_location, replace_os_vars_dev_mode, replace_os_vars_twice,
+ custom_start_script_hooks, custom_start_script_hooks_console,
builtin_wait_for_vm_start_script_hook, builtin_pid_start_script_hook,
builtin_wait_for_process_start_script_hook, mixed_custom_and_builtin_start_script_hooks,
builtin_status_script, custom_status_script,
@@ -122,7 +126,7 @@ ping(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
%% a ping should fail after stopping a node
@@ -145,7 +149,7 @@ shortname_ping(Config) ->
{extended_start_script, true}
]),
- ec_file:write(VmArgs, "-sname foo\n\n"
+ ec_file:write(VmArgs, "-sname foo@localhost\n\n"
"-setcookie cookie\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -161,7 +165,7 @@ shortname_ping(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
%% a ping should fail after stopping a node
@@ -184,7 +188,7 @@ longname_ping(Config) ->
{extended_start_script, true}
]),
- ec_file:write(VmArgs, "-name foo\n\n"
+ ec_file:write(VmArgs, "-name [email protected]\n\n"
"-setcookie cookie\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -200,7 +204,7 @@ longname_ping(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
%% a ping should fail after stopping a node
@@ -233,10 +237,10 @@ attach(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo attach", "&"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
{error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
@@ -267,7 +271,7 @@ pid(Config) ->
%% check for a valid pid
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _Pid} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
@@ -301,11 +305,11 @@ restart(Config) ->
%% a restart is a gracious operation that does not involve the
%% death of the VM, so the pid should be the same
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, Pid1} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo restart"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, Pid2} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
{error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
@@ -339,13 +343,13 @@ reboot(Config) ->
%% a reboot involves stopping the emulator, it needs to be restarted
%% though
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, Pid1} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo reboot"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, Pid2} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
{error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
@@ -381,7 +385,7 @@ escript(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
[ExpectedOutput] = io_lib:format("~s",
[filename:join([OutputDir, "foo"])]),
@@ -415,10 +419,10 @@ remote_console(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo remote_console &"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, NodesStr} = sh(filename:join([OutputDir, "foo", "bin", "foo eval 'nodes(connected).'"])),
Nodes = rlx_test_utils:list_to_term(NodesStr),
?assertEqual(1, length(Nodes)),
@@ -432,7 +436,7 @@ shortname_remote_console(Config) ->
ConfigFile = filename:join([LibDir1, "relx.config"]),
VmArgs = filename:join([LibDir1, "vm.args"]),
- ec_file:write(VmArgs, "-sname foo\n\n"
+ ec_file:write(VmArgs, "-sname foo@localhost\n\n"
"-setcookie cookie\n"),
rlx_test_utils:write_config(ConfigFile,
@@ -457,10 +461,10 @@ shortname_remote_console(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo remote_console &"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, NodesStr} = sh(filename:join([OutputDir, "foo", "bin", "foo eval 'nodes(connected).'"])),
Nodes = rlx_test_utils:list_to_term(NodesStr),
?assertEqual(1, length(Nodes)),
@@ -489,7 +493,7 @@ replace_os_vars(Config) ->
[[{goal_app,
[{var1, "${VAR1}"},
{var2, "${VAR2}"}]}]]),
- ec_file:write(VmArgs, "-sname ${NODENAME}\n\n"
+ ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n"
"-setcookie ${COOKIE}\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -508,7 +512,7 @@ replace_os_vars(Config) ->
{"NODENAME", "node1"},
{"COOKIE", "cookie1"},
{"VAR1", "v1"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node1"},
@@ -547,7 +551,7 @@ replace_os_vars(Config) ->
{"NODENAME", "node2"},
{"COOKIE", "cookie2"},
{"VAR1", "v2"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node2"},
@@ -604,7 +608,7 @@ replace_os_vars_sys_config_vm_args_src(Config) ->
%% new with sys.config.src it doesn't have to be valid Erlang
%% until after var replacemen at runtime.
ec_file:write(SysConfigSrc, "[{goal_app, [{var1, ${VAR1}}]}]."),
- ec_file:write(VmArgs, "-sname ${NODENAME}\n\n"
+ ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n"
"-setcookie ${COOKIE}\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -623,7 +627,7 @@ replace_os_vars_sys_config_vm_args_src(Config) ->
{"NODENAME", "node1"},
{"COOKIE", "cookie1"},
{"VAR1", "101"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node1"},
@@ -662,7 +666,7 @@ replace_os_vars_sys_config_vm_args_src(Config) ->
{"NODENAME", "node2"},
{"COOKIE", "cookie2"},
{"VAR1", "201"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node2"},
@@ -717,7 +721,7 @@ replace_os_vars_multi_node(Config) ->
rlx_test_utils:write_config(SysConfig,
[[{goal_app, [{var1, "${VAR1}"}]}]]),
- ec_file:write(VmArgs, "-sname ${NODENAME}\n\n"
+ ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n"
"-setcookie ${COOKIE}\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -737,7 +741,7 @@ replace_os_vars_multi_node(Config) ->
{"NODENAME", "node1"},
{"COOKIE", "cookie1"},
{"VAR1", "v1"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"RELX_MULTI_NODE", "1"},
@@ -785,7 +789,7 @@ replace_os_vars_multi_node(Config) ->
{"NODENAME", "node2"},
{"COOKIE", "cookie2"},
{"VAR1", "v2"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"RELX_MULTI_NODE", "1"},
@@ -862,7 +866,7 @@ replace_os_vars_included_config(Config) ->
},
"releases/0.0.1/config/included.config"]
]),
- ec_file:write(VmArgs, "-sname ${NODENAME}\n\n"
+ ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n"
"-setcookie ${COOKIE}\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -881,7 +885,7 @@ replace_os_vars_included_config(Config) ->
{"NODENAME", "node1"},
{"COOKIE", "cookie1"},
{"VAR1", "v1"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node1"},
@@ -920,7 +924,7 @@ replace_os_vars_included_config(Config) ->
{"NODENAME", "node2"},
{"COOKIE", "cookie2"},
{"VAR1", "v2"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node2"},
@@ -975,7 +979,7 @@ replace_os_vars_custom_location(Config) ->
rlx_test_utils:write_config(SysConfig,
[[{goal_app, [{var1, "${VAR1}"}]}]]),
- ec_file:write(VmArgs, "-sname ${NODENAME}\n\n"
+ ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n"
"-setcookie ${COOKIE}\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -995,7 +999,7 @@ replace_os_vars_custom_location(Config) ->
{"NODENAME", "node1"},
{"COOKIE", "cookie1"},
{"VAR1", "v1"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"RELX_OUT_FILE_PATH", "/tmp"},
@@ -1041,7 +1045,7 @@ replace_os_vars_custom_location(Config) ->
{"NODENAME", "node2"},
{"COOKIE", "cookie2"},
{"VAR1", "v2"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"RELX_OUT_FILE_PATH", "/tmp"},
@@ -1102,7 +1106,7 @@ replace_os_vars_twice(Config) ->
rlx_test_utils:write_config(SysConfig,
[[{goal_app, [{var1, "${VAR1}"}]}]]),
- ec_file:write(VmArgs, "-sname node\n\n"
+ ec_file:write(VmArgs, "-sname node@localhost\n\n"
"-setcookie cookie\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -1119,7 +1123,7 @@ replace_os_vars_twice(Config) ->
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"VAR1", "v1"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"}]),
{ok, "\"v1\""} = sh(filename:join([OutputDir, "foo", "bin",
@@ -1142,7 +1146,7 @@ replace_os_vars_twice(Config) ->
%% start the node again but this time don't replace env variables
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, "\"${VAR1}\""} = sh(filename:join([OutputDir, "foo", "bin",
"foo eval '{ok, V} = application:get_env(goal_app, var1), V.'"])),
@@ -1175,7 +1179,7 @@ replace_os_vars_dev_mode(Config) ->
rlx_test_utils:write_config(SysConfig,
[[{goal_app, [{var1, "${VAR1}"}]}]]),
- ec_file:write(VmArgs, "-sname ${NODENAME}\n\n"
+ ec_file:write(VmArgs, "-sname ${NODENAME}@localhost\n\n"
"-setcookie ${COOKIE}\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -1194,7 +1198,7 @@ replace_os_vars_dev_mode(Config) ->
{"NODENAME", "node1"},
{"COOKIE", "cookie1"},
{"VAR1", "v1"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node1"},
@@ -1233,7 +1237,7 @@ replace_os_vars_dev_mode(Config) ->
{"NODENAME", "node2"},
{"COOKIE", "cookie2"},
{"VAR1", "v2"}]),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"]),
[{"RELX_REPLACE_OS_VARS", "1"},
{"NODENAME", "node2"},
@@ -1318,7 +1322,7 @@ custom_start_script_hooks(Config) ->
%% now start/stop the release to make sure the script hooks are really getting
%% executed
os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
os:cmd(filename:join([OutputDir, "foo", "bin", "foo stop"])),
%% now check that the output file contains the expected format
{ok,[{pre_start, foo, _, foo},
@@ -1359,6 +1363,42 @@ builtin_pid_start_script_hook(Config) ->
os:cmd(filename:join([OutputDir, "foo", "bin", "foo stop"])),
ok.
+custom_start_script_hooks_console(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+
+ rlx_test_utils:create_app(LibDir1, "goal_app", "0.0.1", [stdlib,kernel], []),
+
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
+ rlx_test_utils:write_config(ConfigFile,
+ [{release, {foo, "0.0.1"},
+ [goal_app]},
+ {lib_dirs, [filename:join(LibDir1, "*")]},
+ {generate_start_script, true},
+ {extended_start_script, true},
+ {extended_start_script_hooks, [
+ {pre_start, [
+ {custom, "hooks/pre_start"}
+ ]}
+ ]},
+ {mkdir, "scripts"},
+ {overlay, [{copy, "./pre_start", "bin/hooks/pre_start"}]}
+ ]),
+
+ %% write the hook scripts, each of them will write an erlang term to a file
+ %% that will later be consulted
+ ok = file:write_file(filename:join([LibDir1, "./pre_start"]),
+ "#!/bin/bash\n# $*\necho \\{pre_start, $REL_NAME, \\'$NAME\\', $COOKIE\\}. >> test"),
+
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
+ rlx_test_utils:create_random_name("relx-output")]),
+ {ok, _State} = relx:do(foo, undefined, [], [LibDir1], 3,
+ OutputDir, ConfigFile),
+ %% now start/stop the release to make sure the script hooks are really getting
+ %% executed
+ {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo console &"])),
+ %% now check that the output file contains the expected format
+ {ok,[{pre_start, foo, _, foo}]} = file:consult(filename:join([OutputDir, "foo", "test"])).
+
builtin_wait_for_vm_start_script_hook(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -1385,7 +1425,7 @@ builtin_wait_for_vm_start_script_hook(Config) ->
os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])),
% this run doesn't need the sleep because the wait_for_vm_start
% start script makes it unnecessary
- %timer:sleep(2000),
+ %timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
os:cmd(filename:join([OutputDir, "foo", "bin", "foo stop"])),
ok.
@@ -1521,7 +1561,7 @@ builtin_status_script(Config) ->
{ok, _State} = relx:do(foo, undefined, [], [LibDir1], 3,
OutputDir, ConfigFile),
os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
%% write the status to a file
{ok, ""} = sh(filename:join([OutputDir, "foo", "bin", "foo status"])).
@@ -1558,7 +1598,7 @@ custom_status_script(Config) ->
{ok, _State} = relx:do(foo, undefined, [], [LibDir1], 3,
OutputDir, ConfigFile),
os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
%% write the status to a file
{ok, StatusStr} = sh(filename:join([OutputDir, "foo", "bin", "foo status"])),
@@ -1588,7 +1628,7 @@ start_sname_in_other_argsfile(Config) ->
ec_file:write(VmArgs, "-args_file " ++ VmArgs2 ++ "\n\n"
"-setcookie cookie\n"),
- ec_file:write(VmArgs2, "-sname foo\n"),
+ ec_file:write(VmArgs2, "-sname foo@localhost\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
rlx_test_utils:create_random_name("relx-output")]),
@@ -1603,7 +1643,7 @@ start_sname_in_other_argsfile(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
%% a ping should fail after stopping a node
@@ -1639,7 +1679,7 @@ start_preserves_arguments(Config) ->
%% and preserving the "tricky" argument that contains a string with a space
%% in it
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start -goal_app baz '\"bat zing\"'"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
BinFile = filename:join([PrivDir, "goal_app.bin"]),
Eval = io_lib:format("{ok,Env}=application:get_env(goal_app,baz),file:write_file(\"~s\",term_to_binary(Env)).",
[BinFile]),
@@ -1670,7 +1710,7 @@ start_nodetool_with_data_from_argsfile(Config) ->
]),
ec_file:write(VmArgs, "-setcookie cookie\n"
- "-sname foo\n\n"
+ "-sname foo@localhost\n\n"
"-proto_dist inet_tcp\n\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -1686,7 +1726,7 @@ start_nodetool_with_data_from_argsfile(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
%% a ping should fail after stopping a node
@@ -1710,7 +1750,7 @@ start_upgrade_escript_with_argsfile_data(Config) ->
]),
ec_file:write(VmArgs, "-setcookie cookie\n"
- "-sname foo\n\n"
+ "-sname foo@localhost\n\n"
"-proto_dist inet_tcp\n\n"),
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
@@ -1726,7 +1766,7 @@ start_upgrade_escript_with_argsfile_data(Config) ->
%% now start/stop the release to make sure the extended script is working
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, _Ver} = sh(filename:join([OutputDir, "foo", "bin", "foo versions"])),
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
%% a ping should fail after stopping a node
@@ -1758,7 +1798,7 @@ start_fail_when_nonreadable_argsfile(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
VmArgs = filename:join([LibDir1, "vm.args"]),
VmArgs2 = VmArgs ++ ".nonreadable",
- ec_file:write(VmArgs, "-name foo\n\n"
+ ec_file:write(VmArgs, "-name [email protected]\n\n"
"-args_file " ++ VmArgs2 ++ "\n\n"
"-setcookie cookie\n"),
ec_file:write(VmArgs2, ""),
@@ -1794,7 +1834,7 @@ extension_script(Config) ->
proplists:get_value(priv_dir, Config),
ExtensionScript),
os:cmd(filename:join([OutputDir, "foo", "bin", "foo start"])),
- timer:sleep(2000),
+ timer:sleep(?SLEEP_TIME),
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
%% write the extension script output to a file
{ok, Str} = sh(filename:join([OutputDir, "foo", "bin", "foo bar"])),
diff --git a/test/rlx_prv_release_alias.erl b/test/rlx_prv_release_alias.erl
new file mode 100644
index 0000000..523940c
--- /dev/null
+++ b/test/rlx_prv_release_alias.erl
@@ -0,0 +1,27 @@
+-module(rlx_prv_release_alias).
+
+-behaviour(provider).
+
+-export([init/1, do/1, format_error/1]).
+
+-define(PROVIDER, test_release_alias).
+-define(DEPS, [app_discover]).
+
+%%============================================================================
+%% API
+%%============================================================================
+
+-spec init(rlx_state:t()) -> {ok, rlx_state:t()}.
+init(State) ->
+ State1 = rlx_state:add_provider(State, providers:create([{name, ?PROVIDER},
+ {module, ?MODULE},
+ {deps, ?DEPS}])),
+ {ok, State1}.
+
+-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
+do(State) ->
+ rlx_prv_release:do(State).
+
+-spec format_error(ErrorDetail::term()) -> iolist().
+format_error(ErrorDetail) ->
+ rlx_prv_release:format_error(ErrorDetail).
diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl
index f0c10c3..3d77732 100644
--- a/test/rlx_release_SUITE.erl
+++ b/test/rlx_release_SUITE.erl
@@ -25,7 +25,9 @@
init_per_testcase/2,
all/0,
providers/1,
+ providers_via_api_options/1,
add_providers/1,
+ add_providers_via_api_options/1,
make_release/1,
make_config_release/1,
make_extend_release/1,
@@ -65,7 +67,7 @@
-include_lib("kernel/include/file.hrl").
suite() ->
- [{timetrap,{seconds,30}}].
+ [{timetrap,{seconds,120}}].
init_per_suite(Config) ->
Config.
@@ -83,19 +85,18 @@ init_per_testcase(_, Config) ->
{state, State1} | Config].
all() ->
- [providers, add_providers, make_release, make_config_release,
- make_extend_release, make_extend_config_release, make_scriptless_release,
- make_overridden_release, make_auto_skip_empty_app_release,
+ [providers, providers_via_api_options, add_providers, add_providers_via_api_options,
+ make_release, make_config_release, make_extend_release, make_extend_config_release,
+ make_scriptless_release, make_overridden_release, make_auto_skip_empty_app_release,
make_skip_app_release, make_exclude_app_release, make_app_type_none_release,
- make_implicit_config_release, make_rerun_overridden_release,
- overlay_release, make_goalless_release, make_external_goal_release, make_depfree_release,
- make_invalid_config_release, make_relup_release, make_relup_release2,
- make_one_app_top_level_release, make_dev_mode_release, make_dev_mode_template_release,
- make_config_script_release, make_release_twice, make_release_twice_dev_mode,
- make_erts_release, make_erts_config_release,
- make_included_nodetool_release, make_not_included_nodetool_release,
- make_src_release, make_excluded_src_release, make_exclude_modules_release,
- make_release_with_sys_config_vm_args_src].
+ make_implicit_config_release, make_rerun_overridden_release, overlay_release,
+ make_goalless_release, make_external_goal_release, make_depfree_release, make_invalid_config_release,
+ make_relup_release, make_relup_release2, make_one_app_top_level_release,
+ make_dev_mode_release, make_dev_mode_template_release, make_config_script_release,
+ make_release_twice, make_release_twice_dev_mode, make_erts_release,
+ make_erts_config_release, make_included_nodetool_release,
+ make_not_included_nodetool_release, make_src_release, make_excluded_src_release,
+ make_exclude_modules_release, make_release_with_sys_config_vm_args_src].
add_providers(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -134,6 +135,52 @@ add_providers(Config) ->
?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+add_providers_via_api_options(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+
+ [(fun({Name, Vsn}) ->
+ rlx_test_utils:create_app(LibDir1, Name, Vsn, [kernel, stdlib], [])
+ end)(App)
+ ||
+ App <-
+ [{rlx_test_utils:create_random_name("lib_app1_"), rlx_test_utils:create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+
+ rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []),
+ rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []),
+ rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
+ rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
+
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
+ rlx_test_utils:write_config(ConfigFile,
+ [{release, {foo, "0.0.1"},
+ [goal_app_1,
+ goal_app_2]}]),
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
+ rlx_test_utils:create_random_name("relx-output")]),
+ {ok, Cwd} = file:get_cwd(),
+ Opts = [{relname, undefined},
+ {relvsn, undefined},
+ {goals, []},
+ {overrides, []},
+ {output_dir, OutputDir},
+ {lib_dirs, [LibDir1]},
+ {root_dir, Cwd},
+ {log_level, 3},
+ {config, ConfigFile},
+ {add_providers, [rlx_prv_release_alias]}],
+ {ok, State} = relx:do(Opts, ["test_release_alias"]),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
+ ?assert(lists:keymember(stdlib, 1, AppSpecs)),
+ ?assert(lists:keymember(kernel, 1, AppSpecs)),
+ ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+
providers(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -171,6 +218,52 @@ providers(Config) ->
?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+providers_via_api_options(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+
+ [(fun({Name, Vsn}) ->
+ rlx_test_utils:create_app(LibDir1, Name, Vsn, [kernel, stdlib], [])
+ end)(App)
+ ||
+ App <-
+ [{rlx_test_utils:create_random_name("lib_app1_"), rlx_test_utils:create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+
+ rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []),
+ rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []),
+ rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
+ rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
+
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
+ rlx_test_utils:write_config(ConfigFile,
+ [{release, {foo, "0.0.1"},
+ [goal_app_1,
+ goal_app_2]}]),
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
+ rlx_test_utils:create_random_name("relx-output")]),
+ {ok, Cwd} = file:get_cwd(),
+ Opts = [{relname, undefined},
+ {relvsn, undefined},
+ {goals, []},
+ {overrides, []},
+ {output_dir, OutputDir},
+ {lib_dirs, [LibDir1]},
+ {root_dir, Cwd},
+ {log_level, 3},
+ {config, ConfigFile},
+ {providers, [rlx_prv_release_alias]}],
+ {ok, State} = relx:do(Opts, ["test_release_alias"]),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
+ ?assert(lists:keymember(stdlib, 1, AppSpecs)),
+ ?assert(lists:keymember(kernel, 1, AppSpecs)),
+ ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+
make_release(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -666,8 +759,10 @@ overlay_release(Config) ->
TestFileFull = filename:join(TestDirFull, TestFile),
SecondTestDir = "second_test_dir",
rlx_test_utils:write_config(ConfigFile,
- [{overlay_vars, [OverlayVars1, OverlayVars2, OverlayVars4]},
+ [{overlay_vars, [{var_list_dir, "non-file-variable-list"},
+ OverlayVars1, OverlayVars2, OverlayVars4]},
{overlay, [{mkdir, "{{target_dir}}/fooo"},
+ {mkdir, "{{target_dir}}/{{var_list_dir}}"},
{copy, OverlayVars1,
"{{target_dir}}/{{foo_dir}}/vars1.config"},
{copy, OverlayVars1,
@@ -728,6 +823,7 @@ overlay_release(Config) ->
?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)),
+ ?assert(ec_file:exists(filename:join([OutputDir, "foo", "non-file-variable-list"]))),
?assert(ec_file:exists(filename:join([OutputDir, "foo", "fooo"]))),
?assert(ec_file:exists(filename:join([OutputDir, "foo", "foodir", "vars1.config"]))),
?assert(ec_file:exists(filename:join([OutputDir, "foo", "yahoo", "vars1.config"]))),