Add command cli

Add command cli

#!/bin/sh

set -e

# Path to this script
SCRIPT=$(readlink $0 || true)
if [ -z $SCRIPT ]; then
    SCRIPT=$0
fi;
# Parent directory of this script
SCRIPT_DIR="$(cd `dirname "$SCRIPT"` && pwd -P)"
# Root directory of all releases
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd -P)"
# Name of the release
REL_NAME="<%= release_name %>"
# Current version of the release
REL_VSN="<%= release_version %>"
# Current version of ERTS being used
ERTS_VSN="<%= erts_vsn %>"
# VM code loading mode, embedded by default, can also be interactive
# See http://erlang.org/doc/man/code.html
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
# Directory containing the current version of this release
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
# The lib directory for this release
REL_LIB_DIR="$RELEASE_ROOT_DIR/lib"
# Options passed to erl
ERL_OPTS="<%= release.profile.erl_opts %>"
# When stdout is piped to a file, this is the directory those files will
# be stored in. defaults to /log in the release root directory
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}"
# A string of extra options to pass to erl, here for plugins
EXTRA_OPTS=""

# Pre-start/stop event hook paths
PRE_START_HOOK="$REL_DIR/hooks/pre_start"
POST_START_HOOK="$REL_DIR/hooks/post_start"
PRE_STOP_HOOK="$REL_DIR/hooks/pre_stop"
POST_STOP_HOOK="$REL_DIR/hooks/post_stop"

# Get node pid
get_pid() {
    if output="$(nodetool rpcterms os getpid)"
    then
        echo "$output" | sed -e 's/"//g'
        return 0
    else
        echo "$output"
        return 1
    fi
}

# Generate a unique nodename
gen_nodename() {
    id="longname$(gen_id)-${NAME}"
    "$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
}

# Generate a random id
gen_id() {
    od -t x -N 4 /dev/urandom | head -n1 | awk '{print $2}'
}

# Control a node
# Use like `nodetool "ping"`
nodetool() {
    command="$1"; shift

    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
                            -setcookie "$COOKIE" "$command" $@
}

# Run an escript in the node's environment
# Use like `escript "path/to/escript"`
escript() {
    shift; scriptpath="$1"; shift
    export RELEASE_ROOT_DIR

    "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
}

# Private. For setting ERTS_DIR and ROOTDIR
_find_erts_dir() {
    __erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
    if [ -d "$__erts_dir" ]; then
        ERTS_DIR="$__erts_dir";
        ROOTDIR="$RELEASE_ROOT_DIR"
    else
        __erl="$(which erl)"
        code="io:format(\"~s\", [code:root_dir()]), halt()."
        __erl_root="$("$__erl" -noshell -eval "$code")"
        ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
        ROOTDIR="$__erl_root"
    fi
}

# Private. Open a shell on a remote node
_rem_sh() {
    # Generate a unique id used to allow multiple remsh to the same node
    # transparently
    id="remsh$(gen_id)-${NAME}"

    # Get the node's ticktime so that we use the same thing.
    TICKTIME="$(nodetool rpcterms net_kernel get_net_ticktime)"

    # Setup remote shell command to control node
    if [ ! -z "$USE_ERL_SHELL" ]; then
        exec "$BINDIR/erl" \
            -hidden \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            "$NAME_TYPE" "$id" -remsh "$NAME" -setcookie "$COOKIE"
    else
        exec "$BINDIR/erl" \
            -pa "$ROOTDIR"/lib/*/ebin -pa "$CONSOLIDATED_DIR" \
            -hidden -noshell \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            -user Elixir.IEx.CLI "$NAME_TYPE" "$id" -setcookie "$COOKIE" \
            -extra --no-halt +iex -"$NAME_TYPE" "$id" --cookie "$COOKIE" --remsh "$NAME"
    fi
}

# Output a start command for the last argument of run_erl
_start_command() {
    printf "exec \"%s\" \"%s\" -- %s %s" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
           "$START_OPTION" "${ARGS}" "${EXTRA_OPTS}"
}

# Allow override of where to look for config files
# By default it's $CWD/
if [ -z "$RELEASE_CONFIG_DIR" ]; then
    RELEASE_CONFIG_DIR="$RELEASE_ROOT_DIR"
fi

# Set VMARGS_PATH, the path to the vm.args file to use
# Use $RELEASE_CONFIG_DIR/vm.args if exists, otherwise releases/VSN/vm.args
if [ -z "$VMARGS_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/vm.args" ]; then
        VMARGS_PATH="$RELEASE_CONFIG_DIR/vm.args"
    else
        VMARGS_PATH="$REL_DIR/vm.args"
    fi
fi

orig_vmargs_path="$VMARGS_PATH.orig"
if [ $REPLACE_OS_VARS ]; then
    #Make sure we don't break dev mode by keeping the symbolic link to
    #the user's vm.args
    if [ ! -L "$orig_vmargs_path" ]; then
       #we're in copy mode, rename the vm.args file to vm.args.orig
       mv "$VMARGS_PATH" "$orig_vmargs_path"
    fi

    awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_vmargs_path" > "$VMARGS_PATH"
 else
    #We don't need to replace env. vars, just rename the
    #symlink vm.args.orig to vm.args, and keep it as a
    #symlink.
    if [ -L "$orig_vmargs_path" ]; then
       mv "$orig_vmargs_path" "$VMARGS_PATH"
    fi
fi

# Make sure log directory exists
mkdir -p "$RUNNER_LOG_DIR"

# Set SYS_CONFIG_PATH, the path to the sys.config file to use
# Use $RELEASE_CONFIG_DIR/sys.config if exists, otherwise releases/VSN/sys.config
if [ -z "$SYS_CONFIG_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
fi

orig_sys_config_path="$SYS_CONFIG_PATH.orig"
if [ $REPLACE_OS_VARS ]; then
    #Make sure we don't break dev mode by keeping the symbolic link to
    #the user's sys.config
    if [ ! -L "$orig_sys_config_path" ]; then
       #We're in copy mode, rename sys.config to sys.config.orig
       mv "$SYS_CONFIG_PATH" "$orig_sys_config_path"
    fi

    awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_sys_config_path" > "$SYS_CONFIG_PATH"
 else
    #We don't need to replace env. vars, just rename the
    #symlink sys.config.orig to sys.config. Keep it as
    #a symlink.
    if [ -L "$orig_sys_config_path" ]; then
       mv "$orig_sys_config_path"  "$SYS_CONFIG_PATH"
    fi
fi

# Extract the target node name from node.args
# Should be `-sname somename` or `-name somename@somehost`
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
if [ -z "$NAME_ARG" ]; then
    echo "vm.args needs to have either -name or -sname parameter."
    exit 1
fi

# Extract the name type and name from the NAME_ARG for REMSH
# NAME_TYPE should be -name or -sname
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
# NAME will be either `somename` or `somename@somehost`
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"

# Where the pipe will be stored when using `start`
# This is used so you can attach the running application to the current
# shell using `attach`
PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}"

# Extract the target 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
        printf "a secret cookie must be provided in one of the following ways:\n  - with vm.args using the -setcookie parameter,\n  or\n  by writing the cookie to '$DEFAULT_COOKIE_FILE', with permissions set to 0400"
        exit 1
    fi
else
    # Extract cookie name from COOKIE_ARG
    COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
fi

_find_erts_dir
export ROOTDIR="$RELEASE_ROOT_DIR"
export BINDIR="$ERTS_DIR/bin"
export EMU="beam"
export PROGNAME="erl"
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
ERTS_LIB_DIR="$ERTS_DIR/../lib"
CONSOLIDATED_DIR="$ROOTDIR/lib/${REL_NAME}-${REL_VSN}/consolidated"

cd "$ROOTDIR"

# 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@$(gen_nodename)
        ;;
esac

# Check the first argument for instructions
case "$1" in
    start|start_boot)

        # Make sure there is not already a node running
        #RES=`$NODETOOL ping`
        #if [ "$RES" = "pong" ]; then
        #    echo "Node is already running!"
        #    exit 1
        #fi
        # Save this for later.
        CMD=$1
        case "$1" in
            start)
                shift
                START_OPTION="console"
                HEART_OPTION="start"
                ;;
            start_boot)
                shift
                START_OPTION="console_boot"
                HEART_OPTION="start_boot"
                ;;
        esac
        ARGS="$@"
        RUN_PARAM="$@"

        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Set arguments for the heart command
        set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
        [ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"

        # Export the HEART_COMMAND
        HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD"
        export HEART_COMMAND

        mkdir -p "$PIPE_DIR"

        "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
                          "$(_start_command)"

        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        ;;

    stop)
        [ -f "$PRE_STOP_HOOK" ] && . "$PRE_STOP_HOOK"
        # Wait for the node to completely stop...
        PID="$(get_pid)"
        if ! nodetool "stop"; then
            exit 1
        fi
        while $(kill -s 0 "$PID" 2>/dev/null);
        do
            sleep 1
        done
        [ -f "$POST_STOP_HOOK" ] && . "$POST_STOP_HOOK"
        ;;

    restart)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM without exiting the process
        if ! nodetool "restart"; then
            exit 1
        fi
        ;;

    reboot)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM completely (uses heart to restart it)
        if ! nodetool "reboot"; then
            exit 1
        fi
        ;;

    pid)
        ## Get the VM's pid
        if ! get_pid; then
            exit 1
        fi
        ;;

    ping)
        ## See if the VM is alive
        if ! nodetool "ping"; then
            exit 1
        fi
        ;;

    escript)
        ## Run an escript under the node's environment
        if ! escript $@; then
            exit 1
        fi
        ;;

    attach)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;

    remote_console)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        _rem_sh
        ;;

    upgrade|downgrade|install)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "install" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    unpack)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "unpack" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    console|console_clean|console_boot)
        # .boot file typically just $REL_NAME (ie, the app name)
        # however, for debugging, sometimes start_clean.boot is useful.
        # For e.g. 'setup', one may even want to name another boot script.
        case "$1" in
            console)
                if [ -f "$REL_DIR/$REL_NAME.boot" ]; then
                  BOOTFILE="$REL_DIR/$REL_NAME"
                else
                  BOOTFILE="$REL_DIR/start"
                fi
                ;;
            console_clean)
                BOOTFILE="$ROOTDIR/bin/start_clean"
                ;;
            console_boot)
                shift
                BOOTFILE="$1"
                shift
                ;;
        esac
        # Setup beam-required vars
        EMU="beam"
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre_start hook along
        # the way. We can't run the post_start hook because
        # the console will crash with no TTY attached
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" \
            -boot "$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -user Elixir.IEx.CLI \
            -extra --no-halt +iex

        # Dump environment info for logging purposes
        echo "Exec: $@" -- ${1+$ARGS} ${EXTRA_OPTS}
        echo "Root: $ROOTDIR"

        # Log the startup
        echo "$RELEASE_ROOT_DIR"
        logger -t "$REL_NAME[$$]" "Starting up"

        exec "$@" -- ${1+$ARGS} ${EXTRA_OPTS}
        ;;

    foreground)
        # start up the release in the foreground for use by runit
        # or other supervision services

        [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
        FOREGROUNDOPTIONS="-noshell -noinput +Bd"

        # Setup beam-required vars
        EMU=beam
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre and post start hooks
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
            -boot "$REL_DIR/$BOOTFILE" -mode "$CODE_LOADING_MODE" -config "$SYS_CONFIG_PATH" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -args_file "$VMARGS_PATH" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            ${ERL_OPTS} \
            -extra ${EXTRA_OPTS}

        # Dump environment info for logging purposes
        echo "Exec: $@" -- ${1+$ARGS}
        echo "Root: $ROOTDIR"

        trap '{}' QUIT TERM KILL HUP SIGUSR1 SIGUSR2
        "$@" -- ${1+$ARGS} &
        __bg_pid=$!
        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        wait $__bg_pid
        ;;
    rpc)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpc $@
        ;;
    rpcterms)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpcterms $@
        ;;
    eval)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        nodetool "eval" $@
        ;;
    command)
        # Execute as command-line utility
        #
        # Like the escript command, this does not start the OTP application.
        # If your command depends on a running OTP application,
        # use
        #
        #     {:ok, _} = Application.ensure_all_started(:your_app)

        shift
        MODULE="$1"; shift
        FUNCTION="$1"; shift

        # Save extra arguments
        ARGS="$@"

        # Build arguments for erlexec
        set -- "$ERL_OPTS"
        [ "$SYS_CONFIG" ] && set -- "$@" -config "$SYS_CONFIG_PATH"
        set -- "$@" -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR"
        set -- "$@" -noshell
        set -- "$@" -boot start_clean
        set -- "$@" -s "$MODULE" "$FUNCTION"

        $BINDIR/erlexec $@ -extra $ARGS
        exit "$?"
        ;;
    *)
        __command_path="$REL_DIR/commands/$1"
        if [ -f "$__command_path" ]; then
            . "$__command_path"
        else
            echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|escript|rpc|rpcterms|eval|command <module> <function> <args>}"
            exit 1
        fi
        ;;
esac

exit 0

#!/bin/sh

set -e

# Path to this script
SCRIPT=$(readlink $0 || true)
if [ -z $SCRIPT ]; then
    SCRIPT=$0
fi;
# Parent directory of this script
SCRIPT_DIR="$(cd `dirname "$SCRIPT"` && pwd -P)"
# Root directory of all releases
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd -P)"
# Name of the release
REL_NAME="<%= release_name %>"
# Current version of the release
REL_VSN="<%= release_version %>"
# Current version of ERTS being used
ERTS_VSN="<%= erts_vsn %>"
# VM code loading mode, embedded by default, can also be interactive
# See http://erlang.org/doc/man/code.html
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
# Directory containing the current version of this release
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
# The lib directory for this release
REL_LIB_DIR="$RELEASE_ROOT_DIR/lib"
# Options passed to erl
ERL_OPTS="<%= release.profile.erl_opts %>"
# When stdout is piped to a file, this is the directory those files will
# be stored in. defaults to /log in the release root directory
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}"
# A string of extra options to pass to erl, here for plugins
EXTRA_OPTS=""

# Pre-start/stop event hook paths
PRE_START_HOOK="$REL_DIR/hooks/pre_start"
POST_START_HOOK="$REL_DIR/hooks/post_start"
PRE_STOP_HOOK="$REL_DIR/hooks/pre_stop"
POST_STOP_HOOK="$REL_DIR/hooks/post_stop"

# Get node pid
get_pid() {
    if output="$(nodetool rpcterms os getpid)"
    then
        echo "$output" | sed -e 's/"//g'
        return 0
    else
        echo "$output"
        return 1
    fi
}

# Generate a unique nodename
gen_nodename() {
    id="longname$(gen_id)-${NAME}"
    "$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
}

# Generate a random id
gen_id() {
    od -t x -N 4 /dev/urandom | head -n1 | awk '{print $2}'
}

# Control a node
# Use like `nodetool "ping"`
nodetool() {
    command="$1"; shift

    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
                            -setcookie "$COOKIE" "$command" $@
}

# Run an escript in the node's environment
# Use like `escript "path/to/escript"`
escript() {
    shift; scriptpath="$1"; shift
    export RELEASE_ROOT_DIR

    "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
}

# Private. For setting ERTS_DIR and ROOTDIR
_find_erts_dir() {
    __erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
    if [ -d "$__erts_dir" ]; then
        ERTS_DIR="$__erts_dir";
        ROOTDIR="$RELEASE_ROOT_DIR"
    else
        __erl="$(which erl)"
        code="io:format(\"~s\", [code:root_dir()]), halt()."
        __erl_root="$("$__erl" -noshell -eval "$code")"
        ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
        ROOTDIR="$__erl_root"
    fi
}

# Private. Open a shell on a remote node
_rem_sh() {
    # Generate a unique id used to allow multiple remsh to the same node
    # transparently
    id="remsh$(gen_id)-${NAME}"

    # Get the node's ticktime so that we use the same thing.
    TICKTIME="$(nodetool rpcterms net_kernel get_net_ticktime)"

    # Setup remote shell command to control node
    if [ ! -z "$USE_ERL_SHELL" ]; then
        exec "$BINDIR/erl" \
            -hidden \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            "$NAME_TYPE" "$id" -remsh "$NAME" -setcookie "$COOKIE"
    else
        exec "$BINDIR/erl" \
            -pa "$ROOTDIR"/lib/*/ebin -pa "$CONSOLIDATED_DIR" \
            -hidden -noshell \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            -user Elixir.IEx.CLI "$NAME_TYPE" "$id" -setcookie "$COOKIE" \
            -extra --no-halt +iex -"$NAME_TYPE" "$id" --cookie "$COOKIE" --remsh "$NAME"
    fi
}

