dotfiles

$HOME is where the <3 is
git clone git://git.alexkarle.com/dotfiles.git
Log | Files | Refs | Submodules | README

commit cf6654ce630c6a2ee9bcf74bf2b3e14a12071fd5 (patch)
parent c713e130a1e5ff461abbd07d3723b10ad5e03098
Author: Alex Karle <alex@alexkarle.com>
Date:   Tue, 23 Feb 2021 10:39:31 -0500

install: Change from git-worktree to symlink farm

We've been here before... about 5mo ago, I decided to give the "just
checkout into $HOME" a shot with a dedicated "cfg" script to push/pull
etc. This worked OK, but it had a couple flaws:

  1. Ignoring everything was annoying (needed git add -f)
  2. The bare repo in ~/.cfg doesn't track other remotes
     (there was no way to see ahead/behind origin)
  3. It promotes an all or nothing approach / relied on DOT.local
     for site-local customizations

This patch goes back to a more traditional style of symlink-farm, with
a twist! The twist is that the .{bash_,}profile files are NOT in git,
as they only contain one-two lines worth versioning. This allows us
to generate them on install and put site-local modifications there.

In addition, since I noticed I was only really using git/tmux/vi/sh on
my remote servers, I ended up splitting the install into skel (the bare
necessities) and install.sh. I expect to use install.sh on the desktop
and skel on the server, and the `lnkdot` script can easily add more
to an existing installation.

Finally, note that the generated profiles put $DOTFILES/bin on the path
instead of copying it to ~/bin. This allows easier separation of what
is and what isn't version controlled out of my personal scripts. `e`
has been updated accordingly to find it's inputrc relative to itself.

Diffstat:
D.bash_profile | 15---------------
M.gitignore | 3++-
D.profile | 5-----
Dbin/cfg | 3---
Mbin/e | 4+++-
Abin/lnkdot | 32++++++++++++++++++++++++++++++++
Aetc/install.sh | 22++++++++++++++++++++++
Aetc/skel.sh | 38++++++++++++++++++++++++++++++++++++++
8 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/.bash_profile b/.bash_profile @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# sourced by non-interactive login shells -# Example: -# - ssh to Linux --> run bash_profile on login -# - open new tmux window --> run bashrc -# -# Exception: -# ** On OSX bash_profile is run by terminal emulators (new tabs, etc) ** -# -# Takeaway: -# ** Write preferences in bashrc, source it from bash_profile ** - -if [ -r ~/.bashrc ]; then - source ~/.bashrc -fi diff --git a/.gitignore b/.gitignore @@ -1 +1,2 @@ -* +# netrw (vim) cruft +.netrwhist diff --git a/.profile b/.profile @@ -1,5 +0,0 @@ -#!/bin/sh -# ~/.profile -- dash/sh/ksh profile -# Sourced for login shells -- set $ENV to ~/.shrc -# to use that as the config for this and all new interactive shells -export ENV="$HOME/.shrc" diff --git a/bin/cfg b/bin/cfg @@ -1,3 +0,0 @@ -#!/bin/sh -# cfg -- manage dotfiles with pure git -exec git --git-dir=$HOME/.cfg --work-tree=$HOME "$@" diff --git a/bin/e b/bin/e @@ -15,7 +15,9 @@ for f in .tags tags; do fi done -export INPUTRC="$HOME/etc/edinputrc" +DOTDIR="$(dirname $(dirname $(readlink -f "$0")))" +echo "$DOTDIR" +export INPUTRC="$DOTDIR/etc/edinputrc" # Only include -v if using GNU ed if ed --version >/dev/null 2>&1 ; then diff --git a/bin/lnkdot b/bin/lnkdot @@ -0,0 +1,32 @@ +#!/bin/sh +# lnkdot -- link a dotfile +set -e + +die() { + echo "$1" 1>&2 + exit 1 +} + +if [ "$#" = "0" ]; then + die "usage: linkdot DOTFILE [DOTFILE ...]" +fi + +DIR="$(dirname "$(dirname "$(readlink -f "$0")")")" + +lnk() { + printf "$1 ... " + if [ -e "$HOME/$1" -a ! -L "$HOME/$1" ]; then + echo "failed" + else + ln -snf $DIR/$1 $HOME/$1 + echo "linked" + fi +} + +for f in "$@"; do + if [ -e "$DIR/$f" ]; then + lnk "$f" + else + die "dotfile doesn't exist: $f" + fi +done diff --git a/etc/install.sh b/etc/install.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# install.sh -- full install via skel.sh/lnkdot +set -e +DIR="$(dirname "$(dirname "$(readlink -f "$0")")")" + +. "$DIR/etc/skel.sh" +add .bash_profile "[ -e \"$DIR/.bashrc\" ] && source \"$DIR/.bashrc\"" + +# Generic .dotfiles +for f in `find $DIR -type f -maxdepth 1 -name '.*' | grep -v git | sed "s#^$DIR/##"`; do + "$DIR/bin/lnkdot" $f +done + +# Generic .config dirs +for d in `find $DIR/.config -type d -maxdepth 1 -mindepth 1 | sed "s#^$DIR/##"`; do + "$DIR/bin/lnkdot" $d +done + +# Other exceptions +"$DIR/bin/lnkdot" .vim +mkdir -p $HOME/.newsboat +"$DIR/bin/lnkdot" .newsboat/urls diff --git a/etc/skel.sh b/etc/skel.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# skel.sh -- links the "/etc/skel" subset of my dotfiles +# intended usage: +# $ git clone git://git.alexkarle.com/dotfiles.git +# $ ./dotfiles/etc/skel.sh +# $ # manually link any other files +# +# NOTE: .{bash_,}profile is *generated* so that per-site +# customizations can be put in. This script checks that the +# bits worth version controlling are installed properly +set -e +DIR="$(dirname "$(dirname "$(readlink -f "$0")")")" + +add() { + dot="$1" + cmd="$2" + printf "%s ... " "$dot" + if test ! -e "$HOME/$dot" + then + echo "$cmd" >> "$HOME/$dot" + echo "new" + elif grep -q "$cmd" "$HOME/$dot" + then + echo "exists" + else + echo "$cmd" >> "$HOME/$dot" + echo "added" + fi +} + +mkdir -p $HOME/.config + +# TODO: create full install.sh +"$DIR/bin/lnkdot" .tmux.conf +"$DIR/bin/lnkdot" .config/git +"$DIR/bin/lnkdot" .exrc +add .profile "export PATH=\"$DIR/bin:\$PATH\"" +add .profile "export ENV=\"$DIR/.shrc\""