Objective: Create an easy way to setup a brand-new machine with familiar development environment.

The problem

Each of us who have owned a computer for sometime, will have some personal customizations to the machine, be it the shell used, the editor used and the configurations for those, etc. But whenever, we have to replace the old machine, we have to set it up again. It would be nice to have a simple way to replicate the development environment.

Ways to Automate Dev Setup

There are many different products that are aiming at automating machine configurations:

  • Chef
  • Ansible
  • Puppet

Each of the products have their pros and cons. However, not every one is suitable for personal machine setup. The basic requirement is that it has to be simple to configure and use. For example, we probably don’t want to maintain a sever in order to automate the development environment setup in a not very frequently use cases.

In that regard, I found the Ansible is appealing: it does not need a server and the configurations seems straight forward: YAML files and python scripts.

Ansible Configurations

Ansible is composed of the following components:

  • Inventory: the definition for the target hosts
  • Roles or Tasks: define a specific state of a software and/or its configuration
  • Playbook: associate Roles or Tasks with hosts or group of hosts defined in the Inventory

For the local development setup, the inventory is quite simple. It is only has localhost. For roles and tasks, I chose to use roles so that the playbook can be simply a list of selected roles. And different playbook can choose different roles. For example, the roles in the playbook for personal computer will be different than that for the company one.

The final setup of the folder is like:

.
├── group_vars
│   └── all.yml
├── inventroy
├── macbook-yahoo.yml
├── macbook.yml
└── roles
    ├── git
    │   ├── tasks
    │   │   └── main.yml
    │   └── templates
    │       └── gitconfig.j2
    ├── macbook-common
    │   ├── tasks
    │   │   ├── configuration.yml
    │   │   ├── dotfiles.yml
    │   │   ├── homebrew-apps.yml
    │   │   ├── homebrew.yml
    │   │   └── main.yml
    │   └── vars
    │       └── main.yml
    ├── macbook-yahoo
    │   ├── tasks
    │   │   ├── homebrew-apps.yml
    │   │   ├── homebrew.yml
    │   │   └── main.yml
    │   └── vars
    │       └── main.yml
    ├── ssh
    │   ├── files
    │   │   ├── aws-proxycmd
    │   │   ├── config
    │   │   └── ssm-proxycmd
    │   └── tasks
    │       └── main.yml
    ├── vim
    │   ├── files
    │   │   ├── vimrc
    │   │   └── vimrc-Old-Vundle
    │   └── tasks
    │       └── main.yml
    ├── vim-github
    │   └── tasks
    │       └── main.yml
    └── zsh
        ├── files
        │   ├── utils.sh
        │   └── zshrc
        ├── handlers
        │   └── main.yml
        └── tasks
            └── main.yml

Vim Configuration

It is necessary to install plugins to enrich the Vim experience. There are different plugin managers for Vim, among which I am using Vundle. The commonly used plugins are:

Plugin 'VundleVim/Vundle.vim'
Plugin 'molokai'
Plugin 'nelstrom/vim-mac-classic-theme'
Plugin 'altercation/vim-colors-solarized'
Plugin 'gmarik/ingretu'
Plugin 'sonph/onehalf'
Plugin 'hashivim/vim-packer'
Plugin 'editorconfig/editorconfig-vim'
Plugin 'rust-lang/rust.vim'
Plugin 'tpope/vim-git'
Plugin 'tpope/vim-fugitive'
Plugin 'vim-ruby/vim-ruby'
Plugin 'gerw/vim-latex-suite'
Plugin 'fs111/pydoc.vim.git'
Plugin 'mitechie/pyflakes-pathogen.git'
Plugin 'scrooloose/syntastic'
Plugin 'preservim/tagbar'
Plugin 'mkitt/browser-refresh.vim'
Plugin 'unimpaired.vim'
Plugin 'airblade/vim-gitgutter'
Plugin 'junegunn/fzf'
Plugin 'junegunn/fzf.vim'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'mustache/vim-mustache-handlebars'
Plugin 'Rykka/riv.vim'
Plugin 'TaskList.vim'
Plugin 'The-NERD-tree'
Plugin 'jQuery'
Plugin 'ragtag.vim'
Plugin 'mbbill/undotree'
Plugin 'ZoomWin'
Plugin 'tComment'
Plugin 'Shougo/neocomplcache'
Plugin 'ycm-core/YouCompleteMe'
Plugin 'akhaku/vim-java-unused-imports'
Plugin 'Townk/vim-autoclose'
Plugin 'vim-scripts/VimClojure'

And the most useful ones are:

  • File finder
    • The-NERD-tree: provide a side file browser
    • fzf: seach file names or content using fzf
  • Completion
    • neocomplcache: completion based on text
    • YouCompleteMe: completion based on semantics

Zsh Configurations

There are also lots of plugin managers for ZSH, with well-known ones like Oh-My-Zsh. The one I am using is zinit. There are different repos related to zinit, and you can search it to find the annecdots. Some replated repos:

The most important settings for Zsh or any shell are history, auto suggestion and history search. Other nice to have infos are like the git branch information, the current directory etc.

Here are the lists of Zsh plugins:

Terminal and Multiplexer

Terminal is the most important part of development environment. The most popular one in Mac OS is iTerm2.

I used to use GNU Screen a lot when I use the remote openstack machine for development because of needed linux setup and the libraries. Another popular multiplexer is Tmux. One of the benefits using multiplexer is to keep the session to remote sever live and thus the remote running process even when the local machine is crashed or stopped. That way, the remote process can be kept running for days.

Recently, I have discovered another multiplexer Zellij created using Rust programming language. It seems nice and have better hints for keybinds.

References