# Output a start command for the last argument of run_erl
_start_command() {
    printf "exec \"%s\" \"%s\" -- %s %s" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
           "$START_OPTION" "${ARGS}" "${EXTRA_OPTS}"
}

# Allow override of where to look for config files
# By default it's $CWD/
if [ -z "$RELEASE_CONFIG_DIR" ]; then
    RELEASE_CONFIG_DIR="$RELEASE_ROOT_DIR"
fi

# Set VMARGS_PATH, the path to the vm.args file to use
# Use $RELEASE_CONFIG_DIR/vm.args if exists, otherwise releases/VSN/vm.args
if [ -z "$VMARGS_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/vm.args" ]; then
        VMARGS_PATH="$RELEASE_CONFIG_DIR/vm.args"
    else
        VMARGS_PATH="$REL_DIR/vm.args"
    fi
fi

orig_vmargs_path="$VMARGS_PATH.orig"
if [ $REPLACE_OS_VARS ]; then
    #Make sure we don't break dev mode by keeping the symbolic link to
    #the user's vm.args
    if [ ! -L "$orig_vmargs_path" ]; then
       #we're in copy mode, rename the vm.args file to vm.args.orig
       mv "$VMARGS_PATH" "$orig_vmargs_path"
    fi

    awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_vmargs_path" > "$VMARGS_PATH"
 else
    #We don't need to replace env. vars, just rename the
    #symlink vm.args.orig to vm.args, and keep it as a
    #symlink.
    if [ -L "$orig_vmargs_path" ]; then
       mv "$orig_vmargs_path" "$VMARGS_PATH"
    fi
fi

# Make sure log directory exists
mkdir -p "$RUNNER_LOG_DIR"

# Set SYS_CONFIG_PATH, the path to the sys.config file to use
# Use $RELEASE_CONFIG_DIR/sys.config if exists, otherwise releases/VSN/sys.config
if [ -z "$SYS_CONFIG_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
fi

orig_sys_config_path="$SYS_CONFIG_PATH.orig"
if [ $REPLACE_OS_VARS ]; then
    #Make sure we don't break dev mode by keeping the symbolic link to
    #the user's sys.config
    if [ ! -L "$orig_sys_config_path" ]; then
       #We're in copy mode, rename sys.config to sys.config.orig
       mv "$SYS_CONFIG_PATH" "$orig_sys_config_path"
    fi

    awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_sys_config_path" > "$SYS_CONFIG_PATH"
 else
    #We don't need to replace env. vars, just rename the
    #symlink sys.config.orig to sys.config. Keep it as
    #a symlink.
    if [ -L "$orig_sys_config_path" ]; then
       mv "$orig_sys_config_path"  "$SYS_CONFIG_PATH"
    fi
fi

# Extract the target node name from node.args
# Should be `-sname somename` or `-name somename@somehost`
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
if [ -z "$NAME_ARG" ]; then
    echo "vm.args needs to have either -name or -sname parameter."
    exit 1
fi

# Extract the name type and name from the NAME_ARG for REMSH
# NAME_TYPE should be -name or -sname
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
# NAME will be either `somename` or `somename@somehost`
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"

# Where the pipe will be stored when using `start`
# This is used so you can attach the running application to the current
# shell using `attach`
PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}"

