Managing your dotfiles and development environment on Unix-like devices

Managing your dotfiles and development environment on Unix-like devices

Shiny new computers are great, but they always have the same problem, they’re missing shell settings, aliases, and other utilities that you use on a daily basis. If you are starting a new job or planning a hardware refresh, it won’t feel like $HOME until you’ve gone through the process of setting up your development environment to your liking.

Once you’ve gone through a few iterations of unboxing a few machines, you’ll soon realize that storing all of your shell settings in a repository will speed up the onboarding process.

I used to have a few bash scripts that I would copy and paste from for this, and I decided it was time to get that into a repo instead of maintaining these things locally. I really liked the way that Corey Schafer managed his files, and borrowed a few of his bash specific settings, and wrote a Python script to manage the dotfiles, and lifecycle of the packages.

The Repository - environment-manager

The repo includes two examples of package managers, brew for MacOS and apt for debian based systems. Following the same pattern you can extend the Python script to include any Linux distribution’s package manager.

You’ll notice that I don’t include any Python specific packages. I dropped maintaining a system wide requirements.txt file, or virutalenvs on my local machine. I mainly handle Python dependencies through various docker containers that I alias. This allows applications like Ansible to not be installed locally on my machine, and managing its dependency on any system that uses the container.

Cloning the repository

To start using this method just clone the repo to your local machine.

git clone https://github.com/nullconfig/environment-manager.git $HOME/environment-manager

Make the tweaks to the package managers section in the packages directory to ensure all your default apps will be installed. If you are truing up the list for an existing installation you can print out a list of installed packages with brew or apt.

For example:

for i in $(apt list --installed| cut -d/ -f1); do echo "\"$i\"" >> $HOME/installed_apps.txt; done

Then just copy this list into the packages/apt_packages.py file, and push the changes to your repo if you’ve already created one. See ongoing maintenance below for more information on converting this to your own repository.


Running the script

Now you can run the install.py script that’s inside the repository.

$ python3 $HOME/environment-manager/install.py -hd $HOME -pm apt

Reading package lists... Done
Building dependency tree
Reading state information... Done
awscli is already the newest version (1.18.69-1ubuntu0.20.04.1).
0 upgraded, 0 newly installed, 0 to remove and 132 not upgraded.
Symlink created /home/sysadmin/environment-manager/environment_manager/dotfiles/.aliases -> /home/sysadmin/.aliases
Symlink created /home/sysadmin/environment-manager/environment_manager/dotfiles/.bashrc -> /home/sysadmin/.bashrc
Symlink created /home/sysadmin/environment-manager/environment_manager/dotfiles/.bash_profile -> /home/sysadmin/.bash_profile
Symlink created /home/sysadmin/environment-manager/environment_manager/dotfiles/.bash_prompt -> /home/sysadmin/.bash_prompt

I added a shell alias that can source the rc file relevant to your shell, and simplify subsequent updates. Once you’ve ran the script once it will be available.

alias env-update='. $HOME/.bashrc'


Ongoing maintenance

From here you can just add or remove packages from the lists in the packages directory $HOME/envrionment-manager/environment_manager/packages/<package_file>, and then run the original command to install them or env-update to manage the aliases if you made changes.

Maintaining repository in your very own repo can be done by stripping out the .git directory in the original folder you cloned, and initialize it, if you didn’t fork the repository.

git init
git add .
git commit -m "init commit"
git branch -M main
git remote add origin https://github.com/username/new_repo
git push -u origin main
comments powered by Disqus