Question:
Should I even write a script to undo the changes done by running a script in the first place?
If no, then how do I clean up/undo the changes done to the system so that I can run the script again (with changes) in a system state that it was in before I ran the script?
If yes, then what should be the approach to write a good undo script?
Script: Link to script on github
#!bin/bash
repos_dir="$HOME/repos"
if [ ! -d "$repos_dir" ]; then
mkdir -p "$repos_dir"
fi
git clone https://github.com/bashonregardless/dotfiles.git "$repos_dir/dotfiles"
software_dir="$HOME/software"
# Create a directory to download nvim software.
if test ! -d "$software_dir"; then
mkdir "$software_dir"
fi
(
cd "$software_dir"
# Download Neovim on Linux
if test $? = 0 && "$(command -v curl)" &> dev/null; then
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage
chmod u+x nvim.appimage
else
echo "Error: curl is not installed"
echo
exit 64
fi
)
# Create "$HOME/bin" dir if it does not exist
if test ! -d "$HOME/bin"
then
mkdir "$HOME/bin"
fi
# Create a symbolic link in "$HOME/bin" dir to "$HOME/software/nvim"
ln "$software_dir/nvim.appimage" "$HOME/bin/nvim"
# Update vimrc at "$HOME/.vim/vimrc"
[ ! -d "$HOME/.vim" ] && mkdir "$HOME/.vim"
if [ ! -e "$HOME/.vim/vimrc" ]; then
# create a new file by copying dotfile vimrc
cp "$repos_dir/dotfiles/vimrc.template" "$HOME/.vim/vimrc"
else
cat "$repos_dir/dotfiles/vimrc.template" >> "$HOME/.vim/vimrc"
fi
# Update init.vim at "$HOME/.config/nvim/" (VIMCONFIG="$HOME/.config/nvim")
[ ! -d "$HOME/.config/nvim" ] && mkdir -p "$HOME/.config/nvim"
if [ ! -e "$HOME/.config/nvim/init.vim" ]; then
# create a new file by copying dotfile vimrc
cp "$repos_dir/dotfiles/init.vim.template" "$HOME/.config/nvim/init.vim"
else
cat "$repos_dir/dotfiles/init.vim.template" >> "$HOME/.config/nvim/init.vim"
fi
# add minpac vim plugin manager (See Modern vim craft)
[ ! -d "$HOME/.config/nvim/pack/minpac/opt" ] && mkdir -p "$HOME/.config/nvim/pack/minpac/opt"
cd "$HOME/.config/nvim/pack/minpac/opt"
git clone https://github.com/k-takata/minpac.git
cd -
# Update dotfiles (create, if non-existent)
if [ ! -e "$HOME/.bash_profile" ]; then
# Copy and rename in the same time
cp "$repos_dir/dotfiles/bash_profile" "$HOME/.bash_profile"
else
cat "$repos_dir/dotfiles/bash_profile" >> "$HOME/.bash_profile"
fi
if [ ! -e "$HOME/.bashrc" ]; then
cp "$repos_dir/dotfiles/bashrc" "$HOME/.bashrc"
else
cat "$repos_dir/dotfiles/bashrc" >> "$HOME/.bashrc"
fi
This script sets up a vim development environment. I wrote the script and thought that it would be enough to setup things correctly, so I ran it for the first time and it worked. Then I made some changes to the script and wanted to test if it was running correctly. When I ran it this time, I encountered a few warnings/errors/logs like:
ln: failed to create hard link '/home/user/bin/nvim': File exists
fatal: destination path '/home/user/repos/dotfiles' already exists and is not an empty > directory.
I have used a few cat file >> another-file
, that appends duplicate contents to the another-file
every time I run the script. This I definitely want to undo.
Changes done to the system by running the script:
- creating ~/repos directory.
- cloning dotfiles repo inside repos.
- cloning compSc repo inside repos.
- creating software dir inside home.
- downloading nvim inside software dir.
- changing the permission of the downloaded file nvim.appimage.
- creating bin dir inside home.
- creating symlink of nvim.appimage with ~/bin/nvim
- create ~/.vim/vimrc (mkdir -p).
- copy/create or append to ~/.vim/vimrc.
- mkdir -p "$HOME/.config/nvim/pack/minpac/opt"
- clone k-takata/minpac indside "$HOME/.config/nvim/pack/minpac/opt"
- copy/create or append to "$HOME/.bash_profile"
These are the changes that happen to my system before even sourcing the ~/.bash_profile file. Sourcing which does further changes to my system, like Updating the PATH and other environment variables, etc.
I would like to undo these changes as well.
How I have been replicating the system state that it was in before running the script ( for testing purpose )?
I use multipass to launch an Ubuntu VM for every small change. After running the script, I delete this VM and launch a new one. This gives me a machine that is in a state where I can run my script for the first time. I do this for every small change. It gets tedious soon.