# Extract the target 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
        printf "a secret cookie must be provided in one of the following ways:\n  - with vm.args using the -setcookie parameter,\n  or\n  by writing the cookie to '$DEFAULT_COOKIE_FILE', with permissions set to 0400"
        exit 1
    fi
else
    # Extract cookie name from COOKIE_ARG
    COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
fi

_find_erts_dir
export ROOTDIR="$RELEASE_ROOT_DIR"
export BINDIR="$ERTS_DIR/bin"
export EMU="beam"
export PROGNAME="erl"
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
ERTS_LIB_DIR="$ERTS_DIR/../lib"
CONSOLIDATED_DIR="$ROOTDIR/lib/${REL_NAME}-${REL_VSN}/consolidated"

cd "$ROOTDIR"

# 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@$(gen_nodename)
        ;;
esac

# Check the first argument for instructions
case "$1" in
    start|start_boot)

        # Make sure there is not already a node running
        #RES=`$NODETOOL ping`
        #if [ "$RES" = "pong" ]; then
        #    echo "Node is already running!"
        #    exit 1
        #fi
        # Save this for later.
        CMD=$1
        case "$1" in
            start)
                shift
                START_OPTION="console"
                HEART_OPTION="start"
                ;;
            start_boot)
                shift
                START_OPTION="console_boot"
                HEART_OPTION="start_boot"
                ;;
        esac
        ARGS="$@"
        RUN_PARAM="$@"

        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Set arguments for the heart command
        set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
        [ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"

        # Export the HEART_COMMAND
        HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD"
        export HEART_COMMAND

        mkdir -p "$PIPE_DIR"

        "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
                          "$(_start_command)"

        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        ;;

    stop)
        [ -f "$PRE_STOP_HOOK" ] && . "$PRE_STOP_HOOK"
        # Wait for the node to completely stop...
        PID="$(get_pid)"
        if ! nodetool "stop"; then
            exit 1
        fi
        while $(kill -s 0 "$PID" 2>/dev/null);
        do
            sleep 1
        done
        [ -f "$POST_STOP_HOOK" ] && . "$POST_STOP_HOOK"
        ;;

    restart)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM without exiting the process
        if ! nodetool "restart"; then
            exit 1
        fi
        ;;

    reboot)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM completely (uses heart to restart it)
        if ! nodetool "reboot"; then
            exit 1
        fi
        ;;

    pid)
        ## Get the VM's pid
        if ! get_pid; then
            exit 1
        fi
        ;;

    ping)
        ## See if the VM is alive
        if ! nodetool "ping"; then
            exit 1
        fi
        ;;

    escript)
        ## Run an escript under the node's environment
        if ! escript $@; then
            exit 1
        fi
        ;;

    attach)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;

    remote_console)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        _rem_sh
        ;;

    upgrade|downgrade|install)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "install" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    unpack)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "unpack" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    console|console_clean|console_boot)
        # .boot file typically just $REL_NAME (ie, the app name)
        # however, for debugging, sometimes start_clean.boot is useful.
        # For e.g. 'setup', one may even want to name another boot script.
        case "$1" in
            console)
                if [ -f "$REL_DIR/$REL_NAME.boot" ]; then
                  BOOTFILE="$REL_DIR/$REL_NAME"
                else
                  BOOTFILE="$REL_DIR/start"
                fi
                ;;
            console_clean)
                BOOTFILE="$ROOTDIR/bin/start_clean"
                ;;
            console_boot)
                shift
                BOOTFILE="$1"
                shift
                ;;
        esac
        # Setup beam-required vars
        EMU="beam"
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre_start hook along
        # the way. We can't run the post_start hook because
        # the console will crash with no TTY attached
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" \
            -boot "$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -user Elixir.IEx.CLI \
            -extra --no-halt +iex

        # Dump environment info for logging purposes
        echo "Exec: $@" -- ${1+$ARGS} ${EXTRA_OPTS}
        echo "Root: $ROOTDIR"

        # Log the startup
        echo "$RELEASE_ROOT_DIR"
        logger -t "$REL_NAME[$$]" "Starting up"

        exec "$@" -- ${1+$ARGS} ${EXTRA_OPTS}
        ;;

    foreground)
        # start up the release in the foreground for use by runit
        # or other supervision services

        [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
        FOREGROUNDOPTIONS="-noshell -noinput +Bd"

        # Setup beam-required vars
        EMU=beam
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre and post start hooks
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
            -boot "$REL_DIR/$BOOTFILE" -mode "$CODE_LOADING_MODE" -config "$SYS_CONFIG_PATH" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -args_file "$VMARGS_PATH" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            ${ERL_OPTS} \
            -extra ${EXTRA_OPTS}

        # Dump environment info for logging purposes
        echo "Exec: $@" -- ${1+$ARGS}
        echo "Root: $ROOTDIR"

        trap '{}' QUIT TERM KILL HUP SIGUSR1 SIGUSR2
        "$@" -- ${1+$ARGS} &
        __bg_pid=$!
        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        wait $__bg_pid
        ;;
    rpc)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpc $@
        ;;
    rpcterms)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpcterms $@
        ;;
    eval)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        nodetool "eval" $@
        ;;
    *)
        __command_path="$REL_DIR/commands/$1"
        if [ -f "$__command_path" ]; then
            . "$__command_path"
        else
            echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|escript|rpc|rpcterms|eval}"
            exit 1
        fi
        ;;
esac

exit 0


Fixes if statements

Fixes if statements

"exists" was used instead of "exist".

:: This batch file handles managing an Erlang node as a Windows service.
::
:: Check the :usage section for information about what this script provides

@echo off

:: Set variables that describe the release
set rel_name=<%= release_name %>
set rel_vsn=<%= release_version %>
set erts_vsn=<%= erts_vsn %>
set erl_opts=<%= erl_opts %>

:: Discover the release root directory from the directory
:: of this script
set script_dir=%~dp0
for %%A in ("%script_dir%\..\..") do (
  set release_root_dir=%%~fA
)
set rel_dir=%release_root_dir%\releases\%rel_vsn%

if "%RELEASE_MUTABLE_DIR%"=="" (
  set mutable_dir=%release_root_dir%\var
) else (
  set mutable_dir=%RELEASE_MUTABLE_DIR%
)

if "%RELEASE_CONFIG_DIR%"=="" (
  set config_dir=%release_root_dir%
) else (
  set config_dir=%RELEASE_CONFIG_DIR%
)

set log_dir=%mutable_dir%\log

:: Create directories which don't exist
if not exist %mutable_dir% mkdir %mutable_dir%
if not exist %config_dir% mkdir %config_dir%
if not exist %log_dir% mkdir %log_dir%

call :find_erts_dir
call :find_sys_config
call :find_vm_args
call :set_boot_script_var

set service_name=%rel_name%_%rel_vsn%
set bindir=%erts_dir%\bin
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 consolidated_dir=%rootdir%\lib\%rel_name%-%rel_vsn%\consolidated
set hook_dir=%rel_dir%\hooks
set command_dir=%rel_dir%\commands

:: Extract node type and name from vm.args
for /f "usebackq tokens=1-2" %%I in (`findstr /b "\-name \-sname" "%vm_args%"`) do (
  set node_type=%%I
  set node_name=%%J
)

:: Extract cookie from vm.args
for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do (
  set cookie=%%J
)

:: Write the erl.ini file to set up paths relative to this script
call :write_ini

:: If a start.boot file is not present, copy one from the named .boot file
if not exist "%rel_dir%\start.boot" (
  copy "%rel_dir%\%rel_name%.boot" "%rel_dir%\start.boot" >nul
)

set taskname="%1"
shift /1
set args=

setlocal EnableDelayedExpansion
:parse_args
set param=%1
if "!param!"=="" goto :args_parsed
if "!args!"=="" (
  set largs=%param%
) else (
  set largs=%largs% %param%
)
set "delim= "
shift /1
goto :parse_args
:args_parsed
endlocal & set args=%largs%

if %taskname%=="install" goto install
if %taskname%=="uninstall" goto uninstall
if %taskname%=="start" goto start
if %taskname%=="foreground" goto foreground
if %taskname%=="console" goto console
if %taskname%=="stop" goto stop
if %taskname%=="restart" call :stop && goto start
if %taskname%=="reboot" call :stop && goto start
if %taskname%=="reload_config" goto reload_config
if %taskname%=="upgrade" goto upgrade
if %taskname%=="downgrade" goto upgrade
if %taskname%=="attach" goto remote_console
if %taskname%=="remote_console" goto remote_console
if %taskname%=="pid" goto pid
if %taskname%=="ping" goto ping
if %taskname%=="pingpeer" goto pingpeer
if %taskname%=="escript" goto escript
if %taskname%=="rpc" goto rpc
if %taskname%=="rpcterms" goto rpcterms
if %taskname%=="eval" goto eval
if %taskname%=="command" goto command
if %taskname%=="describe" goto describe
if %taskname%=="" goto usage
if exist "%command_dir%\%taskname%" (
  "%command_dir%\%taskname%" %*
) else (
  echo Unknown command: %taskname%
)
goto :eof

:: Find the ERTS dir
:find_erts_dir
if "%erts_vsn%"=="" (
  call :use_system_erts
) else (
  call :use_bundled_erts
)
goto :eof

:: Load system ERTS info
:use_system_erts
for /f "delims=" %%i in ('where erl') do set system_erl="%%i"
if %system_erl%=="" (
  echo failed to locate the Erlang Runtime System!
  exit 1
)
set system_root_dir_cmd=%system_erl% -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop
for /f "delims=" %%i in (`%%system_root_dir_cmd%%`) do set system_root=%%i
set system_erts_vsn_cmd=%system_erl% -noshell -eval "Ver=erlang:system_info(version),io:format(\"~s\", [Ver])" -s init stop
for /f "delims=" %%i in (`%%system_erts_vsn_cmd%%`) do set system_erts_vsn=%%i
set erl=%system_erl%
set erts_vsn=%system_erts_vsn%
set rootdir=%system_root%
set erts_dir=%rootdir%\erts-%erts_vsn%
goto :eof

