├── LICENSE ├── README.md ├── bin ├── compile ├── detect └── release ├── elixir_buildpack.config └── lib ├── app_funcs.sh ├── elixir_funcs.sh ├── erlang_funcs.sh ├── misc_funcs.sh └── path_funcs.sh /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Akash Manohar J 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloud Foundry Buildpack for Elixir 2 | 3 | DEPRECATED, please use [https://github.com/HashNuke/heroku-buildpack-elixir](https://github.com/HashNuke/heroku-buildpack-elixir) 4 | -------------------------------------------------------------------------------- /bin/compile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # usage: bin/compile 3 | 4 | # If this var is set to true later on, 5 | # then elixir and rebar will be rebuilt 6 | erlang_changed=false 7 | rebar_changed=false 8 | elixir_changed=false 9 | 10 | build_pack_path=$(cd $(dirname $(dirname $0)); pwd) 11 | 12 | # Ensure dirs are present 13 | mkdir -p $1 $2 14 | 15 | build_path=$(cd $1 && pwd) 16 | cache_path=$(cd $2 && pwd) 17 | 18 | source ${build_pack_path}/lib/path_funcs.sh 19 | source ${build_pack_path}/lib/misc_funcs.sh 20 | source ${build_pack_path}/lib/erlang_funcs.sh 21 | source ${build_pack_path}/lib/elixir_funcs.sh 22 | source ${build_pack_path}/lib/app_funcs.sh 23 | 24 | mkdir $(platform_tools_path) 25 | 26 | load_config 27 | export_config_vars 28 | export_mix_env 29 | 30 | clean_cache 31 | 32 | download_erlang 33 | install_erlang 34 | 35 | download_elixir 36 | install_elixir 37 | restore_mix 38 | install_hex 39 | install_rebar 40 | 41 | pre_compile_hook 42 | 43 | restore_app 44 | app_dependencies 45 | copy_hex 46 | compile_app 47 | backup_app 48 | backup_mix 49 | write_profile_d_script 50 | write_export 51 | 52 | post_compile_hook 53 | -------------------------------------------------------------------------------- /bin/detect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # bin/detect 3 | set -e 4 | 5 | mix_file_url="$1/mix.exs" 6 | 7 | if [ -f $mix_file_url ]; 8 | then 9 | echo "Elixir" 10 | exit 0 11 | else 12 | exit 1 13 | fi 14 | -------------------------------------------------------------------------------- /bin/release: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # bin/release 3 | 4 | echo "--- {}" 5 | -------------------------------------------------------------------------------- /elixir_buildpack.config: -------------------------------------------------------------------------------- 1 | erlang_version=19.1 2 | elixir_version=1.3.4 3 | always_rebuild=false 4 | config_vars_to_export=(DATABASE_URL) 5 | runtime_path=/app 6 | -------------------------------------------------------------------------------- /lib/app_funcs.sh: -------------------------------------------------------------------------------- 1 | function restore_app() { 2 | if [ -d $(deps_backup_path) ]; then 3 | cp -pR $(deps_backup_path) ${build_path}/deps 4 | fi 5 | 6 | if [ $erlang_changed != true ] && [ $elixir_changed != true ]; then 7 | if [ -d $(build_backup_path) ]; then 8 | cp -pR $(build_backup_path) ${build_path}/_build 9 | fi 10 | fi 11 | } 12 | 13 | 14 | function copy_hex() { 15 | mkdir -p ${build_path}/.mix/archives 16 | mkdir -p ${build_path}/.hex 17 | 18 | 19 | # hex is a directory from elixir-1.3.0 20 | full_hex_file_path=$(ls -dt ${HOME}/.mix/archives/hex-* | head -n 1) 21 | 22 | # hex file names after elixir-1.1 in the hex-.ez form 23 | if [ -z "$full_hex_file_path" ]; then 24 | full_hex_file_path=$(ls -t ${HOME}/.mix/archives/hex-*.ez | head -n 1) 25 | fi 26 | 27 | # For older versions of hex which have no version name in file 28 | if [ -z "$full_hex_file_path" ]; then 29 | full_hex_file_path=${HOME}/.mix/archives/hex.ez 30 | fi 31 | 32 | cp ${HOME}/.hex/registry.ets ${build_path}/.hex/ 33 | 34 | output_section "Copying hex from $full_hex_file_path" 35 | cp -R $full_hex_file_path ${build_path}/.mix/archives 36 | } 37 | 38 | 39 | function app_dependencies() { 40 | # Unset this var so that if the parent dir is a git repo, it isn't detected 41 | # And all git operations are performed on the respective repos 42 | local git_dir_value=$GIT_DIR 43 | unset GIT_DIR 44 | 45 | cd $build_path 46 | output_section "Fetching app dependencies with mix" 47 | mix deps.get --only $MIX_ENV || exit 1 48 | 49 | export GIT_DIR=$git_dir_value 50 | cd - > /dev/null 51 | } 52 | 53 | 54 | function backup_app() { 55 | # Delete the previous backups 56 | rm -rf $(deps_backup_path) $(build_backup_path) 57 | 58 | cp -pR ${build_path}/deps $(deps_backup_path) 59 | cp -pR ${build_path}/_build $(build_backup_path) 60 | } 61 | 62 | 63 | function compile_app() { 64 | local git_dir_value=$GIT_DIR 65 | unset GIT_DIR 66 | 67 | cd $build_path 68 | output_section "Compiling" 69 | mix compile || exit 1 70 | 71 | mix deps.clean --unused 72 | 73 | export GIT_DIR=$git_dir_value 74 | cd - > /dev/null 75 | } 76 | 77 | function post_compile_hook() { 78 | cd $build_path 79 | 80 | if [ -n "$post_compile" ]; then 81 | output_section "Executing post compile: $post_compile" 82 | $post_compile || exit 1 83 | fi 84 | 85 | cd - > /dev/null 86 | } 87 | 88 | function pre_compile_hook() { 89 | cd $build_path 90 | 91 | if [ -n "$pre_compile" ]; then 92 | output_section "Executing pre compile: $pre_compile" 93 | $pre_compile || exit 1 94 | fi 95 | 96 | cd - > /dev/null 97 | } 98 | 99 | function write_profile_d_script() { 100 | output_section "Creating .profile.d with env vars" 101 | mkdir -p $build_path/.profile.d 102 | 103 | local export_line="export PATH=\$HOME/.platform_tools:\$HOME/.platform_tools/erlang/bin:\$HOME/.platform_tools/elixir/bin:\$PATH 104 | export LC_CTYPE=en_US.utf8 105 | export MIX_ENV=${MIX_ENV}" 106 | 107 | echo $export_line >> $build_path/.profile.d/elixir_buildpack_paths.sh 108 | } 109 | 110 | function write_export() { 111 | output_section "Writing export for multi-buildpack support" 112 | 113 | local export_line="export PATH=$(platform_tools_path):$(erlang_path)/bin:$(elixir_path)/bin:\$PATH 114 | export LC_CTYPE=en_US.utf8 115 | export MIX_ENV=${MIX_ENV}" 116 | 117 | echo $export_line > $build_pack_path/export 118 | } 119 | -------------------------------------------------------------------------------- /lib/elixir_funcs.sh: -------------------------------------------------------------------------------- 1 | function download_elixir() { 2 | fix_elixir_version 3 | 4 | # If a previous download does not exist, then always re-download 5 | if [ ${force_fetch} = true ] || [ ! -f ${cache_path}/$(elixir_download_file) ]; then 6 | clean_elixir_downloads 7 | elixir_changed=true 8 | 9 | output_section "Fetching Elixir ${elixir_version}" 10 | 11 | local download_url="https://s3.amazonaws.com/s3.hex.pm/builds/elixir/${elixir_version}.zip" 12 | curl -s ${download_url} -o ${cache_path}/$(elixir_download_file) || exit 1 13 | else 14 | output_section "Using cached Elixir ${elixir_version}" 15 | fi 16 | } 17 | 18 | function install_elixir() { 19 | output_section "Installing Elixir ${elixir_version} $(elixir_changed)" 20 | 21 | mkdir -p $(elixir_path) 22 | cd $(elixir_path) 23 | 24 | if type "unzip" &> /dev/null; then 25 | unzip -q ${cache_path}/$(elixir_download_file) 26 | else 27 | jar xf ${cache_path}/$(elixir_download_file) 28 | fi 29 | 30 | cd - > /dev/null 31 | 32 | chmod +x $(elixir_path)/bin/* 33 | PATH=$(elixir_path)/bin:${PATH} 34 | 35 | export LC_CTYPE=en_US.utf8 36 | } 37 | 38 | function fix_elixir_version() { 39 | if [ ${#elixir_version[@]} -eq 2 ] && [ ${elixir_version[0]} = "branch" ]; then 40 | force_fetch=true 41 | elixir_version=${elixir_version[1]} 42 | 43 | elif [ ${#elixir_version[@]} -eq 1 ]; then 44 | force_fetch=false 45 | 46 | # If we detect a version string (ex: 0.15.1) we prefix it with "v" 47 | if [[ ${elixir_version} =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then 48 | elixir_version=v${elixir_version} 49 | fi 50 | 51 | else 52 | output_line "Invalid Elixir version specified" 53 | output_line "See the README for allowed formats at:" 54 | output_line "https://github.com/gogolok/cloudfoundry-buildpack-elixir" 55 | exit 1 56 | fi 57 | } 58 | 59 | function elixir_download_file() { 60 | echo elixir-${elixir_version}.zip 61 | } 62 | 63 | function clean_elixir_downloads() { 64 | rm -rf ${cache_path}/elixir*.zip 65 | } 66 | 67 | function restore_mix() { 68 | if [ -d $(mix_backup_path) ]; then 69 | cp -pR $(mix_backup_path) ${HOME}/.mix 70 | fi 71 | 72 | if [ -d $(hex_backup_path) ]; then 73 | cp -pR $(hex_backup_path) ${HOME}/.hex 74 | fi 75 | } 76 | 77 | function backup_mix() { 78 | # Delete the previous backups 79 | rm -rf $(mix_backup_path) $(hex_backup_path) 80 | 81 | cp -pR ${HOME}/.mix $(mix_backup_path) 82 | cp -pR ${HOME}/.hex $(hex_backup_path) 83 | } 84 | 85 | function install_hex() { 86 | output_section "Installing Hex" 87 | mix local.hex --force 88 | } 89 | 90 | function install_rebar() { 91 | output_section "Installing rebar" 92 | 93 | mix local.rebar --force 94 | } 95 | 96 | function elixir_changed() { 97 | if [ $elixir_changed = true ]; then 98 | echo "(changed)" 99 | fi 100 | } 101 | -------------------------------------------------------------------------------- /lib/erlang_funcs.sh: -------------------------------------------------------------------------------- 1 | function erlang_tarball() { 2 | echo "OTP-${erlang_version}.tar.gz" 3 | } 4 | 5 | function download_erlang() { 6 | erlang_package_url="https://s3.amazonaws.com/heroku-buildpack-elixir/erlang/cedar-14" 7 | erlang_package_url="${erlang_package_url}/$(erlang_tarball)" 8 | 9 | # If a previous download does not exist, then always re-download 10 | if [ ! -f ${cache_path}/$(erlang_tarball) ]; then 11 | clean_erlang_downloads 12 | 13 | # Set this so elixir will be force-rebuilt 14 | erlang_changed=true 15 | 16 | output_section "Fetching Erlang ${erlang_version}" 17 | curl -s ${erlang_package_url} -o ${cache_path}/$(erlang_tarball) || exit 1 18 | else 19 | output_section "Using cached Erlang ${erlang_version}" 20 | fi 21 | } 22 | 23 | function clean_erlang_downloads() { 24 | rm -rf ${cache_path}/OTP-*.tar.gz 25 | } 26 | 27 | function install_erlang() { 28 | output_section "Installing Erlang ${erlang_version} $(erlang_changed)" 29 | 30 | rm -rf $(erlang_build_path) 31 | mkdir -p $(erlang_build_path) 32 | tar zxf ${cache_path}/$(erlang_tarball) -C $(erlang_build_path) --strip-components=1 33 | 34 | rm -rf $(runtime_erlang_path) 35 | mkdir -p $(runtime_platform_tools_path) 36 | ln -s $(erlang_build_path) $(runtime_erlang_path) 37 | $(erlang_build_path)/Install -minimal $(runtime_erlang_path) 38 | 39 | cp -R $(erlang_build_path) $(erlang_path) 40 | PATH=$(erlang_path)/bin:$PATH 41 | } 42 | 43 | function erlang_changed() { 44 | if [ $erlang_changed = true ]; then 45 | echo "(changed)" 46 | fi 47 | } 48 | -------------------------------------------------------------------------------- /lib/misc_funcs.sh: -------------------------------------------------------------------------------- 1 | # Outputs log line 2 | # 3 | # Usage: 4 | # 5 | # output_line "Cloning repository" 6 | # 7 | function output_line() { 8 | local spacing=" " 9 | echo "${spacing} $1" 10 | } 11 | 12 | # Outputs section heading 13 | # 14 | # Usage: 15 | # 16 | # output_section "Application tasks" 17 | # 18 | function output_section() { 19 | local indentation="----->" 20 | echo "${indentation} $1" 21 | } 22 | 23 | 24 | function load_config() { 25 | output_section "Checking Erlang and Elixir versions" 26 | 27 | local custom_config_file="${build_path}/elixir_buildpack.config" 28 | 29 | # Source for default versions file from buildpack first 30 | source "${build_pack_path}/elixir_buildpack.config" 31 | 32 | if [ -f $custom_config_file ]; 33 | then 34 | source $custom_config_file 35 | else 36 | output_line "WARNING: elixir_buildpack.config wasn't found in the app" 37 | output_line "Using default config from Elixir buildpack" 38 | fi 39 | 40 | output_line "Will use the following versions:" 41 | output_line "* Erlang ${erlang_version}" 42 | output_line "* Elixir ${elixir_version[0]} ${elixir_version[1]}" 43 | output_line "Will export the following config vars:" 44 | output_line "* Config vars ${config_vars_to_export[*]}" 45 | } 46 | 47 | 48 | # Make the config vars from config_vars_to_export available at slug compile time. 49 | # Useful for compiled languages like Erlang and Elixir 50 | function export_config_vars() { 51 | for config_var in ${config_vars_to_export[@]}; do 52 | if [ -d $env_path ] && [ -f $env_path/${config_var} ]; then 53 | export ${config_var}="$(cat $env_path/${config_var})" 54 | fi 55 | done 56 | } 57 | 58 | function export_mix_env() { 59 | if [ -z "$MIX_ENV" ]; then 60 | if [ -d $env_path ] && [ -f $env_path/MIX_ENV ]; then 61 | export MIX_ENV=$(cat $env_path/MIX_ENV) 62 | else 63 | export MIX_ENV=prod 64 | fi 65 | fi 66 | 67 | output_line "* MIX_ENV=${MIX_ENV}" 68 | } 69 | 70 | 71 | function clean_cache() { 72 | if [ $always_rebuild = true ]; then 73 | output_section "Cleaning all cache to force rebuilds" 74 | rm -rf $cache_path/* 75 | fi 76 | } 77 | -------------------------------------------------------------------------------- /lib/path_funcs.sh: -------------------------------------------------------------------------------- 1 | function platform_tools_path() { 2 | echo "${build_path}/.platform_tools" 3 | } 4 | 5 | function erlang_path() { 6 | echo "$(platform_tools_path)/erlang" 7 | } 8 | 9 | function runtime_platform_tools_path() { 10 | echo "${runtime_path}/.platform_tools" 11 | } 12 | 13 | function runtime_erlang_path() { 14 | echo "$(runtime_platform_tools_path)/erlang" 15 | } 16 | 17 | function elixir_path() { 18 | echo "$(platform_tools_path)/elixir" 19 | } 20 | 21 | function erlang_build_path() { 22 | echo "${cache_path}/erlang" 23 | } 24 | 25 | function deps_backup_path() { 26 | echo $cache_path/deps_backup 27 | } 28 | 29 | function build_backup_path() { 30 | echo $cache_path/build_backup 31 | } 32 | 33 | function mix_backup_path() { 34 | echo $cache_path/.mix 35 | } 36 | 37 | function hex_backup_path() { 38 | echo $cache_path/.hex 39 | } 40 | --------------------------------------------------------------------------------