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