:: Load bundled ERTS info
:use_bundled_erts
set erts_dir=%release_root_dir%\erts-%erts_vsn%
set erl=%erts_dir%\bin\erl
set rootdir=%release_root_dir%
goto :eof

:: Find the sys.config file
:find_sys_config
set possible_sys=%release_config_dir%\sys.config
if exist %possible_sys% (
  set sys_config_src=%possible_sys%
) else (
  set sys_config_src=%rel_dir%\sys.config
)
set sys_config_target=%config_dir%\sys.config
:: Replace environment variables
powershell -command "$content = get-content %sys_config_src%; [regex]::matches($content, '\${[\w\d_-]+}') | foreach { $content = $content.Replace($_.value, [System.Environment]::GetEnvironmentVariable($_.value)) }; out-file -filepath %sys_config_target% -inputobject $content -encoding ascii"
set sys_config=%sys_config_target%
goto :eof

:find_vm_args
set possible_vmargs=%release_config_dir%\vm.args
if exist %possible_vmargs% (
  set vmargs_src=%possible_vmargs%
) else (
  set vmargs_src=%rel_dir%\vm.args
)
set vmargs_target=%config_dir%\vm.args
:: Replace environment variables
powershell -command "$content = get-content %vmargs_src%; [regex]::matches($content, '\${[\w\d_-]+}') | foreach { $content = $content.Replace($_.value, [System.Environment]::GetEnvironmentVariable($_.value)) }; out-file -filepath %vmargs_target% -inputobject $content -encoding ascii"
set vm_args=%vmargs_target%
goto :eof

:: set boot_script variable
:set_boot_script_var
if exist %rel_dir%\%rel_name%.boot (
  set boot_script=%rel_dir%\%rel_name%
) else (
  set boot_script=%rel_dir%\start
)
goto :eof

:: Write the erl.ini file
:write_ini
set erl_ini=%erts_dir%\bin\erl.ini
set converted_bindir=%bindir:\=\\%
set converted_rootdir=%rootdir:\=\\%
echo [erlang] > "%erl_ini%"
echo Bindir=%converted_bindir% >> "%erl_ini%"
echo Progname=%progname% >> "%erl_ini%"
echo Rootdir=%converted_rootdir% >> "%erl_ini%"
goto :eof

:: Display usage information
:usage
echo Usage: %~n0 ^<task^>
echo.
echo Service Control
echo =====================
echo install                             # installs the release as a service
echo uninstall                           # uninstalls the release service
echo start                               # starts the service
echo start_boot                          # not implemented
echo foreground                          # start the release in the foreground
echo console                             # run the release in a local shell
echo console_clean                       # not implemented
echo stop                                # stops the service
echo restart                             # restarts the release service
echo reboot                              # alias for restart on Windows
echo reload_config                       # reload the current system's configuration from disk
echo.
echo Upgrades
echo =====================
echo upgrade ^<version^>                   # upgrade the current release service
echo downgrade ^<version^>                 # downgrade the current release service
echo.
echo Utilities
echo =====================
echo attach                              # alias for remote_console on Windows
echo remote_console                      # open a remote console connected to the release
echo pid                                 # get the process id of the running release
echo ping                                # ping the current release service, pong is returned if ok
echo pingpeer ^<peer^>                     # check if a peer node is running, pong is returned if ok
echo escript ^<file^>                      # execute an escript
echo rpc ^<mod^> ^<fun^> ^[^<args..^>^]          # execute an RPC call using the given MFA
echo rpcterms ^<mod^> ^<fun^> ^[^<expr^>^]       # execute an RPC call using the given Erlang expr for args
echo eval ^<expr^>                         # execute the given Erlang expr on the running node
echo command ^<mod^> ^<fun^> ^[^<args..^>^]      # execute the given module/function in a clean VM
echo describe                            # list details about the release
echo.
echo Custom Commands
echo ======================
for %%i in (%command_dir%\*.d\*.bat) do (
  echo %%~ni
)
goto :eof

:: Install the release as a Windows service
:: or install the specified version passed as argument
:install
setlocal EnableDelayedExpansion
set service_args=%erl_opts% -setcookie "!cookie!" ++ ^
       -rootdir "%rootdir%" ^
       -reldir "%release_root_dir%\releases"
set start_erl=%erts_dir%\bin\start_erl.exe
set description=Erlang node %node_name% in %rootdir%
if "" == "%args%" (
  :: Install the service
  %erlsrv% add %service_name% ^
            -c "%description%" ^
            %node_type% "%node_name%" ^
            -w "%mutable_dir%" ^
            -m "%start_erl%" ^
            -args "!service_args!" ^
            -debugtype new ^
            -stopaction "init:stop()."
  endlocal
) else (
  :: relup and reldown
  endlocal
  goto upgrade
)
goto :eof

:: Uninstall the Windows service
:uninstall
%erlsrv% remove %service_name%
%epmd% -kill
goto :eof

:: Start the Windows service
:start
call :pre_configure_hooks
call :post_configure_hooks
call :pre_start_hooks
%erlsrv% start %service_name%
call :post_start_hooks
goto :eof

:: Stop the Windows service
:stop
call :pre_stop_hooks
%erlsrv% stop %service_name%
call :post_stop_hooks
goto :eof

:: Upgrade this release
:upgrade
setlocal EnableDelayedExpansion
if "" == "%args%" (
  echo Missing version argument
  echo Usage: %rel_name% %taskname% {version}
  set ERRORLEVEL=1
  exit /b %ERRORLEVEL%
)
set source_version=%rel_vsn%
set target_version=%args%
:: Unpack
%escript% "%release_root_dir%\bin\release_utils.escript" ^
    unpack_release %rel_name% "%node_type%" "%node_name%" "!cookie!" "%target_version%"
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
:: Update env
set rel_vsn=%target_version%
set rel_dir=%release_root_dir\releases\%target_version%
:: TODO: init_configs
if exist "%rel_dir%\sys.config.bak" do (
  move /Y "%rel_dir%\sys.config.bak" "%rel_dir%\sys.config"
)
if exist "%rel_dir%\vm.args.bak" do (
  move /Y "%rel_dir%\vm.args.bak" "%rel_dir%\vm.args"
)
copy /B /Y "%rel_dir%/sys.config" "%rel_dir%\sys.config.bak"
copy /B /Y "%rel_dir%/vm.args" "%rel_dir%\vm.args.bak"
copy /B /Y "%sys_config" "%rel_dir%/sys.config"
copy /B /Y "%vm_args%" "%rel_dir%/vm.args"
:: Run pre hooks
call :pre_configure_hooks
call :post_configure_hooks
call :pre_upgrade_hooks
:: Perform upgrade
%escript% "%rootdir%/bin/release_utils.escript" ^
    install_release "%rel_name%" "%node_type%" "%node_name%" "!cookie!" "%target_version%"
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
:: Cleanup
move /Y "%rel_dir%\sys.config.bak" "%rel_dir%\sys.config"
move /Y "%rel_dir%\vm.args.bak" "%rel_dir%\vm.args"
:: Run post hooks
call :post_upgrade_hooks
endlocal
goto :eof

:: Start a console
:console
call :pre_configure_hooks
call :post_configure_hooks
call :pre_start_hooks
start "%rel_name% console" %werl% -boot "%boot_script%" ^
       -config "%sys_config%"  ^
       -args_file "%vm_args%" ^
       -user Elixir.IEx.CLI ^
       -extra --no-halt +iex
goto :eof

:: Start the release in the foreground
:foreground
call :pre_configure_hooks
call :post_configure_hooks
call :pre_start_hooks
set EMU=beam
set PROGNAME=%~n0
start "" /B "%erl%" -noshell -noinput +Bd ^
       -boot "%boot_script%" ^
       -boot_var ERTS_LIB_DIR "%erts_dir%\..\lib" ^
       -env ERL_LIBS "%release_root_dir%\lib%" ^
       -pa "%consolidated_dir%" ^
       -args_file "%vm_args%" ^
       -config "%sys_config%" ^
       %erl_opts% ^
       -extra %extra_opts%
call :set_pid
call :post_start_hooks

:wait_for_exit
tasklist /FI "PID eq %pid%" | find /I "erl.exe"
if %ERRORLEVEL% geq 1 (
  :: Process has shutdown
  call :post_stop_hooks
) else (
  sleep 5
  goto :wait_for_exit
)
goto :eof

:: Ping the running node
:ping
setlocal EnableDelayedExpansion
%escript% %nodetool% ping %node_type% "%node_name%" -setcookie "!cookie!"
endlocal
goto :eof

:: Ping a peer node
:: Ping a peer node
:pingpeer
setlocal EnableDelayedExpansion
if "%args"=="" (
  echo "Peer name is required!"
  exit 1
) else (
  %escript% %nodetool% ping %node_type% "%args%" -setcookie "!cookie!"
)
endlocal
goto :eof

:: Execute an escript
:escript
%escript% %args%
goto :eof

:: Execute an RPC command
:rpc
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% rpc %node_type% %node_name% -setcookie "!cookie!" %args%
endlocal
goto :eof

:: Execute an RPC command where args are expressed
:: in the form of an Erlang expression
:rpcterms
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% rpcterms %node_type% %node_name% -setcookie "!cookie!" %args%
endlocal
goto :eof

:: Eval an expression on the running node
:eval
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% eval %node_type% %node_name% -setcookie "!cookie!" !args!
endlocal
goto :eof

:: Execute a command in a clean Erlang VM
:command
for /f "tokens=1-2*" %%a in ("%args%") do (
  set module=%%a
  set function=%%b
  set command_args=%%c
)
%erl% -boot_var ERTS_LIB_DIR "%erts_dir%\..\lib" ^
       -hidden -noshell -boot start_clean ^
       -pa "%consolidated_dir%" ^
       -s %module% %function% -s init stop
       -extra %command_args%
goto :eof

:: Get the process id of the running node
:pid
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% eval %node_type% %node_name% -setcookie "!cookie!" "erlang:list_to_integer(os:getpid())."
endlocal
goto :eof

