dotfiles

My personal dotfiles 💠️

config (4025B)

      1 #!/bin/bash
      2 #                   __ _       
      3 #   ___ ___  _ __  / _(_) __ _ 
      4 #  / __/ _ \| '_ \| |_| |/ _` |
      5 # | (_| (_) | | | |  _| | (_| |
      6 #  \___\___/|_| |_|_| |_|\__, |
      7 #                        |___/ 
      8 #
      9 # A simple configuration manager
     10 # 2021 (C) Pablo
     11 # Free use of this software is granted under the terms of the GPL-3.0 License
     12 
     13 # Get the path to the git repository that should be used for storing stuff
     14 if [ -n "$DOTFILES_REPO" ]
     15 then
     16   dotfiles_repo="$DOTFILES_REPO"
     17 elif [ -n "$XDG_DATA_HOME" ]
     18 then
     19   dotfiles_repo="$XDG_DATA_HOME/dotfiles"
     20 else
     21   dotfiles_repo="$HOME/.local/share/dotfiles"
     22 fi
     23 
     24 # Get the name of the files that holds the list of all dotfiles that should be
     25 # tracked
     26 if [ -n "$DOTFILES_LIST" ]
     27 then
     28   dotfiles_list="$DOTFILES_LIST"
     29 elif [ -n "$XDG_CONFIG_HOME" ]
     30 then
     31   dotfiles_list="$XDG_CONFIG_HOME/dotfiles.list"
     32 else
     33   dotfiles_list="$HOME/.config/dotfiles.list"
     34 fi
     35 
     36 # Calls git in the appropriate repository
     37 call_git() 
     38 {
     39   git --git-dir="$dotfiles_repo" --work-tree="$HOME" "$@"
     40 }
     41 
     42 # Parse the commands
     43 case "$1" in
     44   # Commit and push updates to all remotes
     45   update)
     46     # Add the relevant files to the repo
     47     xargs git --git-dir="$dotfiles_repo" --work-tree="$HOME" add \
     48       < "$dotfiles_list"
     49 
     50     shift
     51 
     52     case "$1" in
     53       # Edit the commit message from a file
     54       -e|--edit|'')
     55         # Create a temporary file to store the commit message
     56         commit_msg_file="$(mktemp)"
     57         touch "$commit_msg_file"
     58 
     59         # Open the editor and edit the message
     60         $EDITOR "$commit_msg_file" 
     61         if call_git commit -F "$commit_msg_file" 
     62         then
     63           # Remove the temporary file
     64           rm "$commit_msg_file"
     65         else
     66           # Remove the temporary file and exit with an error
     67           rm "$commit_msg_file"
     68           exit 1
     69         fi
     70         ;;
     71 
     72       # Use to commit messages specified with -m
     73       -m)
     74         call_git commit "$@" || exit $?
     75         ;;
     76 
     77       # Print an error message and exit with an error
     78       *)
     79         printf "Unknown option: '%s'\nSee config(1)\n" "$1"
     80         exit 1
     81         ;;
     82     esac
     83 
     84     # Push the changes to all remotes
     85     for remote in "$(call_git remote -v | awk '/(push)/ { print $1 }' | uniq)"
     86     do
     87       call_git push "$remote" master
     88     done
     89 
     90     ;;
     91 
     92   # Add files to the list of files
     93   add)
     94     shift
     95 
     96     # Add files to the list of dotfiles
     97     for item in "$@"
     98     do
     99       echo "Adding '$item' to the list of dotfiles"
    100       realpath "$item" >> "$dotfiles_list"
    101       call_git add "$item"
    102     done
    103     ;;
    104 
    105   # Remove files from the list of dotfiles
    106   rm)
    107     shift
    108 
    109     # Remove files from the list of dotfiles
    110     for item in "$@"
    111     do
    112       echo "Removing '$item' from the list of dotfile"
    113       pattern="$(realpath "$item")"
    114       pattern="${pattern//\//\\\/}"
    115 
    116       # Remove the files from the git repository and from the list of files
    117       # Awk is used because 'item' may be a directory
    118       awk -i inplace "!/^$pattern/ { print }" "$dotfiles_list"
    119       call_git rm "$item" --cached -r
    120     done
    121     ;;
    122 
    123   # List the dotfiles specified in configurations list
    124   list)
    125     cat "$dotfiles_list"
    126     ;;
    127 
    128   # Show the configuration files that have been modified or deleted
    129   status)
    130     config_git_status="$(mktemp)"
    131     call_git status > "$config_git_status"
    132 
    133     if grep modified "$config_git_status" > /dev/null;
    134     then
    135       printf '\033[0;33mmodified files:\033[0m\n'
    136       awk '/modified/ { print $2 }' "$config_git_status" \
    137         | xargs -r realpath \
    138         | xargs -r -n 1 printf '\033[0;33m    %s\033[0m\n'
    139     fi
    140 
    141     if grep deleted "$config_git_status" > /dev/null;
    142     then
    143       printf '\033[0;31mdeleted files:\033[0m\n'
    144       awk '/deleted/ { print $2 }' "$config_git_status" \
    145         | xargs -r realpath \
    146         | xargs -r -n 1 printf '\033[0;31m    %s\033[0m\n'
    147     fi
    148 
    149     rm "$config_git_status"
    150     ;;
    151 
    152   # Just pass the following arguments to git
    153   --)
    154     shift
    155     call_git "$@"
    156     ;;
    157 
    158   # Just pass the arguments to git
    159   *)
    160     call_git "$@"
    161     ;;
    162 esac
    163