Autoenv – Set a lasting, project-based habitat

Projects are different from one another and so are environments. We might be developing an application on our local machine with certain environment variables like debug level, API keys, or memory size. Then we want to deploy the application to a staging or production server, which has other values for the same environment variables. A tool that comes in handy for loading environments on the fly is autoenv.

To install it we go to the official GitHub page and follow the instructions:

https://github.com/kennethreitz/autoenv

First we will clone the project in our home directory, and then we add the following line to our .zshrc config file, so that every time zsh starts, autoenv is loaded by default:

source ~/.autoenv/activate.sh

Now let's create an example workplace with two imaginary projects, project 1 and project 2.

We open an environment file for project 1:

vim project1/.env

Let's now imagine that project 1 uses an environment variable called ENV, which we will set to dev:

export ENV=dev
Autoenv – Set a lasting, project-based habitat

Now let's do the same thing for project 2, but with a different value for ENV; qa:

export ENV=qa
Autoenv – Set a lasting, project-based habitat

Save and close both files. Now when we cd in the project 1 folder, we see the following message:

autoenv:
autoenv: WARNING:
autoenv: This is the first time you are about to source /home/hacker/course/work/project1/.env:
autoenv:
autoenv:     --- (begin contents) ---------------------------------------
autoenv:     export ENV=dev$
autoenv:
autoenv:     --- (end contents) -----------------------------------------
autoenv:
autoenv: Are you sure you want to allow this? (y/N)

Hit y to load the file. This happens every time a new environment file is sourced. Now if we grep the environment for the ENV variable, we can see it present and with a value of dev:

Autoenv – Set a lasting, project-based habitat

Now let's change the directory to project 2:

Autoenv – Set a lasting, project-based habitat

We can see that the same warning message is issued. And when we grep for the ENV variable, we now see that its value is qa. If we leave this folder, the environment variable is still defined, and will be defined until some other script overrides it or when the current session is closed. The .env file is sourced, even if we cd to a directory deeper inside project1.

Now let's look at a more complex example for project1.

Let's say we want to get the version from package.json, and we also want to use a variable called COMPOSE_FILE that will specify a different file for docker compose. Docker users know what it's all about, but if you don't.. Google time!

Here is an example:

export environment=dev
export version=`cat package.json | grep version | cut -f 4 -d "\""`
export COMPOSE_FILE=docker-compose.yml

For this to take effect, we need to first copy a package.json file, and test that the cat command works:

Autoenv – Set a lasting, project-based habitat

Everything seems fine, so let's cd into our folder:

Autoenv – Set a lasting, project-based habitat

And as you can see, the environment variables have been set:

Autoenv – Set a lasting, project-based habitat

Autoenv can really come in handy, and is not limited to just exporting environment variables. You can do stuff like issuing a reminder when entering a certain project or running a git pull or updating the look and feel of the terminal so that a distinct feel is given for each project.

Commands can be categorized as harmless or harmful. Most commands fall within the first category, but there is one that is very common and that has been known to produce a lot of damage in the world of computers. The dreaded command is rm, which has wiped out numerous hard drives, making precious volumes of data inaccessible. The Linux desktop has borrowed the concept of trash from other desktops and the default action when deleting a file is sending it to the Trash. Sending files there is a good practice, so that no unintentional removing is done. But this trash is no magic location; it's just a hidden folder, usually located in ~/.local.

In this part, we will be looking at a utility tool designed to work with trash. We will install it with:

Don't rm the trash

This will install multiple commands. Let's look at our current directory that contains quite a few files. Let's assume we don't need the files starting with file.*

In order to remove files we will use:

Don't rm the trash

(There is a separate command for working with the trash. We will rehash to reload our path.) We list all the trash commands. The command for listing the trash content is:

Don't rm the trash

Here we see the files that are in our trash. It is only showing the files that were put there with the trash command. We can see the date when they were deleted, the hour, and the exact location. If we'd have had multiple files with the same name and path, they would have been listed here, and we could have identified them by the deletion date.

In order to restore a file from trash we will use the command:

Don't rm the trash

It will show us a list of options and ask for a number corresponding to the file we want restored. In this case we will select 1, meaning we want to restore the json file.

We open the file and we can see that the content was not altered in the process.

In order to remove all the files in the trash, we use:

Don't rm the trash

This is the equivalent of doing rm in the first place. Now if we list the trash again, we see it doesn't have any content.

Although the internet is full of rm -rf / jokes, this is actually a serious issue that can cause headaches and wasted time trying to restore the damage caused. If you've been using rm for a long time and can't get into the habit of using trash, we suggest adding an alias for rm to actually run the trash command instead. In this case, it's a good idea to pile up stacks of files in trash than to risk removing a file that might be needed, before committing, or even removing the whole root partition!