:set_pid
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
set get_pid_cmd=%escript% %nodetool% eval %node_type% %node_name% -setcookie "!cookie!" "erlang:list_to_integer(os:getpid())."
for /f "usebackq delims=" %%i in (`%%get_pid_cmd%%`) do set pid=%%i
endlocal & set pid=%pid%
goto :eof

:: Reload the running configuration
:reload_config
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
call :pre_configure_hooks
call :post_configure_hooks
setlocal EnableDelayedExpansion
%escript% %nodetool% reload_config %node_type% %node_name% -setcookie "!cookie!" "%sys_config%"
endlocal
goto :eof

:: Describe this release
:describe
setlocal EnableDelayedExpansion
echo Service Information
echo =====================
%erlsrv% list %service_name%
echo.
echo Release Metadata
echo =====================
echo ERTS                %erts_vsn%
echo Release Directory   %rel_dir%
echo Config File         %sys_config%
echo Args File           %vm_args%
echo Name Type           %node_type%
echo Node Name           %node_name%
echo Node Cookie         !cookie!
echo Extra Opts          %erl_opts%
echo.
echo Hooks:
for %%i in (%hook_dir%\*.d\*.bat) do (
  echo %%i
)
echo.
echo Commands:
for %%i in (%command_dir%\*.d\*.bat) do (
  echo %%i
)
endlocal
goto :eof

:: Remote shell to a running node
:remote_console
call :ping
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
set id=remsh%RANDOM%-%node_name%
start "%node_name% attach" %werl% -hidden -noshell -boot "%clean_boot_script%" ^
       -user Elixir.IEx.CLI %node_type% %id% -setcookie "!cookie!" ^
       -extra --no-halt +iex -%node_type% %id% --cookie "!cookie!" --remsh %node_name%
endlocal
goto :eof

:: Hook helpers
:execute_hooks
for /r "%hook_dir%\%1.d" %%f in (*.bat) do (
  echo Running %1 hook: %%f
  %%f
  if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
)
goto :eof

:pre_configure_hooks
call :execute_hooks pre_configure
goto :eof

:post_configure_hooks
call :execute_hooks post_configure
goto :eof

:pre_start_hooks
call :execute_hooks pre_start
goto :eof

:post_start_hooks
call :execute_hooks post_start
goto :eof

:pre_stop_hooks
call :execute_hooks pre_stop
goto :eof

:post_stop_hooks
call :execute_hooks post_stop
goto :eof

:pre_upgrade_hooks
call :execute_hooks pre_upgrade
goto :eof

:post_upgrade_hooks
call :execute_hooks post_upgrade
goto :eof

:: This batch file handles managing an Erlang node as a Windows service.
::
:: Check the :usage section for information about what this script provides

@echo off

:: Set variables that describe the release
set rel_name=<%= release_name %>
set rel_vsn=<%= release_version %>
set erts_vsn=<%= erts_vsn %>
set erl_opts=<%= erl_opts %>

:: Discover the release root directory from the directory
:: of this script
set script_dir=%~dp0
for %%A in ("%script_dir%\..\..") do (
  set release_root_dir=%%~fA
)
set rel_dir=%release_root_dir%\releases\%rel_vsn%

if "%RELEASE_MUTABLE_DIR%"=="" (
  set mutable_dir=%release_root_dir%\var
) else (
  set mutable_dir=%RELEASE_MUTABLE_DIR%
)

if "%RELEASE_CONFIG_DIR%"=="" (
  set config_dir=%release_root_dir%
) else (
  set config_dir=%RELEASE_CONFIG_DIR%
)

set log_dir=%mutable_dir%\log

:: Create directories which don't exist
if not exist %mutable_dir% mkdir %mutable_dir%
if not exist %config_dir% mkdir %config_dir%
if not exist %log_dir% mkdir %log_dir%

call :find_erts_dir
call :find_sys_config
call :find_vm_args
call :set_boot_script_var

set service_name=%rel_name%_%rel_vsn%
set bindir=%erts_dir%\bin
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 consolidated_dir=%rootdir%\lib\%rel_name%-%rel_vsn%\consolidated
set hook_dir=%rel_dir%\hooks
set command_dir=%rel_dir%\commands

:: Extract node type and name from vm.args
for /f "usebackq tokens=1-2" %%I in (`findstr /b "\-name \-sname" "%vm_args%"`) do (
  set node_type=%%I
  set node_name=%%J
)

:: Extract cookie from vm.args
for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do (
  set cookie=%%J
)

:: Write the erl.ini file to set up paths relative to this script
call :write_ini

:: If a start.boot file is not present, copy one from the named .boot file
if not exist "%rel_dir%\start.boot" (
  copy "%rel_dir%\%rel_name%.boot" "%rel_dir%\start.boot" >nul
)

set taskname="%1"
shift /1
set args=

setlocal EnableDelayedExpansion
:parse_args
set param=%1
if "!param!"=="" goto :args_parsed
if "!args!"=="" (
  set largs=%param%
) else (
  set largs=%largs% %param%
)
set "delim= "
shift /1
goto :parse_args
:args_parsed
endlocal & set args=%largs%

if %taskname%=="install" goto install
if %taskname%=="uninstall" goto uninstall
if %taskname%=="start" goto start
if %taskname%=="foreground" goto foreground
if %taskname%=="console" goto console
if %taskname%=="stop" goto stop
if %taskname%=="restart" call :stop && goto start
if %taskname%=="reboot" call :stop && goto start
if %taskname%=="reload_config" goto reload_config
if %taskname%=="upgrade" goto upgrade
if %taskname%=="downgrade" goto upgrade
if %taskname%=="attach" goto remote_console
if %taskname%=="remote_console" goto remote_console
if %taskname%=="pid" goto pid
if %taskname%=="ping" goto ping
if %taskname%=="pingpeer" goto pingpeer
if %taskname%=="escript" goto escript
if %taskname%=="rpc" goto rpc
if %taskname%=="rpcterms" goto rpcterms
if %taskname%=="eval" goto eval
if %taskname%=="command" goto command
if %taskname%=="describe" goto describe
if %taskname%=="" goto usage
if exist "%command_dir%\%taskname%" (
  "%command_dir%\%taskname%" %*
) else (
  echo Unknown command: %taskname%
)
goto :eof

:: Find the ERTS dir
:find_erts_dir
if "%erts_vsn%"=="" (
  call :use_system_erts
) else (
  call :use_bundled_erts
)
goto :eof

:: Load system ERTS info
:use_system_erts
for /f "delims=" %%i in ('where erl') do set system_erl="%%i"
if %system_erl%=="" (
  echo failed to locate the Erlang Runtime System!
  exit 1
)
set system_root_dir_cmd=%system_erl% -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop
for /f "delims=" %%i in (`%%system_root_dir_cmd%%`) do set system_root=%%i
set system_erts_vsn_cmd=%system_erl% -noshell -eval "Ver=erlang:system_info(version),io:format(\"~s\", [Ver])" -s init stop
for /f "delims=" %%i in (`%%system_erts_vsn_cmd%%`) do set system_erts_vsn=%%i
set erl=%system_erl%
set erts_vsn=%system_erts_vsn%
set rootdir=%system_root%
set erts_dir=%rootdir%\erts-%erts_vsn%
goto :eof

:: Load bundled ERTS info
:use_bundled_erts
set erts_dir=%release_root_dir%\erts-%erts_vsn%
set erl=%erts_dir%\bin\erl
set rootdir=%release_root_dir%
goto :eof

:: Find the sys.config file
:find_sys_config
set possible_sys=%release_config_dir%\sys.config
if exist %possible_sys% (
  set sys_config_src=%possible_sys%
) else (
  set sys_config_src=%rel_dir%\sys.config
)
set sys_config_target=%config_dir%\sys.config
:: Replace environment variables
powershell -command "$content = get-content %sys_config_src%; [regex]::matches($content, '\${[\w\d_-]+}') | foreach { $content = $content.Replace($_.value, [System.Environment]::GetEnvironmentVariable($_.value)) }; out-file -filepath %sys_config_target% -inputobject $content -encoding ascii"
set sys_config=%sys_config_target%
goto :eof

:find_vm_args
set possible_vmargs=%release_config_dir%\vm.args
if exist %possible_vmargs% (
  set vmargs_src=%possible_vmargs%
) else (
  set vmargs_src=%rel_dir%\vm.args
)
set vmargs_target=%config_dir%\vm.args
:: Replace environment variables
powershell -command "$content = get-content %vmargs_src%; [regex]::matches($content, '\${[\w\d_-]+}') | foreach { $content = $content.Replace($_.value, [System.Environment]::GetEnvironmentVariable($_.value)) }; out-file -filepath %vmargs_target% -inputobject $content -encoding ascii"
set vm_args=%vmargs_target%
goto :eof

:: set boot_script variable
:set_boot_script_var
if exist %rel_dir%\%rel_name%.boot (
  set boot_script=%rel_dir%\%rel_name%
) else (
  set boot_script=%rel_dir%\start
)
goto :eof

:: Write the erl.ini file
:write_ini
set erl_ini=%erts_dir%\bin\erl.ini
set converted_bindir=%bindir:\=\\%
set converted_rootdir=%rootdir:\=\\%
echo [erlang] > "%erl_ini%"
echo Bindir=%converted_bindir% >> "%erl_ini%"
echo Progname=%progname% >> "%erl_ini%"
echo Rootdir=%converted_rootdir% >> "%erl_ini%"
goto :eof

