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.