Properly setting up your development environment
Guillaume Briday
4 minutes
Today, I want to discuss a topic that is very important to me. Setting up your development environment and computer is a fundamental aspect of your organization and daily workflow.
It is crucial to manage your dependencies, tools, and have an environment that can be recreated on any computer. Developers are most affected by this, I think, but they are not the only ones.
Dependency manager: Homebrew
A dependency manager, as the name suggests, will manage your dependencies. It automates the installation, updates, configuration, and removal of software and tools that you want to install.
If you are on Linux, there are more dependency managers than I could mention. However, on macOS, by default, there are none.
Fortunately, the community has solved this problem with Homebrew. It's the most well-known, I think, because when you want to install a package in the future, in the vast majority of cases, the documentation will recommend doing it with Homebrew.
All packages are updated very regularly, and you can find the complete list here. Also, since the project is open source, you can even propose a new version of a package.
Not yet convinced of the benefits of a package manager? Let's see some use cases:
# Install a package
$ brew install [package]
# To update all packages:
$ brew upgrade
# or
$ brew upgrade [package]
# To list installed packages:
$ brew list
# To update the list of available packages:
$ brew update
# To list outdated packages:
$ brew outdated
You can see that the simplicity of use is quite impressive. And we can go even further!
Cask is an extension of Brew. It allows you to install real software directly from the command line, which saves a considerable amount of time.
For example, to install a piece of software like Firefox:
- Open a browser
- Search for "Firefox"
- Find the correct link to download Firefox
- Download the
.dmg
- Open it
- Drag the icon to the
Applications
folder - Eject the
.dmg
With Cask:
$ brew cask install firefox
And it will download and install Firefox in a completely transparent manner.
Similarly, you can uninstall software:
$ brew cask remove firefox
Dotfiles
Dotfiles
are configuration files on UNIX environments. They are called this way because they are prefixed with a dot and are hidden by default.
By extension, there are some configuration files that are not prefixed by a dot but are used with an extension, like .json
, but have the same purpose of configuring a tool.
Before explaining how I organize myself, you can find my dotfiles on GitHub.
I have organized my dotfiles into several subfolders, one for each tool or software I use.
Let's take the example of Git
and VSCode
.
For Git, in the corresponding folder, we find the two standard Git configuration files: .gitconfig
and .gitignore_global
.
By default, Git doesn't expect to find these files in this folder, so they need to be moved to your home
directory to be activated.
Saving and versioning these files allows me to reuse them on any Mac I find myself using.
For VSCode, the configuration is more complex, but the principle is similar.
├── keybindings.json
├── locale.json
├── package.sh
└── settings.json
On macOS, these files (except package.sh
, which we'll discuss later) are located in ~/Library/Application Support/Code/User
. For my part, each time I make a change in my VSCode preferences, I copy these files and put them in my ~/dotfiles
folder, which contains my entire versioned configuration.
To use this configuration on another machine, I just need to move these files into VSCode's configuration folder, and the settings will be automatically applied.
For extensions, there is no configuration file. However, you can export the list of installed extensions with the command:
$ code --list-extensions
And you can install an extension with the command:
$ code --install-extension [extension]
To find the name of the extension, you can go to the EXTENSIONS
section, and you will find the name to use next to the title of the extension you want to install.
For example, with the Docker extension:
In this case:
$ code --install-extension PeterJausovec.vscode-docker
The principle is similar for other dotfiles
, except for files like the Better Touch Tools configuration, which I need to import manually.
This is very convenient, but we're not going to launch as many commands as there are software, Brew packages, or VSCode extensions to install. We need to automate the installation.
Automating installation
To do this, we'll use Bash scripts that execute a series of commands for us. We could also use Ansible to configure our local environment.
Simply create a file (the extension doesn't matter) and add a Shebang with the path to Bash (for example):
#!/usr/bin/env bash
echo "Hello World"
To continue with our VSCode extension list example, I use a script in a package.sh
file. I add the .sh
extension purely for indication.
To execute the file, you first need to give it permission:
$ chmod +x package.sh
Then call it:
$ ./package.sh
Hello World
Now all your extensions will be installed one by one.
The possibilities are endless, but I'll give some examples. I use it to configure Brew with all my packages and software, also to configure macOS directly and to download applications from the Mac App Store.
We could go further and have a single file that executes everything at once, but then we would lose the ability to run the configuration independently, which I find too restrictive.
Similarly, for simple commands like copying Git files, I don't need to create a script since it's just one command.
I have detailed the entire process for setting up my development environment in the project's README.
Sharing dotfiles
Since they are just simple files, they are very easy to version and can be shared on GitHub, for example. There are tens of thousands of repositories with example configurations, and you can take a lot of inspiration from them and adapt them to your needs.
I highly recommend sharing your configuration as well. It can give other developers ideas, and you can easily download your configuration.
Note, if these files become public, you should first remove any confidential information and add them during installation.
Conclusion
Make sure to keep your configuration up to date; you'll be glad you did when you need it.
If you have suggestions or questions, feel free to leave them in the comments.
Thank you!
EDIT:
Now, instead of manually copying files each time I make changes, I use symbolic links. This allows me to modify the files directly in my Git repository, and the changes will be automatically applied everywhere.