:: Display usage information
:usage
echo Usage: %~n0 ^<task^>
echo.
echo Service Control
echo =====================
echo install                             # installs the release as a service
echo uninstall                           # uninstalls the release service
echo start                               # starts the service
echo start_boot                          # not implemented
echo foreground                          # start the release in the foreground
echo console                             # run the release in a local shell
echo console_clean                       # not implemented
echo stop                                # stops the service
echo restart                             # restarts the release service
echo reboot                              # alias for restart on Windows
echo reload_config                       # reload the current system's configuration from disk
echo.
echo Upgrades
echo =====================
echo upgrade ^<version^>                   # upgrade the current release service
echo downgrade ^<version^>                 # downgrade the current release service
echo.
echo Utilities
echo =====================
echo attach                              # alias for remote_console on Windows
echo remote_console                      # open a remote console connected to the release
echo pid                                 # get the process id of the running release
echo ping                                # ping the current release service, pong is returned if ok
echo pingpeer ^<peer^>                     # check if a peer node is running, pong is returned if ok
echo escript ^<file^>                      # execute an escript
echo rpc ^<mod^> ^<fun^> ^[^<args..^>^]          # execute an RPC call using the given MFA
echo rpcterms ^<mod^> ^<fun^> ^[^<expr^>^]       # execute an RPC call using the given Erlang expr for args
echo eval ^<expr^>                         # execute the given Erlang expr on the running node
echo command ^<mod^> ^<fun^> ^[^<args..^>^]      # execute the given module/function in a clean VM
echo describe                            # list details about the release
echo.
echo Custom Commands
echo ======================
for %%i in (%command_dir%\*.d\*.bat) do (
  echo %%~ni
)
goto :eof

:: Install the release as a Windows service
:: or install the specified version passed as argument
:install
setlocal EnableDelayedExpansion
set service_args=%erl_opts% -setcookie "!cookie!" ++ ^
       -rootdir "%rootdir%" ^
       -reldir "%release_root_dir%\releases"
set start_erl=%erts_dir%\bin\start_erl.exe
set description=Erlang node %node_name% in %rootdir%
if "" == "%args%" (
  :: Install the service
  %erlsrv% add %service_name% ^
            -c "%description%" ^
            %node_type% "%node_name%" ^
            -w "%mutable_dir%" ^
            -m "%start_erl%" ^
            -args "!service_args!" ^
            -debugtype new ^
            -stopaction "init:stop()."
  endlocal
) else (
  :: relup and reldown
  endlocal
  goto upgrade
)
goto :eof

:: Uninstall the Windows service
:uninstall
%erlsrv% remove %service_name%
%epmd% -kill
goto :eof

:: Start the Windows service
:start
call :pre_configure_hooks
call :post_configure_hooks
call :pre_start_hooks
%erlsrv% start %service_name%
call :post_start_hooks
goto :eof

:: Stop the Windows service
:stop
call :pre_stop_hooks
%erlsrv% stop %service_name%
call :post_stop_hooks
goto :eof

:: Upgrade this release
:upgrade
setlocal EnableDelayedExpansion
if "" == "%args%" (
  echo Missing version argument
  echo Usage: %rel_name% %taskname% {version}
  set ERRORLEVEL=1
  exit /b %ERRORLEVEL%
)
set source_version=%rel_vsn%
set target_version=%args%
:: Unpack
%escript% "%release_root_dir%\bin\release_utils.escript" ^
    unpack_release %rel_name% "%node_type%" "%node_name%" "!cookie!" "%target_version%"
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
:: Update env
set rel_vsn=%target_version%
set rel_dir=%release_root_dir\releases\%target_version%
:: TODO: init_configs
if exists "%rel_dir%\sys.config.bak" do (
  move /Y "%rel_dir%\sys.config.bak" "%rel_dir%\sys.config"
)
if exists "%rel_dir%\vm.args.bak" do (
  move /Y "%rel_dir%\vm.args.bak" "%rel_dir%\vm.args"
)
copy /B /Y "%rel_dir%/sys.config" "%rel_dir%\sys.config.bak"
copy /B /Y "%rel_dir%/vm.args" "%rel_dir%\vm.args.bak"
copy /B /Y "%sys_config" "%rel_dir%/sys.config"
copy /B /Y "%vm_args%" "%rel_dir%/vm.args"
:: Run pre hooks
call :pre_configure_hooks
call :post_configure_hooks
call :pre_upgrade_hooks
:: Perform upgrade
%escript% "%rootdir%/bin/release_utils.escript" ^
    install_release "%rel_name%" "%node_type%" "%node_name%" "!cookie!" "%target_version%"
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
:: Cleanup
move /Y "%rel_dir%\sys.config.bak" "%rel_dir%\sys.config"
move /Y "%rel_dir%\vm.args.bak" "%rel_dir%\vm.args"
:: Run post hooks
call :post_upgrade_hooks
endlocal
goto :eof

:: Start a console
:console
call :pre_configure_hooks
call :post_configure_hooks
call :pre_start_hooks
start "%rel_name% console" %werl% -boot "%boot_script%" ^
       -config "%sys_config%"  ^
       -args_file "%vm_args%" ^
       -user Elixir.IEx.CLI ^
       -extra --no-halt +iex
goto :eof

:: Start the release in the foreground
:foreground
call :pre_configure_hooks
call :post_configure_hooks
call :pre_start_hooks
set EMU=beam
set PROGNAME=%~n0
start "" /B "%erl%" -noshell -noinput +Bd ^
       -boot "%boot_script%" ^
       -boot_var ERTS_LIB_DIR "%erts_dir%\..\lib" ^
       -env ERL_LIBS "%release_root_dir%\lib%" ^
       -pa "%consolidated_dir%" ^
       -args_file "%vm_args%" ^
       -config "%sys_config%" ^
       %erl_opts% ^
       -extra %extra_opts%
call :set_pid
call :post_start_hooks

:wait_for_exit
tasklist /FI "PID eq %pid%" | find /I "erl.exe"
if %ERRORLEVEL% geq 1 (
  :: Process has shutdown
  call :post_stop_hooks
) else (
  sleep 5
  goto :wait_for_exit
)
goto :eof

:: Ping the running node
:ping
setlocal EnableDelayedExpansion
%escript% %nodetool% ping %node_type% "%node_name%" -setcookie "!cookie!"
endlocal
goto :eof

:: Ping a peer node
:: Ping a peer node
:pingpeer
setlocal EnableDelayedExpansion
if "%args"=="" (
  echo "Peer name is required!"
  exit 1
) else (
  %escript% %nodetool% ping %node_type% "%args%" -setcookie "!cookie!"
)
endlocal
goto :eof

:: Execute an escript
:escript
%escript% %args%
goto :eof

:: Execute an RPC command
:rpc
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% rpc %node_type% %node_name% -setcookie "!cookie!" %args%
endlocal
goto :eof

:: Execute an RPC command where args are expressed
:: in the form of an Erlang expression
:rpcterms
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% rpcterms %node_type% %node_name% -setcookie "!cookie!" %args%
endlocal
goto :eof

:: Eval an expression on the running node
:eval
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% eval %node_type% %node_name% -setcookie "!cookie!" !args!
endlocal
goto :eof

:: Execute a command in a clean Erlang VM
:command
for /f "tokens=1-2*" %%a in ("%args%") do (
  set module=%%a
  set function=%%b
  set command_args=%%c
)
%erl% -boot_var ERTS_LIB_DIR "%erts_dir%\..\lib" ^
       -hidden -noshell -boot start_clean ^
       -pa "%consolidated_dir%" ^
       -s %module% %function% -s init stop
       -extra %command_args%
goto :eof

:: Get the process id of the running node
:pid
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
%escript% %nodetool% eval %node_type% %node_name% -setcookie "!cookie!" "erlang:list_to_integer(os:getpid())."
endlocal
goto :eof

:set_pid
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
set get_pid_cmd=%escript% %nodetool% eval %node_type% %node_name% -setcookie "!cookie!" "erlang:list_to_integer(os:getpid())."
for /f "usebackq delims=" %%i in (`%%get_pid_cmd%%`) do set pid=%%i
endlocal & set pid=%pid%
goto :eof

:: Reload the running configuration
:reload_config
call :ping>NUL
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
call :pre_configure_hooks
call :post_configure_hooks
setlocal EnableDelayedExpansion
%escript% %nodetool% reload_config %node_type% %node_name% -setcookie "!cookie!" "%sys_config%"
endlocal
goto :eof

:: Describe this release
:describe
setlocal EnableDelayedExpansion
echo Service Information
echo =====================
%erlsrv% list %service_name%
echo.
echo Release Metadata
echo =====================
echo ERTS                %erts_vsn%
echo Release Directory   %rel_dir%
echo Config File         %sys_config%
echo Args File           %vm_args%
echo Name Type           %node_type%
echo Node Name           %node_name%
echo Node Cookie         !cookie!
echo Extra Opts          %erl_opts%
echo.
echo Hooks:
for %%i in (%hook_dir%\*.d\*.bat) do (
  echo %%i
)
echo.
echo Commands:
for %%i in (%command_dir%\*.d\*.bat) do (
  echo %%i
)
endlocal
goto :eof

:: Remote shell to a running node
:remote_console
call :ping
if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
setlocal EnableDelayedExpansion
set id=remsh%RANDOM%-%node_name%
start "%node_name% attach" %werl% -hidden -noshell -boot "%clean_boot_script%" ^
       -user Elixir.IEx.CLI %node_type% %id% -setcookie "!cookie!" ^
       -extra --no-halt +iex -%node_type% %id% --cookie "!cookie!" --remsh %node_name%
endlocal
goto :eof

:: Hook helpers
:execute_hooks
for /r "%hook_dir%\%1.d" %%f in (*.bat) do (
  echo Running %1 hook: %%f
  %%f
  if %ERRORLEVEL% GEQ 1 exit %ERRORLEVEL%
)
goto :eof

:pre_configure_hooks
call :execute_hooks pre_configure
goto :eof

:post_configure_hooks
call :execute_hooks post_configure
goto :eof

:pre_start_hooks
call :execute_hooks pre_start
goto :eof

:post_start_hooks
call :execute_hooks post_start
goto :eof

:pre_stop_hooks
call :execute_hooks pre_stop
goto :eof

:post_stop_hooks
call :execute_hooks post_stop
goto :eof

:pre_upgrade_hooks
call :execute_hooks pre_upgrade
goto :eof

:post_upgrade_hooks
call :execute_hooks post_upgrade
goto :eof


