#!/bin/bash
-# dot - a (mostly) one script dotfiles manager
-#
-# Copyright 2026 Edward Delaporte V
-# Licensed under AGPLv3 and later.
-#
-# Features
-# symlinks - any file in $HOME/dotfiles/files may be symlinked
-#
-# dot setup
-# install the necessary tools to $HOME/envs/dot
-#
-# dot list
-# list available roles
-#
-# dot check
-# check setup vs expected
-#
-# dot add ROLE
-# add ROLE to localhost
-#
-# dot apply
-# apply all added ROLES
+ENVS="$HOME/envs"
+ANSIBLE="$ENVS/ansible/bin/ansible-playbook"
+read -d '' HELP << EOF
+dot - a (mostly) one script dotfiles manager
+
+Copyright 2026 Edward Delaporte V
+Licensed under AGPLv3 and later.
+
+dot setup
+ install ansible CLI to $ANSIBLE
+
+dot link FILE
+ updates ~/dot.HOSTNAME.yaml
+ to include a symlink from ~/dotfiles/files/FILE to ~/.FILE
+
+dot check
+ check setup against ~/backup/dot.HOSTNAME.yaml
+
+dot apply
+ apply config in ~/backup/dot.HOSTNAME.yaml
+
+dot help FEATURE
+ setup - more information on setup
+ all - additional features
+EOF
+
+read -d '' SETUP_HELP << EOF
+## Setup
+
+1. Install this file on your path
+2. Clone your (or my) 'dotfiles' repository to ~/dotfiles
+3. Run 'dot help' to get started.
+
+EOF
+
+
+read -d '' EXTRA_HELP << EOF
+
+dot install SCRIPT
+ updates ~/dot.HOSTNAME.yaml
+ to run ~/dotfiles/SCRIPT.sh if it has not yet been run
+ creates ~/dot/SCRIPT.installed after SCRIPT has been run
+
+EOF
+
+
+if [ ! -n "$1" ] || [ "$1" == "help" ]; then
+ echo "$HELP"
+fi
+if [ "$1" == "help" ] && [ "$2" == "all" ]; then
+ echo ""
+ echo "$EXTRA_HELP"
+ echo ""
+ echo "$SETUP_HELP"
+fi
+if [ "$1" == "help" ] && [ "$2" == "setup" ]; then
+ echo ""
+ echo "$SETUP_HELP"
+fi
# set -v
+#
-ENVS="$HOME/envs"
-ANSIBLE="$ENVS/ansible/bin/ansible-playbook"
-TASKFILE="$HOME/dot.$HOSTNAME.yaml"
+TASKFILE="$HOME/backup/dot.$HOSTNAME.yaml"
+LINKFILES="$HOME/dotfiles/files"
+INSTALLS="$HOME/dotfiles/install"
+DOT="$HOME/.dot"
read -d '' EMPTY_TASKFILE << EOF
---
connection: local
tasks:
- - name: Do nothing
- ansible.builtin.shell: echo "Nothing to do."
+ - name: Check on $TASKFILE
+ ansible.builtin.stat:
+ path: $TASKFILE
EOF
+if [[ ! -f "$TASKFILE" ]]; then
+ echo "Creating empty $TASKFILE"
+ mkdir -p "$HOME/backup"
+ echo "$EMPTY_TASKFILE" >> $TASKFILE
+fi
if [ "$1" == "setup" ]; then
if [[ ! -f "$ANSIBLE" ]]; then
if [[ -f "$ANSIBLE" ]]; then
echo "[ ok ]: Ansible setup at $ANSIBLE"
fi
- if [[ ! -f "$TASKFILE" ]]; then
- echo "Creating $TASKFILE"
- echo "$EMPTY_TASKFILE" >> $TASKFILE
- fi
if [[ -f "$TASKFILE" ]]; then
echo "[ ok ]: dot config at $TASKFILE"
fi
exit 1
fi
echo "$EMPTY_TASKFILE" > $TASKFILE
+ echo ""
fi
$ANSIBLE $TASKFILE --check --diff
fi
-if [ "$1" == "list" ]; then
- echo "May symlink:"
- cd $HOME/dotfiles/files
- ls -p | grep -v /
-fi
+if [ "$1" == "link" ]; then
+ if [ ! -n "$2" ]; then
+ echo "Can symlink: (from $LINKFILES)"
+ cd $LINKFILES
+ ls -p | grep -v /
+ exit 1
+ fi
+
+read -d '' LINK_THIS_FILE << EOF
+
+ - name: symlink $2
+ ansible.builtin.file:
+ src: "$LINKFILES/$2"
+ dest: "$HOME/.$2"
+ state: "link"
+EOF
+if [[ "$2" == *"."* ]];then
+ # File already contains a dot
+read -d '' LINK_THIS_FILE << EOF
+ - name: symlink $2
+ ansible.builtin.file:
+ src: "$LINKFILES/$2"
+ dest: "$HOME/$2"
+ state: "link"
+EOF
+fi
-if [ "$1" == "link" ]; then
+ echo " $LINK_THIS_FILE" >> $TASKFILE
+ echo "$2 added to symlinks in $TASKFILE"
+ echo "Run 'dot apply' to create all configured symlinks"
+fi
+
+
+if [ "$1" == "apply" ]; then
+ if [[ ! -f "$TASKFILE" ]]; then
+ echo "$TASKFILE is missing. Run 'dot setup'"
+ exit 1
+ fi
+ $ANSIBLE $TASKFILE
+fi
+
+if [ "$1" == "install" ]; then
if [ ! -n "$2" ]; then
- echo "May symlink:"
- cd $HOME/dotfiles/files
- ls -p | grep -v /
+ echo "Can install: (.sh scripts in $INSTALLS)"
+ cd $INSTALLS
+ ls -p | grep -v / | grep .sh
+ exit 1
+ fi
+ if [[ ! -f "$INSTALLS/$2.sh" ]]; then
+ echo "No such install script $INSTALLS/$2.sh"
+ echo "Run dot install with no params to list scripts."
+ exit 1
fi
-read -d '' LINK_FILE << EOF
----
- tasks:
- - name: Create a symbolic link
- ansible.builtin.file:
- src: /file/to/link/to
- dest: /path/to/symlink
- owner: foo
- group: foo
- state: link
+mkdir -p $DOT
+read -d '' RUN_INSTALL << EOF
+ - name: check $2
+ stat:
+ path: "$DOT/$2.installed"
+ register: $2_installed
+ - name: install $2
+ ansible.builtin.shell: |
+ "$INSTALLS/$2.sh"
+ touch "$DOT/$2.installed"
+ when: not $2_installed.stat.exists
+ - name: verify $2 is installed
+ ansible.builtin.debug:
+ msg: "$2 is installed."
+ when: $2_installed.stat.exists
EOF
-
+ echo " $RUN_INSTALL" >> $TASKFILE
+ echo "Run 'dot apply' to run the install"
fi
-