├── .gitignore ├── README.md ├── biome.sh ├── circle.yml ├── logo.png ├── logo.svg └── test ├── command.bats ├── get_project.bats └── test_helper.bash /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | Biomefile 3 | defaults.sh 4 | .DS_Store 5 | *.swo 6 | *.swp 7 | coverage/ 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://github.com/1egoman/biome) 2 | 3 | Biome is a tool that creates isolated containers for your app's environment variables. 4 | 5 | [![CircleCI](https://circleci.com/gh/1egoman/biome.svg?style=shield)](https://circleci.com/gh/1egoman/biome) 6 | 7 | ## Introduction 8 | Typically, one stores all their environment variables in `.env` (or something similar), and sources 9 | them in, before running their app. This is bad for two reasons: 10 | 11 | 1. Forgot to gitignore your `.env` file? Time to regenerate all your secrets. 12 | 2. If you need to re-clone your project, you have to reconstruct your environment. 13 | 14 | Biome takes a different approach. Biome creates separate "environments" for each of your app's 15 | configurations to live in. Each environment can easily be sourced to bring in all of your app's 16 | secrets. Each app's configuration lives in `~/.biome/app_name.sh` - all secrets live far away from 17 | code. Within each project is a `Biomefile` that references the container name in `~/.biome`, and 18 | this file is version controlled along with your code. Combining these two files allow new users to 19 | easily construct their own version of your environment. 20 | 21 | ## Install 22 | ```bash 23 | brew tap 1egoman/tap 24 | brew install biome 25 | ``` 26 | 27 | or, here's a 1-liner to install it in `/usr/local/bin/biome`: 28 | ```bash 29 | curl https://raw.githubusercontent.com/1egoman/biome/master/biome.sh > /tmp/biome && sudo install -m 555 /tmp/biome /usr/local/bin/ && rm -f /tmp/biome 30 | ``` 31 | For help, run `biome help`. 32 | 33 | ## Quickstart 34 | First, create a new environment by running `biome init`: 35 | ``` 36 | Name of project? biome-project 37 | Enter a variable name you'd like to add. FOO 38 | Enter FOO's default value, or leave empty for none. default value 39 | Enter a variable name you'd like to add. 40 | 41 | Ok, let's set up your local environment. 42 | Value for FOO? (default value) bar 43 | The environment biome-project has been created. 44 | To start this environment, run biome use. 45 | ``` 46 | 47 | Then, to open your environment, run `biome use`. You'll get a shell with the variables defined that 48 | you specified in the previous command. Exit the shell with `exit`. 49 | 50 | To learn more, run `biome help`: 51 | ``` 52 | usage: biome 53 | 54 | Commands: 55 | init [-h] Create a new environment for the project in the current directory. Use the -h|--hidden flag to use a hidden .Biomefile. 56 | edit Edit the environment in the current directory. 57 | use Spawn a subshell with the project in the cwd's sourced environment. 58 | inject Update a new environment with changes since it has been activated with biome use. 59 | rm Delete a project's environment so it can be reconfigured. 60 | (no command) Given the template specified in the Biomefile, creates a new environment for your app. 61 | 62 | Set up a new project: 63 | - Run biome init to make a new environment. You'll be prompted for a name and the default configuration. 64 | - Run biome use to try out your new environment. Leave the environment by running exit. 65 | - Make any changes to your environment with biome edit 66 | 67 | Create a new environment in a project that already uses Biome: 68 | - Run biome. You'll be prompted for all the configuration values that the Biomefile contains. 69 | - Run biome use to try out your new environment. Leave the environment by running exit. 70 | ``` 71 | 72 | ## Projects and Organisations using Biome 73 | - [Backstroke](https://github.com/1egoman/backstroke) 74 | - [Density](https://github.com/densityco) 75 | - [Add your Project](https://github.com/1egoman/biome/issues/30) 76 | 77 | ## FAQ 78 | - **Is there an easy way to tell which environment I'm in within a shell created by biome?** 79 | Biome sets a few additional environment variables (see them with `env | grep BIOME`), one of 80 | them being `BIOME_PROJECT`. This contains the name of the current project that has been loaded from 81 | the environment. 82 | 83 | - **Do I have to install Biome globally?** 84 | No, some people choose to install Biome locally (in the root of the project), which makes the process of 85 | contributing easier for others. 86 | 87 | - **I'm facing problems using Biome. Help me!** 88 | If you can't figure out a problem on your own, leave an issue and I'll take a look. 89 | 90 | - **I want to contribute.** 91 | Great! Pull requests are always welcome. 92 | 93 | --- 94 | Created by [Ryan Gaus](http://rgaus.net) 95 | -------------------------------------------------------------------------------- /biome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set autoindent noexpandtab tabstop=4 shiftwidth=4 : 3 | # Biome is a script that manages an isolated shell environment for a project. 4 | # Written by Ryan Gaus 5 | 6 | # From the CWD, find the nearest Biomefile. 7 | # Walk backward from the pwd until the root. If there's a Biomefile, return it. 8 | # Once at the root, (where dirname of a path equals the path itself), throw an error. 9 | function get_biomefile { 10 | local find_prefix 11 | local last_find_prefix 12 | find_prefix="$(pwd)" 13 | 14 | while [[ ! -f "${find_prefix}/Biomefile" && ! -f "${find_prefix}/.Biomefile" ]]; do 15 | last_find_prefix="${find_prefix}" 16 | find_prefix="$(dirname "${last_find_prefix}")" 17 | 18 | if [[ "${find_prefix}" == "${last_find_prefix}" ]]; then 19 | return 1 # no biomefile was found 20 | fi 21 | done 22 | 23 | # Biomefile has preference over .Biomefile 24 | if [[ -f "${find_prefix}/Biomefile" ]]; then 25 | BIOMEFILE="${find_prefix}/Biomefile" 26 | else 27 | BIOMEFILE="${find_prefix}/.Biomefile" 28 | fi 29 | } 30 | 31 | function get_project { 32 | local passed_project="${1}" 33 | local passed_project_path="${HOME}/.biome/${1}.sh" 34 | 35 | # step 0: get the Biomefile path, if a project was not passed 36 | get_biomefile 37 | 38 | # step 1: if the passed project doesn't exist and there's a Biomefile, use the Biomefile. 39 | if ([[ "${passed_project}" == '' ]] || [[ ! -f "${passed_project_path}" ]]) && [[ -f "${BIOMEFILE}" ]]; then 40 | PROJECT=$(grep ^name "${BIOMEFILE}" | awk -F= '{print $2}') 41 | 42 | # if the passed project's path exists, then use the passed project 43 | elif [[ -f "${passed_project_path}" ]]; then 44 | # use passed project 45 | PROJECT="${passed_project}" 46 | 47 | # otherwise, throw an error 48 | elif [[ "${passed_project}" ]]; then 49 | echo "Error: no such project ${passed_project}." 50 | exit 2 51 | else 52 | echo "Error: please pass a project as an argument or create a Biomefile with biome init." 53 | exit 1 54 | fi 55 | 56 | PROJECT_PATH="${HOME}/.biome/${PROJECT}.sh" 57 | } 58 | 59 | function set_meta_vars { 60 | export BIOME_SHELL="true" 61 | export BIOME_PROJECT="${PROJECT}" 62 | 63 | # add the project name to the shell prompt if possible and necessary 64 | if [[ -n "${BASH_VERSION}" ]] && [[ -z "${BIOME_SHELL_INIT_CFG}" ]]; then 65 | INITIAL_PROMPT_COMMAND="${PROMPT_COMMAND}" 66 | export PROMPT_COMMAND="[[ -z \"\${BIOME_SHELL_INIT_CFG}\" ]] && PS1=\"($PROJECT) \${PS1}\"; unset PROMPT_COMMAND" 67 | fi 68 | } 69 | 70 | function unset_meta_vars { 71 | unset BIOME_SHELL 72 | unset BIOME_PROJECT 73 | 74 | # reset any modifications involving the shell prompt 75 | if [[ -n "${BASH_VERSION}" ]] && [[ -z "${BIOME_SHELL_INIT_CFG}" ]]; then 76 | PROMPT_COMMAND="${INITIAL_PROMPT_COMMAND}" 77 | fi 78 | } 79 | 80 | function get_variable { 81 | read -r -p "Enter a variable name you'd like to add, or [Enter] to finish. " VAR_NAME 82 | 83 | if [[ "${VAR_NAME}" ]]; then 84 | read -r -p "Enter ${VAR_NAME}'s default value, or leave empty for none. " VAR_DEFAULT 85 | fi 86 | } 87 | 88 | function make_template_project { 89 | cat <<-EOF > "${HOME}/.biome/${PROJECT}.sh" 90 | # A file that contains environment variables for a project 91 | # Activate me with biome use ${PROJECT} 92 | # add variables like export FOO="bar" 93 | # include other variables with source /path/to/more/vars 94 | EOF 95 | } 96 | 97 | # Get all defined variables in the Biomefile, and ask the user for their values. Stick these in 98 | # ~/.biome/${PROJECT}.sh 99 | function fetch_var_values { 100 | get_biomefile 101 | 102 | if [[ -f "${BIOMEFILE}" ]]; then 103 | while read -r -u 10 i; do 104 | if [[ ! "${i}" =~ ^# ]] && [[ "${i}" != '' ]]; then # not a comment or empty line 105 | # get the variable name, its default value 106 | VARIABLE_NAME="$(echo "${i}" | sed 's/=.*//')" 107 | VARIABLE_DEFAULT_VALUE="$(echo "${i}" | cut -f2- -d'=')" 108 | 109 | # also, get whether it's been set already. 110 | if [[ -f "${PROJECT_PATH}" ]]; then 111 | VARIABLE_ALREADY_SET="$(grep "^export ${VARIABLE_NAME}" "${PROJECT_PATH}")" 112 | else 113 | VARIABLE_ALREADY_SET='' 114 | fi 115 | 116 | if [[ "${VARIABLE_ALREADY_SET}" != '' ]] && [[ "${VARIABLE_NAME}" != "name" ]]; then 117 | echo "${VARIABLE_NAME} has been defined. Run biome edit to change its value." 118 | elif [[ "${VARIABLE_NAME}" != "name" ]]; then 119 | read -r -p "Value for ${VARIABLE_NAME}? (${VARIABLE_DEFAULT_VALUE}) " VARIABLE_VALUE 120 | 121 | # replace the value with the default if the user didn't enter anything 122 | if [[ "${VARIABLE_VALUE}" == '' ]]; then 123 | VARIABLE_VALUE=${VARIABLE_DEFAULT_VALUE} 124 | fi 125 | 126 | echo "export ${VARIABLE_NAME}=\"${VARIABLE_VALUE}\"" >> "${HOME}/.biome/${PROJECT}.sh" 127 | fi 128 | fi 129 | done 10< "${BIOMEFILE}" 130 | else 131 | echo "There isn't a Biomefile here. To create a new project, run biome init." 132 | echo "For help, run biome help." 133 | exit 2 134 | fi 135 | } 136 | 137 | # if ~/.biome doesn't exist, make it 138 | if [[ ! -d "${HOME}/.biome" ]]; then 139 | mkdir "${HOME}/.biome" 140 | 141 | # add .bash_profile code for biome child shells 142 | if [[ -n "${BASH_VERSION}" ]] && [[ -f "${HOME}/.bash_profile" ]]; then 143 | echo -e " 144 | # biome configuration 145 | export BIOME_SHELL_INIT_CFG=\"true\" 146 | if [[ ! -z \"\${BIOME_PROJECT}\" ]]; then 147 | export PS1=\"(\${BIOME_PROJECT}) \${PS1}\" 148 | fi" >> ~/.bash_profile 149 | fi 150 | fi 151 | 152 | # Parse the arguments for flags 153 | for arg in "${@}"; do 154 | case ${arg} in 155 | -h|--hidden) HIDDEN=true;; 156 | esac 157 | done 158 | 159 | # all the different subcommands 160 | case ${1} in 161 | # Install all variables into the global project config 162 | '') 163 | get_project "${2}" 164 | fetch_var_values 165 | echo "All variables for ${PROJECT} have been defined. To start this environment, run biome use." 166 | ;; 167 | 168 | # given a project, source it into the current shell. Creates a 'biome shell'. 169 | use) 170 | get_project "${@:2}" # allow mutltiple words 171 | echo "Sourcing ${PROJECT} from ${PROJECT_PATH}" 172 | 173 | # Spawn a new shell 174 | set_meta_vars 175 | bash -c "$(cat "${PROJECT_PATH}") && ${SHELL} -l" 176 | unset_meta_vars 177 | ;; 178 | 179 | # When in a biome shell, update variables to their latest values. 180 | # For example: 181 | # biome use 182 | # $ # change the defined values with biome edit 183 | # $ . biome inject 184 | # $ # now the values are updated following edits 185 | inject) 186 | # is being sourced? 187 | if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then 188 | echo "Error: please source this script by either running \`. biome inject\` or \`source biome inject\`" 189 | exit 1 190 | fi 191 | 192 | 193 | # if already inside of a biome shell, update its contents. 194 | if [[ "${BIOME_PROJECT}" != '' ]]; then 195 | BIOME_PROJECT_NO_WHITESPACE="$(echo "${BIOME_PROJECT}" | sed 's/ //g')" 196 | PROJECT_PATH="${HOME}/.biome/${BIOME_PROJECT_NO_WHITESPACE}.sh" 197 | source "${PROJECT_PATH}" 198 | echo "Injected data from ${BIOME_PROJECT_NO_WHITESPACE}." 199 | else 200 | echo "Not in a Biome shell. Run \`biome use\` to enter one with your current config." 201 | fi 202 | ;; 203 | 204 | # edit a specified project 205 | edit) 206 | get_project "${2}" 207 | 208 | if [[ "${EDITOR}" ]]; then 209 | "${EDITOR}" "${PROJECT_PATH}" 210 | else 211 | vi "${PROJECT_PATH}" 212 | fi 213 | 214 | echo "Note: if you have any biome sessions open, make sure you run biome inject to copy any 215 | edits you just made to each session." 216 | ;; 217 | 218 | # Create a new local Biomefile and associated template 219 | init) 220 | get_biomefile 221 | 222 | if [[ ! -f "${BIOMEFILE}" ]]; then 223 | read -r -p "Name of project? " PROJECT 224 | PROJECT_PATH="${HOME}/.biome/${PROJECT}.sh" 225 | 226 | if [[ -f "${PROJECT_PATH}" ]]; then 227 | # when it already exists... 228 | echo "This project already exists. If you'd like to overwrite it, run rm ~/.biome/${PROJECT}.sh then run this again." 229 | else 230 | if [[ ${HIDDEN} == true ]]; then 231 | BIOMEFILENAME=".Biomefile"; 232 | else 233 | BIOMEFILENAME="Biomefile"; 234 | fi 235 | 236 | echo "# This is a Biomefile. It helps you create an environment to run this app." > "${BIOMEFILENAME}" 237 | echo "# More info at https://github.com/1egoman/biome" >> "${BIOMEFILENAME}" 238 | echo "name=${PROJECT}" >> "${BIOMEFILENAME}" 239 | 240 | # get variables 241 | get_variable 242 | while [[ "${VAR_NAME}" ]]; do 243 | echo "${VAR_NAME}=${VAR_DEFAULT}" >> "${BIOMEFILENAME}" 244 | get_variable 245 | done 246 | 247 | # create a new project 248 | make_template_project 249 | echo 250 | echo "Ok, let's set up your local environment." 251 | fetch_var_values 252 | 253 | # make a commit with git 254 | echo "The environment ${PROJECT} has been created. To start this environment, run biome use." 255 | fi 256 | else 257 | echo "Error: Biomefile exists. To start using this environment on your system run 'biome'" 258 | exit 3 259 | fi 260 | ;; 261 | 262 | # Nuke the specified project's environment and Biomefile 263 | rm) 264 | get_project "${2}" 265 | if [[ -f "${HOME}/.biome/${PROJECT}.sh" ]]; then 266 | rm "${HOME}/.biome/${PROJECT}.sh" 267 | echo "Removed your environment. Run biome to re-configure." 268 | else 269 | echo "Error: There isn't an environment for this project." 270 | exit 2 271 | fi 272 | ;; 273 | 274 | help) 275 | echo "usage: biome " 276 | echo 277 | echo "Commands:" 278 | echo -e " init [-h|--hidden]\\tCreate a new environment for the project in the current directory. Use --hidden flag to use a hidden .Biomefile." 279 | echo -e " edit\\tEdit the environment in the current directory." 280 | echo -e " use\\tSpawn a subshell with the project in the cwd's sourced environment." 281 | echo -e " inject\\tUpdate a new environment with changes since it has been activated with biome use." 282 | echo -e " rm\\tDelete a project's environment so it can be reconfigured." 283 | echo -e " (no command)\\tGiven the template specified in the Biomefile, create a new environment for your app." 284 | echo 285 | echo "Set up a new project:" 286 | echo " - Run biome init to make a new environment. You'll be prompted for a name and the default configuration." 287 | echo " - Run biome use to try out your new environment. Leave the environment by running exit." 288 | echo " - Make any changes to your environment with biome edit" 289 | echo 290 | echo "Create a new environment in a project that already uses Biome:" 291 | echo " - Run biome. You'll be prompted for all the configuration values that the Biomefile contains." 292 | echo " - Run biome use to try out your new environment. Leave the environment by running exit." 293 | echo 294 | ;; 295 | 296 | *) 297 | echo "Hmm, I don't know how to do that. Run biome help for assistance." 298 | exit 1 299 | ;; 300 | 301 | esac 302 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | override: 3 | - "sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe'" 4 | - "sudo apt-get update" 5 | - "sudo apt-get install shellcheck" 6 | 7 | checkout: 8 | post: 9 | - git clone https://github.com/sstephenson/bats.git 10 | - cd bats && sudo ./install.sh /usr/local 11 | 12 | test: 13 | override: 14 | - shellcheck --exclude=SC1090,SC2001 biome.sh 15 | - bats --tap test/ 16 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1egoman/biome/582849be7e1600dbd20dab3d4fa7d15426b570c4/logo.png -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/command.bats: -------------------------------------------------------------------------------- 1 | #!/bin/env bats 2 | # vim: set autoindent noexpandtab tabstop=4 shiftwidth=4 : 3 | # a quick note: this file uses tabs to ensure that <<-EOF will work properly. Please use tabs too! 4 | load test_helper 5 | 6 | # ---------------------------------------------------------------------------- 7 | # biome init 8 | # ------------------------------------------------------------------------------ 9 | @test "biome init will initialize a new project" { 10 | INPUT="$(cat <<-EOF 11 | my_app 12 | FOO 13 | bar 14 | 15 | baz 16 | EOF)" 17 | 18 | echo "$INPUT" | $BIOME init 19 | 20 | chmod 700 "$HOME/.biome/my_app.sh" 21 | $(cmp $HOME/.biome/my_app.sh <<-EOF 22 | # A file that contains environment variables for a project 23 | # Activate me with biome use my_app 24 | # add variables like export FOO="bar" 25 | # include other variables with source /path/to/more/vars 26 | export FOO="baz" 27 | EOF) 28 | } 29 | 30 | @test "biome init --hidden will initialize a new project with a .Biomefile" { 31 | INPUT="$(cat <<-EOF 32 | my_app 33 | 34 | EOF)" 35 | 36 | echo "$INPUT" | $BIOME init --hidden 37 | 38 | chmod 700 "./.Biomefile" 39 | $(cmp ./.Biomefile <<-EOF 40 | # This is a Biomefile. It helps you create an environment to run this app 41 | # More info at https://github.com/1egoman/biome 42 | name=my_app 43 | EOF) 44 | } 45 | 46 | @test "biome init will fail with a Biomefile" { 47 | touch Biomefile 48 | 49 | run $BIOME init 50 | [[ "$status" != 0 ]] 51 | } 52 | 53 | @test "biome init will fail with a preexisting environment" { 54 | echo "name=my_app" > Biomefile 55 | mkdir -p $HOME/.biome 56 | touch "$HOME/.biome/my_app.sh" 57 | 58 | run $BIOME init 59 | [[ "$status" != 0 ]] 60 | } 61 | 62 | # ---------------------------------------------------------------------------- 63 | # biome 64 | # ------------------------------------------------------------------------------ 65 | 66 | @test "biome will create the environment that's defined in the Biomefile" { 67 | cat <<-EOF > Biomefile 68 | name=my_app 69 | FOO=hello 70 | BAR=world 71 | BAZ= 72 | EOF 73 | 74 | INPUT="$(cat <<-EOF 75 | data 76 | 77 | more data 78 | EOF)" 79 | echo "$INPUT" | $BIOME 80 | 81 | chmod 700 "$HOME/.biome/my_app.sh" 82 | $(cmp $HOME/.biome/my_app.sh <<-EOF 83 | export FOO="data" 84 | export BAR="world" 85 | export FOO="more data" 86 | EOF) 87 | } 88 | 89 | @test "biome will create the environment that's defined in the Biomefile, with whitespace" { 90 | cat <<-EOF > Biomefile 91 | name=my_app 92 | 93 | FOO=hello 94 | 95 | BAR=world 96 | BAZ= 97 | EOF 98 | 99 | INPUT="$(cat <<-EOF 100 | data 101 | 102 | more data 103 | EOF)" 104 | echo "$INPUT" | $BIOME 105 | 106 | chmod 700 "$HOME/.biome/my_app.sh" 107 | $(cmp $HOME/.biome/my_app.sh <<-EOF 108 | export FOO="data" 109 | export BAR="world" 110 | export FOO="more data" 111 | EOF) 112 | } 113 | 114 | @test "biome will create the environment that's defined in the .Biomefile" { 115 | cat <<-EOF > .Biomefile 116 | name=my_app 117 | FOO=hello 118 | BAR=world 119 | BAZ= 120 | EOF 121 | 122 | INPUT="$(cat <<-EOF 123 | data 124 | 125 | more data 126 | EOF)" 127 | echo "$INPUT" | $BIOME 128 | 129 | chmod 700 "$HOME/.biome/my_app.sh" 130 | $(cmp $HOME/.biome/my_app.sh <<-EOF 131 | export FOO="data" 132 | export BAR="world" 133 | export FOO="more data" 134 | EOF) 135 | } 136 | 137 | @test "biome will create the environment that's defined in the Biomefile should both a Biomefile and a .Biomefile be present" { 138 | cat <<-EOF > .Biomefile 139 | name=my_app 140 | FOO=hello 141 | BAR=world 142 | BAZ=hidden 143 | EOF 144 | 145 | cat <<-EOF > Biomefile 146 | name=my_app 147 | FOO=hello 148 | BAR=biome 149 | BAZ=visible 150 | EOF 151 | 152 | INPUT="$(cat <<-EOF 153 | 154 | EOF)" 155 | echo "$INPUT" | $BIOME 156 | 157 | chmod 700 "$HOME/.biome/my_app.sh" 158 | $(cmp $HOME/.biome/my_app.sh <<-EOF 159 | export FOO="hello" 160 | export BAR="biome" 161 | export FOO="visible" 162 | EOF) 163 | } 164 | 165 | @test "biome will append to an already existing environment" { 166 | # create Biomefile ane pre-initialized data 167 | cat <<-EOF > Biomefile 168 | name=my_app 169 | ALREADY_EXISTS= 170 | FOO=hello 171 | BAR=world 172 | BAZ= 173 | EOF 174 | 175 | mkdir -p "$HOME/.biome" 176 | 177 | cat <<-EOF > $HOME/.biome/my_app.sh 178 | export ALREADY_EXISTS="hello" 179 | EOF 180 | 181 | INPUT="$(cat <<-EOF 182 | data 183 | 184 | more data 185 | EOF)" 186 | echo "$INPUT" | $BIOME 187 | 188 | chmod 700 "$HOME/.biome/my_app.sh" 189 | $(cmp $HOME/.biome/my_app.sh <<-EOF 190 | export ALREADY_EXISTS="hello" 191 | export FOO="data" 192 | export BAR="world" 193 | export FOO="more data" 194 | EOF) 195 | } 196 | 197 | # ---------------------------------------------------------------------------- 198 | # biome rm 199 | # ------------------------------------------------------------------------------ 200 | 201 | @test "biome rm will remove an environment" { 202 | # create Biomefile ane pre-initialized data 203 | cat <<-EOF > Biomefile 204 | name=my_app 205 | EOF 206 | 207 | mkdir -p "$HOME/.biome" 208 | 209 | cat <<-EOF > $HOME/.biome/my_app.sh 210 | export A_VARIABLE="value" 211 | EOF 212 | 213 | $BIOME rm 214 | 215 | # make sure the environment doesn't exist 216 | run cat "$HOME/.biome/my_app.sh" 217 | [[ "$status" != 0 ]] 218 | 219 | # but also that the Biomefile does exist 220 | [[ "$(cat Biomefile)" == "name=my_app" ]] 221 | } 222 | @test "biome rm won't delete a non-existant environment" { 223 | # create Biomefile ane pre-initialized data 224 | cat <<-EOF > Biomefile 225 | name=my_app 226 | EOF 227 | 228 | mkdir -p "$HOME/.biome" 229 | # no environment 230 | 231 | run $BIOME rm 232 | [[ "$status" != 0 ]] 233 | 234 | # but also that the Biomefile does exist 235 | [[ "$(cat Biomefile)" == "name=my_app" ]] 236 | } 237 | @test "biome rm won't delete a non-existant environment (no .biome folder)" { 238 | # create Biomefile ane pre-initialized data 239 | cat <<-EOF > Biomefile 240 | name=my_app 241 | EOF 242 | # no environment 243 | 244 | run $BIOME rm 245 | [[ "$status" != 0 ]] 246 | 247 | # but also that the Biomefile does exist 248 | [[ "$(cat Biomefile)" == "name=my_app" ]] 249 | } 250 | 251 | # ---------------------------------------------------------------------------- 252 | # biome use 253 | # ------------------------------------------------------------------------------ 254 | 255 | @test "biome use will spawn a subshell with the correct environment vars set" { 256 | # create Biomefile ane pre-initialized data 257 | cat <<-EOF > Biomefile 258 | name=my_app 259 | EOF 260 | 261 | mkdir -p "$HOME/.biome" 262 | 263 | cat <<-EOF > $HOME/.biome/my_app.sh 264 | export A_VARIABLE="value" 265 | export ANOTHER="content with spaces" 266 | EOF 267 | 268 | # log all environment variables within the shell to ~/environment 269 | OLDSHELL="$SHELL" 270 | SHELL="bash -c 'env > $HOME/environment'" 271 | run $BIOME use # use run so the command will always run so the shell can be reset 272 | SHELL="$OLDSHELL" 273 | 274 | chmod 700 $HOME/.biome/my_app.sh 275 | # these variables should be set 276 | [[ "$(cat $HOME/environment | grep A_VARIABLE=value)" != "" ]] && 277 | [[ "$(cat $HOME/environment | grep ANOTHER=content\ with\ spaces)" != "" ]] && 278 | [[ "$(cat $HOME/environment | grep BIOME_SHELL=true)" != "" ]] && 279 | [[ "$(cat $HOME/environment | grep BIOME_PROJECT=my_app)" != "" ]]; 280 | } 281 | 282 | @test "biome use modifies the command prompt to include the project name" { 283 | # create Biomefile with pre-initialized data 284 | cat <<-EOF > Biomefile 285 | name=my_app 286 | EOF 287 | 288 | mkdir -p "$HOME/.biome" 289 | 290 | cat <<-EOF > $HOME/.biome/my_app.sh 291 | export A_VARIABLE="value" 292 | export ANOTHER="content with spaces" 293 | EOF 294 | 295 | # log the prompt to ~/prompt 296 | OLDSHELL="$SHELL" 297 | SHELL="bash -c 'echo \"$PS1\" > $HOME/prompt'" 298 | run $BIOME use # use run so the command will always run so the shell can be reset 299 | SHELL="$OLDSHELL" 300 | 301 | chmod 700 $HOME/.biome/my_app.sh 302 | [[ "$(cat $HOME/prompt)" != "(my_app)"* ]]; 303 | } 304 | 305 | # ---------------------------------------------------------------------------- 306 | # biome help 307 | # ------------------------------------------------------------------------------ 308 | 309 | @test "biome help will show help" { 310 | run $BIOME help 311 | [[ "$status" == 0 ]] && 312 | [[ "${lines[0]}" == "usage: biome " ]] 313 | } 314 | 315 | @test "biome will fail for an unknown command" { 316 | run $BIOME something-unknown 317 | [[ "$status" != 0 ]] && 318 | [[ "${lines[0]}" = "Hmm, I don't know how to do that. Run biome help for assistance." ]] 319 | } 320 | 321 | # ---------------------------------------------------------------------------- 322 | # biome inject 323 | # ---------------------------------------------------------------------------- 324 | @test "biome inject will update a biome session" { 325 | # create Biomefile ane pre-initialized data 326 | cat <<-EOF > Biomefile 327 | name=my_app 328 | EOF 329 | 330 | mkdir -p "$HOME/.biome" 331 | 332 | cat <<-EOF > $HOME/.biome/my_app.sh 333 | export FOO="bar" 334 | EOF 335 | 336 | # log all environment variables within the shell to ~/environment 337 | OLDSHELL="$SHELL" 338 | SHELL="bash -c 'env > $HOME/pre && echo \"export a=b\" >> $HOME/.biome/my_app.sh && . $BIOME inject && env > $HOME/post'" 339 | run $BIOME use # use run so the command will always run so the shell can be reset 340 | SHELL="$OLDSHELL" 341 | 342 | # these variables should be set 343 | # They need to be pinned to the front because the $SHELL also contains the variable declaration 344 | [[ "$(cat $HOME/pre | grep ^a=b)" == "" ]] && # should not be updated at start 345 | [[ "$(cat $HOME/post | grep ^a=b)" != "" ]]; # should be updated by the end 346 | } 347 | 348 | 349 | # ---------------------------------------------------------------------------- 350 | # Biomefile nesting 351 | # (Make sure that Biome can find, for example, ../Biomefile) 352 | # ---------------------------------------------------------------------------- 353 | @test "biome should be able to find a biomefile that is nested 1 level below the current cwd" { 354 | echo "name=my_app" > ../Biomefile 355 | mkdir -p "$HOME/.biome" 356 | touch "$HOME/.biome/my_app.sh" 357 | 358 | run $BIOME use my_app 359 | [[ "$status" == "0" ]] 360 | rm ../Biomefile 361 | } 362 | 363 | @test "biome should be able to find a .Biomefile that is nested 1 level below the current cwd" { 364 | echo "name=my_app" > ../.Biomefile 365 | mkdir -p "$HOME/.biome" 366 | touch "$HOME/.biome/my_app.sh" 367 | 368 | run $BIOME use my_app 369 | [[ "$status" == "0" ]] 370 | rm ../.Biomefile 371 | } 372 | 373 | @test "biome should be able to find a biomefile that is nested multiple levels below the current cwd" { 374 | echo "name=my_app" > ../../Biomefile 375 | mkdir -p "$HOME/.biome" 376 | touch "$HOME/.biome/my_app.sh" 377 | 378 | run $BIOME use my_app 379 | [[ "$status" == 0 ]] 380 | rm ../../Biomefile 381 | } 382 | 383 | @test "biome should be able to find a .Biomefile that is nested multiple levels below the current cwd" { 384 | echo "name=my_app" > ../../.Biomefile 385 | mkdir -p "$HOME/.biome" 386 | touch "$HOME/.biome/my_app.sh" 387 | 388 | run $BIOME use my_app 389 | [[ "$status" == 0 ]] 390 | rm ../../.Biomefile 391 | } 392 | 393 | @test "biome fails when a biomefile does not exist at any level" { 394 | mkdir -p "$HOME/.biome" 395 | touch "$HOME/.biome/my_app.sh" 396 | 397 | run $BIOME use 398 | [[ "$status" != 0 ]] 399 | } 400 | 401 | @test "biome works when a user biome use's with an environment as an arg" { 402 | mkdir -p "$HOME/.biome" 403 | touch "$HOME/.biome/my_app.sh" 404 | 405 | run $BIOME use my_app 406 | [[ "$status" == 0 ]] 407 | } 408 | 409 | # ---------------------------------------------------------------------------- 410 | # Biomefile envionment names with spaces 411 | # ---------------------------------------------------------------------------- 412 | @test "biome should be able to handle spaces in an environment name" { 413 | # create Biomefile ane pre-initialized data 414 | cat <<-EOF > Biomefile 415 | name=my app 416 | EOF 417 | 418 | mkdir -p "$HOME/.biome" 419 | 420 | cat <<-EOF > "$HOME/.biome/my app.sh" 421 | export A_VARIABLE="value" 422 | export ANOTHER="content with spaces" 423 | EOF 424 | 425 | # log all environment variables within the shell to ~/environment 426 | OLDSHELL="$SHELL" 427 | SHELL="bash -c 'env > $HOME/environment'" 428 | run $BIOME use # use run so the command will always run so the shell can be reset 429 | SHELL="$OLDSHELL" 430 | 431 | chmod 700 "$HOME/.biome/my app.sh" 432 | # these variables should be set 433 | [[ "$(cat $HOME/environment | grep A_VARIABLE=value)" != "" ]] && 434 | [[ "$(cat $HOME/environment | grep ANOTHER=content\ with\ spaces)" != "" ]] && 435 | [[ "$(cat $HOME/environment | grep BIOME_SHELL=true)" != "" ]] && 436 | [[ "$(cat $HOME/environment | grep BIOME_PROJECT=my\ app)" != "" ]]; 437 | } 438 | @test "biome should be able to use an environment with spaces" { 439 | # create Biomefile ane pre-initialized data 440 | cat <<-EOF > Biomefile 441 | name=my app 442 | EOF 443 | 444 | mkdir -p "$HOME/.biome" 445 | 446 | cat <<-EOF > "$HOME/.biome/my app.sh" 447 | export A_VARIABLE="value" 448 | export ANOTHER="content with spaces" 449 | EOF 450 | 451 | # log all environment variables within the shell to ~/environment 452 | OLDSHELL="$SHELL" 453 | SHELL="bash -c 'env > $HOME/environment'" 454 | run $BIOME use "my app" # use run so the command will always run so the shell can be reset 455 | SHELL="$OLDSHELL" 456 | 457 | chmod 700 "$HOME/.biome/my app.sh" 458 | # these variables should be set 459 | [[ "$(cat $HOME/environment | grep A_VARIABLE=value)" != "" ]] && 460 | [[ "$(cat $HOME/environment | grep ANOTHER=content\ with\ spaces)" != "" ]] && 461 | [[ "$(cat $HOME/environment | grep BIOME_SHELL=true)" != "" ]] && 462 | [[ "$(cat $HOME/environment | grep BIOME_PROJECT=my\ app)" != "" ]]; 463 | } 464 | 465 | 466 | HOME="$OLDHOME" 467 | -------------------------------------------------------------------------------- /test/get_project.bats: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | load test_helper 3 | 4 | @test "get_project should get a project by a passed name" { 5 | mkdir -p "$HOME/.biome" 6 | cat <<-EOF > $HOME/.biome/my_app.sh 7 | export A_VARIABLE="value" 8 | EOF 9 | 10 | $BIOME rm my_app 11 | 12 | run cat $HOME/.biome/my_app.sh # (the file should not exist) 13 | [[ "$status" == 1 ]] 14 | } 15 | 16 | @test "get_project should get a project by an implicit Biomefile" { 17 | cat <<-EOF > Biomefile 18 | name=my_app 19 | EOF 20 | 21 | mkdir -p "$HOME/.biome" 22 | 23 | cat <<-EOF > $HOME/.biome/my_app.sh 24 | export A_VARIABLE="value" 25 | EOF 26 | 27 | $BIOME rm 28 | 29 | run cat "$HOME/.biome/my_app.sh" # (the file should not exist) 30 | [[ "$status" == 1 ]] 31 | } 32 | 33 | @test "get_project should use the passed project over the Biomefile" { 34 | cat <<-EOF > Biomefile 35 | name=some_other_app 36 | EOF 37 | mkdir -p "$HOME/.biome" 38 | cat <<-EOF > $HOME/.biome/my_app.sh 39 | export A_VARIABLE="value" 40 | EOF 41 | 42 | $BIOME rm my_app 43 | 44 | run cat "$HOME/.biome/my_app.sh" # (the file should not exist) 45 | [[ "$status" == 1 ]] 46 | } 47 | 48 | @test "get_project should fail without a Biomefile or passed project" { 49 | # no Biomefile 50 | run $BIOME rm 51 | [[ "$status" == 1 ]] 52 | } 53 | -------------------------------------------------------------------------------- /test/test_helper.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # run before each test 4 | function setup { 5 | BIOME="$(pwd)/biome.sh" 6 | TEST_ROOT="$(pwd)/test" 7 | clean_test 8 | } 9 | 10 | # reset the test state 11 | function clean_test { 12 | cd $TEST_ROOT 13 | [[ -d workspace/ ]] && rm -rf workspace/ 14 | 15 | mkdir -p workspace/cwd 16 | mkdir -p workspace/home 17 | 18 | chmod -R 777 workspace/ 19 | 20 | OLDHOME="$HOME" 21 | HOME="$(pwd)/workspace/home" 22 | cd workspace/cwd 23 | } 24 | --------------------------------------------------------------------------------