X-Git-Url: https://us-delaporte.pagekite.me/gitweb/dotfiles.git/blobdiff_plain/8c7db1f6bb896bc732ec7aa925a7865d5e772f61..2683674fac0457fb6c20fc476df20eb5da2ac71c:/bin/dot?ds=inline diff --git a/bin/dot b/bin/dot index 0fd7dd7..e2a83b3 100755 --- a/bin/dot +++ b/bin/dot @@ -1,32 +1,83 @@ #!/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 link FILE -# updates ~/dot.HOSTNAME.yaml -# to include a symlink from ~/dotfiles/files/FILE to ~/.FILE -# -# dot check -# check setup against ~/dot.HOSTNAME.yaml -# -# dot apply -# apply config in ~/dot.HOSTNAME.yaml +ENVS="$HOME/envs" # Python environments - including required Ansible +ANSIBLE="$ENVS/ansible/bin/ansible-playbook" # Core command +TASKFILE="$HOME/backup/dot.$HOSTNAME.yaml" # Backup of localhost config +DOTFILES="$HOME/dotfiles" # Where to find dotfiles + +LINKFILES="$DOTFILES/files" # Files to symlink +INSTALLS="$DOTFILES/install" # Install scripts +DOT="$HOME/.dot" # Touched files go here to track installs +REQS="$DOTFILES/reqs" # Python env requirements.txt files + +mkdir -p "$DOT" + +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 list + display the contents of $TASKFILE + +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 + +dot env ENV + create Python environment ~/envs/ENV based on ~/dotfiles/reqs/ENV.txt + +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" -LINKFILES="$HOME/dotfiles/files" -INSTALLS="$HOME/dotfiles/install" read -d '' EMPTY_TASKFILE << EOF --- @@ -41,6 +92,16 @@ read -d '' EMPTY_TASKFILE << EOF path: $TASKFILE EOF +if [[ ! -f "$TASKFILE" ]]; then + echo "Creating empty $TASKFILE" + mkdir -p "$HOME/backup" + echo "$EMPTY_TASKFILE" >> $TASKFILE +fi + +if [ "$1" == "list" ]; then + cat $TASKFILE + exit 0 +fi if [ "$1" == "setup" ]; then if [[ ! -f "$ANSIBLE" ]]; then @@ -52,10 +113,6 @@ if [ "$1" == "setup" ]; 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 @@ -78,7 +135,7 @@ fi if [ "$1" == "link" ]; then if [ ! -n "$2" ]; then - echo "May symlink:" + echo "Can symlink: (from $LINKFILES)" cd $LINKFILES ls -p | grep -v / exit 1 @@ -93,28 +150,101 @@ read -d '' LINK_THIS_FILE << EOF 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 + 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 + $ANSIBLE -v $TASKFILE fi if [ "$1" == "install" ]; then if [ ! -n "$2" ]; then - echo "Can install:" + echo "Can install: (.sh scripts in $INSTALLS)" cd $INSTALLS - ls -p | grep -v / + 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 - $INSTALLS/$2 + +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" + register: ret + failed_when: > + ("Error" in ret.stdout) or + ("Error" in ret.stderr) or + (ret.rc != 0) + 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 +if [ "$1" == "env" ]; then + if [ ! -n "$2" ]; then + echo "Can create: (.txt files in $REQS)" + cd $REQS + ls -p | grep -v / | grep .txt + exit 1 + fi + if [[ ! -f "$REQS/$2.txt" ]]; then + echo "No such requirements file script $REQS/$2.txt" + echo "Run dot env with no params to list files." + exit 1 + fi + +read -d '' ADD_ENV << EOF + - name: check env $2 + stat: + path: "$ENVS/$2" + register: $2_path + - name: add env $2 + ansible.builtin.shell: | + cd $ENVS + python3 -m venv $2 + $ENVS/$2/bin/python -m pip install -r $REQS/$2.txt + when: not $2_path.stat.exists + - name: verify env $2 exists + ansible.builtin.debug: + msg: "env $2 exists" + when: $2_path.stat.exists +EOF + echo " $ADD_ENV" >> $TASKFILE + echo "Run 'dot apply' to run the install" +fi +