]> us-delaporte.pagekite.me Git - dotfiles.git/blob - bin/dot
d99ef6eeef4bf1d17c0a1ef14c6dd0578627a30b
[dotfiles.git] / bin / dot
1 #!/bin/bash
2 ENVS="$HOME/envs"
3 ANSIBLE="$ENVS/ansible/bin/ansible-playbook"
4 read -d '' HELP << EOF
5 dot - a (mostly) one script dotfiles manager
6
7 1. Install this file on your path
8 2. Clone your (or my) 'dotfiles' repository to ~/dotfiles
9 3. Run 'dot help' to get started.
10
11 Copyright 2026 Edward Delaporte V
12 Licensed under AGPLv3 and later.
13
14 dot setup
15 install ansible CLI to $ANSIBLE
16
17 dot link FILE
18 updates ~/dot.HOSTNAME.yaml
19 to include a symlink from ~/dotfiles/files/FILE to ~/.FILE
20
21 dot install SCRIPT
22 updates ~/dot.HOSTNAME.yaml
23 to run ~/dotfiles/SCRIPT.sh if it has not yet been run
24 creates ~/dot/SCRIPT.installed after SCRIPT has been run
25
26 dot check
27 check setup against ~/dot.HOSTNAME.yaml
28
29 dot apply
30 apply config in ~/dot.HOSTNAME.yaml
31 EOF
32
33 if [ ! -n "$1" ] || [ "$1" == "help" ]; then
34 echo "$HELP"
35 fi
36 # set -v
37
38 TASKFILE="$HOME/dot.$HOSTNAME.yaml"
39 LINKFILES="$HOME/dotfiles/files"
40 INSTALLS="$HOME/dotfiles/install"
41 DOT="$HOME/dot"
42
43 read -d '' EMPTY_TASKFILE << EOF
44 ---
45 - name: Set up dotfiles on $HOSTNAME
46 gather_facts: no
47 hosts: localhost
48 connection: local
49
50 tasks:
51 - name: Check on $TASKFILE
52 ansible.builtin.stat:
53 path: $TASKFILE
54 EOF
55
56
57 if [ "$1" == "setup" ]; then
58 if [[ ! -f "$ANSIBLE" ]]; then
59 mkdir -p "$ENVS"
60 echo "Setting up Ansible in ~/envs/ansible"
61 cd $HOME/envs; python3 -m venv ansible
62 $HOME/envs/ansible/bin/pip install ansible jinja2
63 fi
64 if [[ -f "$ANSIBLE" ]]; then
65 echo "[ ok ]: Ansible setup at $ANSIBLE"
66 fi
67 if [[ ! -f "$TASKFILE" ]]; then
68 echo "Creating $TASKFILE"
69 echo "$EMPTY_TASKFILE" >> $TASKFILE
70 fi
71 if [[ -f "$TASKFILE" ]]; then
72 echo "[ ok ]: dot config at $TASKFILE"
73 fi
74 fi
75
76 if [ "$1" == "reset" ]; then
77 read -n1 -p "Reset $TASKFILE? [y,N]" input
78 if [[ ! $input == "Y" && ! $input == "y" ]]; then
79 echo "Aborted by user"
80 exit 1
81 fi
82 echo "$EMPTY_TASKFILE" > $TASKFILE
83 echo ""
84 fi
85
86
87 if [ "$1" == "check" ]; then
88 $ANSIBLE $TASKFILE --check --diff
89 fi
90
91 if [ "$1" == "link" ]; then
92 if [ ! -n "$2" ]; then
93 echo "Can symlink: (from $LINKFILES)"
94 cd $LINKFILES
95 ls -p | grep -v /
96 exit 1
97 fi
98
99 read -d '' LINK_THIS_FILE << EOF
100
101 - name: symlink $2
102 ansible.builtin.file:
103 src: "$LINKFILES/$2"
104 dest: "$HOME/.$2"
105 state: "link"
106 EOF
107
108 echo " $LINK_THIS_FILE" >> $TASKFILE
109 echo "$2 added to symlinks in $TASKFILE"
110 echo "Run 'dot apply' to create all configured symlinks"
111 fi
112
113
114 if [ "$1" == "apply" ]; then
115 if [[ ! -f "$TASKFILE" ]]; then
116 echo "$TASKFILE is missing. Run 'dot setup'"
117 exit 1
118 fi
119 $ANSIBLE $TASKFILE
120 fi
121
122 if [ "$1" == "install" ]; then
123 if [ ! -n "$2" ]; then
124 echo "Can install: (.sh scripts in $INSTALLS)"
125 cd $INSTALLS
126 ls -p | grep -v / | grep .sh
127 exit 1
128 fi
129 if [[ ! -f "$INSTALLS/$2.sh" ]]; then
130 echo "No such install script $INSTALLS/$2.sh"
131 echo "Run dot install with no params to list scripts."
132 exit 1
133 fi
134
135 mkdir -p $DOT
136 read -d '' RUN_INSTALL << EOF
137 - name: check $2
138 stat:
139 path: "$DOT/$2.installed"
140 register: $2_installed
141 - name: install $2
142 ansible.builtin.shell: |
143 "$INSTALLS/$2.sh"
144 touch "$DOT/$2.installed"
145 when: not $2_installed.stat.exists
146 - name: verify $2 is installed
147 ansible.builtin.debug:
148 msg: "$2 is installed."
149 when: $2_installed.stat.exists
150 EOF
151 echo " $RUN_INSTALL" >> $TASKFILE
152 echo "Run 'dot apply' to run the install"
153 fi