Undo dynamic translation for now, breaks stuff

  <%= gettext "Thank you for so much registering/logging in!" %>

          <button type="button" class="btn btn-default">
            <%= gettext "Back" %>
          </button>

          <button type="button" class="btn btn-default">
            <%= gettext "Log out" %>
          </button>

          <button type="button" class="btn btn-default">
            <%= gettext "Settings" %>
          </button>

        <%= for {stock_type, _stocks} <- @food_stock_by_type do %>

             <%= stock_type %>

        <% end %>

           Dropdown

              Action

        <%= for {stock_type, stocks} <- @food_stock_by_type do %>

            <%= stock_type %> <%= gettext("credits remaining:") %> <%=  @credits[stock_type] %>

            <%= for stock <- stocks do %>

                  <%= stock.food.longdesc %>

                  <%= stock.packaging %>

                  <%= stock.food.manufacturer_name %>

            <% end %>

        <% end %>

  <%= gettext "Thank you for so much registering/logging in!" %>

          <button type="button" class="btn btn-default">
            <%= gettext "Back" %>
          </button>

          <button type="button" class="btn btn-default">
            <%= gettext "Log out" %>
          </button>

          <button type="button" class="btn btn-default">
            <%= gettext "Settings" %>
          </button>

        <%= for {stock_type, _stocks} <- @food_stock_by_type do %>

             <%= stock_type %>

        <% end %>

           Dropdown

              Action

        <%= for {stock_type, stocks} <- @food_stock_by_type do %>

            <%= stock_type %> <%= gettext("credits remaining:") %> <%=  @credits[stock_type] %>

            <%= for stock <- stocks do %>

                  <%= Gettext.gettext(OpenPantry.Gettext, stock.food.longdesc) %>

                  <%= Gettext.gettext(OpenPantry.Gettext, stock.packaging) %>

                  <%= Gettext.gettext(OpenPantry.Gettext, stock.food.manufacturer_name) %>

            <% end %>

        <% end %>


Adds introduction message to users#show.

<%# header tag begins in parent template %>

      <img src="<%= Vutuv.Avatar.binary(@user, :medium) %>">

        <%= full_name(@user) %>
        <%= if same_user?(@user, @current_user) do %>
        <%= link to: user_path(@conn, :edit, @user), class: "profile-header__edit button button--icon button--small" do %>

        <% end %>
        <% end %>

        <%= current_title(@job) %>
        <%= if(@organization != "" and @organization) do %>
          @ <%= @organization %>
        <% end %>

        <%= if(@follower_count>0) do %>

<%= String.capitalize(@user.first_name) %> <%= gettext "has" %><%= @follower_count %> <%= gettext "followers" %>

        <% end %>
        <%= if is_visitor?(@conn, @current_user) do %>
          <%= if user_follows_user?(@current_user, @user) do %>
            <%= button to: connection_path(@conn, :delete, user_follows_user?(@current_user, @user)), method: :delete , class: "button button-link" do %>
               Unfollow
            <% end %>
          <%= else %>
            <%= button to: connection_path(@conn, :create, connection: %{follower_id: @current_user_id, followee_id: @user.id}), method: :post , class: "button button-link" do %>
               Follow
            <% end %>
          <% end %>
        <% end %>

<%= render Vutuv.LayoutView, "flash.html", assigns %>

  <%= gettext "Users" %> / <%= full_name @user %>

  <%= if same_user?(@user, @current_user) do %>

<%= gettext "Your New vutuv Profile Page" %>

        Please take a couple of minutes to add information that might be interesting for your followers. Why don't you start with skills and your work experiences?

        Like in Mission Impossible this introduction message will self-destruct in one hour.

  <% end %>

    <%= if same_user?(@user, @current_user) do %>
    <%= link to: user_path(@conn, :edit, @user), class: "card__edit button button--icon button--small" do %>

    <% end %>
    <% end %>

<%= gettext "Headline" %>

<%= @user.headline %>

      <%= if(@user.gender != "other" && @user.gender) do %>

<%= gettext "Gender" %>

<%= @user.gender %>

      <% end %>
      <%= if(@user.birthdate) do %>

<%= gettext "Birthday" %>

<%= @user.birthdate %>

      <% end %>

    <%= render Vutuv.SharedView, "_ad.html" %>

      <%= if same_user?(@user, @current_user) do %>
      <%= link to: user_email_path(@conn, :index, @user), class: "card__edit button button--icon button--small" do %>

      <% end %>
      <% end %>

<%= gettext "Contact" %>

<%= if (Enum.count(@emails) == 1), do: gettext("Email"), else: gettext("Emails") %>

        <%= for email <- @emails do %>

<a href="mailto:<%= email(@user) %>"><%= email.value %>

        <% end %>

        <%= if same_user?(@user, @current_user) do %>
          <%= link gettext("Add"), to: user_email_path(@conn, :new, @current_user) %>
        <% end %>

<%= gettext "Vcard" %>

<%= link gettext("Download"), to: api_user_v_card_path(@conn, :get, @user) %>

    <%= if Enum.count(@user.social_media_accounts) > 0 or same_user?(@user, @current_user) do %>

        <%= if same_user?(@user, @current_user) do %>
        <%= link to: user_social_media_account_path(@conn, :index, @user), class: "card__edit button button--icon button--small" do %>

        <% end %>
        <% end %>

<%= gettext "Social Media" %>

          <%= for account <- @user.social_media_accounts do %>

<%= account.provider %>

<%= link "@#{account.value}", to: Vutuv.SocialMediaAccount.get_full_url(account) %>

          <% end %>

          <%= if same_user?(@user, @current_user) do %>
            <%= link gettext("Add"), to: user_social_media_account_path(@conn, :new, @current_user) %>
          <% end %>

    <% end %>

  <%= if Enum.count(@user_skills) > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Skills" %>

    <%= if Enum.count(@user_skills) > 0 do %>
    <%= render Vutuv.UserSkillView, "card_list.html", assigns %>
    <% end %>

    <%= if same_user?(@user, @current_user) do %>
      <% #Form for easy skill entry %>
      <%= if Enum.count(@user_skills) == 0 do %>
        <%= form_for @conn, user_path(@conn, :skills_create, @user), [as: :skills, class: "editform"], fn f -> %>
          <div class="editform__field<%= if error_tag(f, :name), do: " editform__field--error"%>">
            <%= label f, :skills, gettext("Enter comma seperated skills here") %>
            <%= text_input f, :skills, placeholder: gettext("PHP, JavaScript, Tap Dancing, Origami"), autofocus: true %>
            <%= error_tag f, :skills %>

            <%= submit gettext("Add"), class: "button button--full" %>

        <% end %>
      <% end %>
    <% end %>
    <%= if Enum.count(@user_skills) > 0 do %>

        <%= if same_user?(@user, @current_user) do %>
          <%= link gettext("Add"), to: user_user_skill_path(@conn, :new, @current_user) %>
        <% end %>
        <%= if same_user?(@user, @current_user) and Enum.count(@user.user_skills) > 4 do %> | <% end %>
        <%= if Enum.count(@user.user_skills) > 4 do %>
          <%= link gettext("View All"), to: user_user_skill_path(@conn, :index, @user)%>
        <% end %>

    <% end %>

  <% end %>

  <section class="card half<%= if @follower_count == 0, do: " card--empty" %>">

<%= gettext "Followers" %>

    <%= if(@follower_count > 0) do %>

    <%= render "card_list.html", conn: @conn, users: @user.followers, current_user: @current_user, current_user_id: @current_user_id %>

    <% else %>

<%= gettext "No Followers yet!" %>

    <% end %>
    <%= if(@follower_count > 3) do %>
      <%= link "#{@followers_count-3} #{gettext "More"}", to: user_follower_path(@conn, :index, @user), class: "card__morelink" %>
    <% end %>

<%= gettext "Following" %>

    <%= if(@followee_count > 0) do %>

    <%= render "card_list.html", conn: @conn, users: @user.followees, current_user: @current_user, current_user_id: @current_user_id %>

    <% else %>

<%= gettext "Not following anyone yet!" %>

    <% end %>
    <%= if(@followee_count > 3) do %>
      <%= link "#{@followee_count-3} #{gettext "More"}", to: user_followee_path(@conn, :index, @user), class: "card__morelink" %>
    <% end %>

    <%= if @total_jobs > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Experience" %>

    <%= if @total_jobs > 0 do %>
    <%= render Vutuv.WorkExperienceView, "card_list.html", assigns %>

    <% else %>

    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_work_experience_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_jobs>3 do %> | <% end %>
      <%= if @total_jobs>3 do %>
        <%= link gettext("View All"), to: user_work_experience_path(@conn, :index, @user) %>
      <% end %>

  <% end %>

  <%= if @total_numbers > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Phone Numbers" %>

    <%= if @total_numbers > 0 do %>
    <%= render Vutuv.PhoneNumberView, "card_list.html", phone_numbers: @user.phone_numbers, user: @user, conn: @conn, current_user: @current_user %>
    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_phone_number_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_numbers > 3 do %> | <% end %>
      <%= if @total_numbers>3 do %>
        <%= link gettext("View All"), to: user_phone_number_path(@conn, :index, @user) %>
      <% end %>

  <% end %>

  <%= if @total_links > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Links" %>

    <%= if @total_links > 0 do %>
    <%= render Vutuv.UrlView, "card_list.html", urls: @user.urls, user: @user, conn: @conn, current_user: @current_user %>
    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_url_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_links > 3 do %> | <% end %>
      <%= if @total_links>3 do %>
        <%= link gettext("View All"), to: user_url_path(@conn, :index, @user) %>
      <% end %>

  <% end %>

  <%= if @total_addresses > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Addresses" %>

    <%= if @total_addresses > 0 do %>
    <%= render Vutuv.AddressView, "card_list.html", addresses: @user.addresses, user: @user, conn: @conn, current_user: @current_user %>
    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_address_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_addresses > 3 do %> | <% end %>
      <%= if @total_addresses>3 do %>
        <%= link gettext("View All"), to: user_address_path(@conn, :index, @user) %>
      <% end %>

  <% end %>

