commit d8c786f52dfc364908418843b0640ab8fa38110e Author: Denis Lehmann Date: Tue Sep 7 11:47:41 2021 +0200 initial commit diff --git a/README.org b/README.org new file mode 100644 index 0000000..2ced901 --- /dev/null +++ b/README.org @@ -0,0 +1,67 @@ +* dotlink + + There are countless ways of managing your dotfiles.. this is also one. + After trying several approaches and switching between different setups, this method met finally all of my requirements: + + - As simple as possible + - Multiple machines are managed in one repository + - Identical configurations for one program on several machines only need to be adjusted in one place + - Different configurations for one program on several machines are no problem + - Set everything up with one command + - Updating configurations shall require nothing more than =git pull= + + This is a reference repository which contains a =setup= script and example dotfiles for two machines called =host1= and =host2=. + + *Warning*: If you want to try this make a backup of your dotfiles! + The =setup= script doesn't overwrite existing files but you never know. + +** Concept + + The concept is based on symlinks and two directories called =common= and =machines= and a bash script called =setup=. + + The =machines= directory contains subdirectories for all machines on which dotfiles are managed. + They need to match the /hostname/ of the machine (in this repository =host1= and =host2=) and mimic the corresponding =$HOME= directories. + + The =common= directory contains configs which are present on multiple machines. + It doesn't follow any specific structure, you can choose what suits your setup. + Subdirectories with program names, followed by the configuration files (in this repository only =mpv=) make probably the most sense but its up to you. + The =common= directory should never contain symlinks. + + Symlinks from the =machines= directory to the =common= directory make the configs available on multiple machines and they can be adjusted in one place (see =mpv= in this repository). + + Here is the tree output from this repository: + + #+begin_example text + dotlink/ + ├── common + │   └── mpv + │   ├── input.conf + │   └── mpv.conf + ├── machines + │   ├── host1 + │   │   ├── .config + │   │   │   └── mpv -> ../../../common/mpv/ + │   │   └── .offlineimaprc + │   └── host2 + │   └── .config + │   ├── beets + │   │   └── config.yaml + │   └── mpv -> ../../../common/mpv/ + └── setup + #+end_example + + The *mpv* configuration is shared between hosts, =host1= has an *OfflineIMAP* configuration in his home directory and =host2= has a *beets* configuration in his =.config= directory. + + When calling the =setup= script, all files from the directory which matches the current /hostname/ are linked to their destination in the =$HOME= directory. + Calling the script is only neccessary when new files are added. + If you updated a configuration somewhere else just call =git pull= and thats it. + +** Adding configuration files for multiple host + + It is important that the links from the =machines= directory to the =common= directory are relative. + Follow these steps to add new configurations for multiple machines: + + 1. Add the files to the =common= directory + 2. Execute =ln -rs common/ machines//= for every machine on which the files should be present + 3. Call the =setup= script on every modified machine + diff --git a/common/mpv/input.conf b/common/mpv/input.conf new file mode 100644 index 0000000..3527866 --- /dev/null +++ b/common/mpv/input.conf @@ -0,0 +1 @@ +# Example input.conf \ No newline at end of file diff --git a/common/mpv/mpv.conf b/common/mpv/mpv.conf new file mode 100644 index 0000000..4442a40 --- /dev/null +++ b/common/mpv/mpv.conf @@ -0,0 +1 @@ +# Example mpv.conf \ No newline at end of file diff --git a/machines/host1/.config/mpv b/machines/host1/.config/mpv new file mode 120000 index 0000000..72c41f2 --- /dev/null +++ b/machines/host1/.config/mpv @@ -0,0 +1 @@ +../../../common/mpv/ \ No newline at end of file diff --git a/machines/host1/.offlineimaprc b/machines/host1/.offlineimaprc new file mode 100644 index 0000000..80035a9 --- /dev/null +++ b/machines/host1/.offlineimaprc @@ -0,0 +1 @@ +# Example .offlineimaprc \ No newline at end of file diff --git a/machines/host2/.config/beets/config.yaml b/machines/host2/.config/beets/config.yaml new file mode 100644 index 0000000..207ef47 --- /dev/null +++ b/machines/host2/.config/beets/config.yaml @@ -0,0 +1 @@ +# Example config.yaml \ No newline at end of file diff --git a/machines/host2/.config/mpv b/machines/host2/.config/mpv new file mode 120000 index 0000000..82ade02 --- /dev/null +++ b/machines/host2/.config/mpv @@ -0,0 +1 @@ +../../../common/mpv \ No newline at end of file diff --git a/setup b/setup new file mode 100755 index 0000000..76af01e --- /dev/null +++ b/setup @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# Text formatting variables +text_bold="\e[1m" +text_red="\e[31m" +text_reset="\e[0m" +text_yellow="\e[33m" + +# Output functions +function log { + echo -ne "$1\n" +} + +function warning { + echo -ne "${text_bold}${text_yellow}WARNING${text_reset} $1\n" +} + +function error { + echo -ne "${text_bold}${text_red}ERROR${text_reset} $1\n" +} + +# Get current dotfile directory for later linking +dotfiles="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +# Check if dotfiles for machine exist +if [ ! -d "$dotfiles/machines/$HOSTNAME" ]; then + error "No dotfiles for machine $text_bold$HOSTNAME$text_reset found" + exit 1 +fi + +# Get dotfiles for current machine +cd "$dotfiles/machines/$HOSTNAME" +files=( $(find -L -type f -printf '%P\n')) + +log "Linking $text_bold${#files[@]}$text_reset files..\n" + +# Link files +for file in "${files[@]}"; do + + # Check if target is a link + if [ -L "$HOME/$file" ]; then + + if [ "$(readlink $HOME/$file)" != "$dotfiles/machines/$HOSTNAME/$file" ]; then + warning "$text_bold$HOME/$file$text_reset is a link but doesn't point to this repository, it will not be linked" + continue + fi + + # Check if target is a file or directory + elif [ -f "$HOME/$file" ]; then + + warning "$text_bold$HOME/$file$text_reset exists and will not be linked" + continue + + # Create link + else + + # Create target directory if not existent + mkdir -p "$(dirname $HOME/$file)" + + # Link file + ln -s "$dotfiles/machines/$HOSTNAME/$file" "$HOME/$file" + log "Linked $text_bold$dotfiles/$file$text_reset to $text_bold$HOME/$file$text_reset" + + fi + +done + +log "\ndone"