<%# header tag begins in parent template %>

      <img src="<%= Vutuv.Avatar.binary(@user, :medium) %>">

        <%= full_name(@user) %>
        <%= if same_user?(@user, @current_user) do %>
        <%= link to: user_path(@conn, :edit, @user), class: "profile-header__edit button button--icon button--small" do %>

        <% end %>
        <% end %>

        <%= current_title(@job) %>
        <%= if(@organization != "" and @organization) do %>
          @ <%= @organization %>
        <% end %>

        <%= if(@follower_count>0) do %>

<%= String.capitalize(@user.first_name) %> <%= gettext "has" %><%= @follower_count %> <%= gettext "followers" %>

        <% end %>
        <%= if is_visitor?(@conn, @current_user) do %>
          <%= if user_follows_user?(@current_user, @user) do %>
            <%= button to: connection_path(@conn, :delete, user_follows_user?(@current_user, @user)), method: :delete , class: "button button-link" do %>
               Unfollow
            <% end %>
          <%= else %>
            <%= button to: connection_path(@conn, :create, connection: %{follower_id: @current_user_id, followee_id: @user.id}), method: :post , class: "button button-link" do %>
               Follow
            <% end %>
          <% end %>
        <% end %>

<%= render Vutuv.LayoutView, "flash.html", assigns %>

  <%= gettext "Users" %> / <%= full_name @user %>

    <%= if same_user?(@user, @current_user) do %>
    <%= link to: user_path(@conn, :edit, @user), class: "card__edit button button--icon button--small" do %>

    <% end %>
    <% end %>

<%= gettext "Headline" %>

<%= @user.headline %>

      <%= if(@user.gender != "other" && @user.gender) do %>

<%= gettext "Gender" %>

<%= @user.gender %>

      <% end %>
      <%= if(@user.birthdate) do %>

<%= gettext "Birthday" %>

<%= @user.birthdate %>

      <% end %>

    <%= render Vutuv.SharedView, "_ad.html" %>

      <%= if same_user?(@user, @current_user) do %>
      <%= link to: user_email_path(@conn, :index, @user), class: "card__edit button button--icon button--small" do %>

      <% end %>
      <% end %>

<%= gettext "Contact" %>

<%= if (Enum.count(@emails) == 1), do: gettext("Email"), else: gettext("Emails") %>

        <%= for email <- @emails do %>

<a href="mailto:<%= email(@user) %>"><%= email.value %>

        <% end %>

        <%= if same_user?(@user, @current_user) do %>
          <%= link gettext("Add"), to: user_email_path(@conn, :new, @current_user) %>
        <% end %>

<%= gettext "Vcard" %>

<%= link gettext("Download"), to: api_user_v_card_path(@conn, :get, @user) %>

    <%= if Enum.count(@user.social_media_accounts) > 0 or same_user?(@user, @current_user) do %>

        <%= if same_user?(@user, @current_user) do %>
        <%= link to: user_social_media_account_path(@conn, :index, @user), class: "card__edit button button--icon button--small" do %>

        <% end %>
        <% end %>

<%= gettext "Social Media" %>

          <%= for account <- @user.social_media_accounts do %>

<%= account.provider %>

<%= link "@#{account.value}", to: Vutuv.SocialMediaAccount.get_full_url(account) %>

          <% end %>

          <%= if same_user?(@user, @current_user) do %>
            <%= link gettext("Add"), to: user_social_media_account_path(@conn, :new, @current_user) %>
          <% end %>

    <% end %>

  <%= if Enum.count(@user_skills) > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Skills" %>

    <%= if Enum.count(@user_skills) > 0 do %>
    <%= render Vutuv.UserSkillView, "card_list.html", assigns %>
    <% end %>

    <%= if same_user?(@user, @current_user) do %>
      <% #Form for easy skill entry %>
      <%= if Enum.count(@user_skills) == 0 do %>
        <%= form_for @conn, user_path(@conn, :skills_create, @user), [as: :skills, class: "editform"], fn f -> %>
          <div class="editform__field<%= if error_tag(f, :name), do: " editform__field--error"%>">
            <%= label f, :skills, gettext("Enter comma seperated skills here") %>
            <%= text_input f, :skills, placeholder: gettext("PHP, JavaScript, Tap Dancing, Origami"), autofocus: true %>
            <%= error_tag f, :skills %>

            <%= submit gettext("Add"), class: "button button--full" %>

        <% end %>
      <% end %>
    <% end %>
    <%= if Enum.count(@user_skills) > 0 do %>

        <%= if same_user?(@user, @current_user) do %>
          <%= link gettext("Add"), to: user_user_skill_path(@conn, :new, @current_user) %>
        <% end %>
        <%= if same_user?(@user, @current_user) and Enum.count(@user.user_skills) > 4 do %> | <% end %>
        <%= if Enum.count(@user.user_skills) > 4 do %>
          <%= link gettext("View All"), to: user_user_skill_path(@conn, :index, @user)%>
        <% end %>

    <% end %>

  <% end %>

  <section class="card half<%= if @follower_count == 0, do: " card--empty" %>">

<%= gettext "Followers" %>

    <%= if(@follower_count > 0) do %>

    <%= render "card_list.html", conn: @conn, users: @user.followers, current_user: @current_user, current_user_id: @current_user_id %>

    <% else %>

<%= gettext "No Followers yet!" %>

    <% end %>
    <%= if(@follower_count > 3) do %>
      <%= link "#{@followers_count-3} #{gettext "More"}", to: user_follower_path(@conn, :index, @user), class: "card__morelink" %>
    <% end %>

<%= gettext "Following" %>

    <%= if(@followee_count > 0) do %>

    <%= render "card_list.html", conn: @conn, users: @user.followees, current_user: @current_user, current_user_id: @current_user_id %>

    <% else %>

<%= gettext "Not following anyone yet!" %>

    <% end %>
    <%= if(@followee_count > 3) do %>
      <%= link "#{@followee_count-3} #{gettext "More"}", to: user_followee_path(@conn, :index, @user), class: "card__morelink" %>
    <% end %>

    <%= if @total_jobs > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Experience" %>

    <%= if @total_jobs > 0 do %>
    <%= render Vutuv.WorkExperienceView, "card_list.html", assigns %>

    <% else %>

    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_work_experience_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_jobs>3 do %> | <% end %>
      <%= if @total_jobs>3 do %>
        <%= link gettext("View All"), to: user_work_experience_path(@conn, :index, @user) %>
      <% end %>

  <% end %>

  <%= if @total_numbers > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Phone Numbers" %>

    <%= if @total_numbers > 0 do %>
    <%= render Vutuv.PhoneNumberView, "card_list.html", phone_numbers: @user.phone_numbers, user: @user, conn: @conn, current_user: @current_user %>
    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_phone_number_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_numbers > 3 do %> | <% end %>
      <%= if @total_numbers>3 do %>
        <%= link gettext("View All"), to: user_phone_number_path(@conn, :index, @user) %>
      <% end %>

  <% end %>

  <%= if @total_links > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Links" %>

    <%= if @total_links > 0 do %>
    <%= render Vutuv.UrlView, "card_list.html", urls: @user.urls, user: @user, conn: @conn, current_user: @current_user %>
    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_url_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_links > 3 do %> | <% end %>
      <%= if @total_links>3 do %>
        <%= link gettext("View All"), to: user_url_path(@conn, :index, @user) %>
      <% end %>

  <% end %>

  <%= if @total_addresses > 0 or same_user?(@user, @current_user) do %>

<%= gettext "Addresses" %>

    <%= if @total_addresses > 0 do %>
    <%= render Vutuv.AddressView, "card_list.html", addresses: @user.addresses, user: @user, conn: @conn, current_user: @current_user %>
    <% end %>

      <%= if same_user?(@user, @current_user) do %>
        <%= link gettext("Add"), to: user_address_path(@conn, :new, @current_user) %>
      <% end %>
      <%= if same_user?(@user, @current_user) and @total_addresses > 3 do %> | <% end %>
      <%= if @total_addresses>3 do %>
        <%= link gettext("View All"), to: user_address_path(@conn, :index, @user) %>
      <% end %>

  <% end %>


use textarea for values of parameters

use textarea for values of parameters

<%= form_for @changeset, @action, fn f -> %>
  <%= if @changeset.action do %>

Oops, something went wrong! Please check the errors below.

  <% end %>

    <%= label f, :key, class: "control-label" %>
    <%= text_input f, :key, class: "form-control" %>
    <%= error_tag f, :key %>

    <%= label f, :value, class: "control-label" %>
    <%= textarea f, :value, class: "form-control" %>
    <%= error_tag f, :value %>

    <%= label f, :group, class: "control-label" %>
    <%= text_input f, :group, class: "form-control" %>
    <%= error_tag f, :group %>

    <%= label f, :feature_id, class: "control-label" %>
    <%= select f, :feature_id, map_features_for_select(@features), class: "form-control" %>
    <%= error_tag f, :feature_id %>

    <%= label f, :version_id, class: "control-label" %>
    <%= select f, :version_id, map_versions_for_select(@versions), class: "form-control" %>
    <%= error_tag f, :version_id %>

    <%= submit "Submit", class: "btn btn-primary" %>

<% end %>

<%= form_for @changeset, @action, fn f -> %>
  <%= if @changeset.action do %>

Oops, something went wrong! Please check the errors below.

  <% end %>

    <%= label f, :key, class: "control-label" %>
    <%= text_input f, :key, class: "form-control" %>
    <%= error_tag f, :key %>

    <%= label f, :value, class: "control-label" %>
    <%= text_input f, :value, class: "form-control" %>
    <%= error_tag f, :value %>

    <%= label f, :group, class: "control-label" %>
    <%= text_input f, :group, class: "form-control" %>
    <%= error_tag f, :group %>

    <%= label f, :feature_id, class: "control-label" %>
    <%= select f, :feature_id, map_features_for_select(@features), class: "form-control" %>
    <%= error_tag f, :feature_id %>

    <%= label f, :version_id, class: "control-label" %>
    <%= select f, :version_id, map_versions_for_select(@versions), class: "form-control" %>
    <%= error_tag f, :version_id %>

    <%= submit "Submit", class: "btn btn-primary" %>

<% end %>