config

A simple configuration manager

Commit
2b71fd0634d0b58ec26657581b169e7a8410cd56
Author
Pablo <pablo-escobar@riseup.net>
Date

Initial commit

Diffstat

2 files changed, 258 insertions, 0 deletions

Status File Name N° Changes Insertions Deletions
Added config 142 142 0
Added config.1 116 116 0
diff --git a/config b/config
@@ -0,0 +1,142 @@
+#!/bin/bash
+#                   __ _       
+#   ___ ___  _ __  / _(_) __ _ 
+#  / __/ _ \| '_ \| |_| |/ _` |
+# | (_| (_) | | | |  _| | (_| |
+#  \___\___/|_| |_|_| |_|\__, |
+#                        |___/ 
+#
+# A simple configuration manager
+# 2021 (C) Pablo
+# Free use of this software is granted under the terms of the GPL-3.0 License
+
+# Get the path to the git repository that should be used for storing stuff
+if [ -n "$DOTFILES_REPO" ]
+then
+  dotfiles_repo="$DOTFILES_REPO"
+elif [ -n "$XDG_DATA_HOME" ]
+then
+  dotfiles_repo="$XDG_DATA_HOME/dotfiles"
+else
+  dotfiles_repo="$HOME/.local/share/dotfiles"
+fi
+
+# Get the name of the files that holds the list of all dotfiles that should be
+# tracked
+if [ -n "$DOTFILES_LIST" ]
+then
+  dotfiles_list="$DOTFILES_LIST"
+elif [ -n "$XDG_CONFIG_HOME" ]
+then
+  dotfiles_list="$XDG_CONFIG_HOME/dotfiles.list"
+else
+  dotfiles_list="$HOME/.config/dotfiles.list"
+fi
+
+# Calls git in the appropriate repository
+call_git() 
+{
+  git --git-dir="$dotfiles_repo" --work-tree="$HOME" "$@"
+}
+
+# Parse the commands
+case "$1" in
+  # Commit and push updates to all remotes
+  update)
+    commit_msg_file="$(mktemp)"
+
+    # Add the relevant files to the repo
+    xargs git --git-dir="$dotfiles_repo" --work-tree="$HOME" add \
+      < "$dotfiles_list"
+
+    shift
+
+    while [ $# -gt 0 ]
+    do
+      case "$1" in
+        # Edit the commit message directly
+        -e|--edit)
+          printf '' > "$commit_msg_file"
+          $EDITOR "$commit_msg_file" 
+          break
+          ;;
+
+        # Append messages to the temporary file
+        *)
+          printf '%s\n\n' "$1" >> "$commit_msg_file"
+          shift
+          ;;
+      esac
+    done
+
+    # Commit the changes
+    call_git commit -F "$commit_msg_file" || exit $?
+
+    # Push the changes to all remotes
+    for remote in $(call_git remote -v | awk '/(push)/ { print $1 }' | uniq)
+    do
+      call_git push "$remote" master
+    done
+
+    rm "$commit_msg_file"
+    ;;
+
+  # Add files to the list of files
+  add)
+    shift
+
+    # Add files to the list of dotfiles
+    for item in "$@"
+    do
+      echo "Adding '$item' to the list of dotfiles"
+      realpath "$item" >> "$dotfiles_list"
+    done
+    ;;
+
+  # Remove files from the list of dotfiles
+  rm)
+    shift
+
+    # Remove files from the list of dotfiles
+    for item in "$@"
+    do
+      echo "Removing '$item' from the list of dotfile"
+      pattern="$(realpath "$item")"
+      pattern="${pattern//\//\\\/}"
+
+      # Remove the files from the git repository and from the list of files
+      # Awk is used because 'item' may be a directory
+      awk -i inplace "!/^$pattern/ { print }" "$dotfiles_list"
+      call_git rm "$item" --cached -r
+    done
+    ;;
+
+  # List the dotfiles specified in configurations list
+  list)
+    cat "$dotfiles_list"
+    ;;
+
+  # Show the configuration files that have been modified or deleted
+  status)
+    config_git_status="$(mktemp)"
+    call_git status > "$config_git_status"
+
+    echo 'modified files:'
+    awk '/modified/ { print $2 }' "$config_git_status" \
+      | xargs -r realpath \
+      | xargs -r -n 1 printf '    %s\n'
+
+    echo 'deleted files:'
+    awk '/deleted/ { print $2 }' "$config_git_status" \
+      | xargs -r realpath \
+      | xargs -r -n 1 printf '    %s\n'
+
+    rm "$config_git_status"
+    ;;
+
+  # Just pass the arguments to git
+  *)
+    call_git "$@"
+    ;;
+esac
+
diff --git a/config.1 b/config.1
@@ -0,0 +1,116 @@
+'\" t
+.\" 2021 (C) Pablo
+.\" Free use of this software is granted under the terms of the GPL-3.0 License
+.\"
+.TH "CONFIG" "1" "2021-04-17" "\ \&" "\ \&"
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.ss \n[.ss] 0
+.nh
+.ad l
+.de URL
+\fI\\$2\fP <\\$1>\\$3
+..
+.als MTO URL
+.if \n[.g] \{\
+.  mso www.tmac
+.  am URL
+.    ad l
+.  .
+.  am MTO
+.    ad l
+.  .
+.  LINKSTYLE blue R < >
+.\}
+.SH "CONFIG"
+config \- A simple configuration manager.
+.SH "SYNOPSIS"
+.sp
+\fBconfig\fP update (\-e|\-\-edit|MESSAGE)
+.sp
+\fBconfig\fP add FILE...
+.sp
+\fBconfig\fP rm FILE...
+.sp
+\fBconfig\fP list
+.sp
+\fBconfig\fP status
+.sp
+\fBconfig\fP log
+.SH "DESCRIPTION"
+.sp
+The config(1) command uses a bare Git repository to track dotfiles.
+.SH "COMMANDS"
+.sp
+\fBupdate\fP
+.RS 4
+Add the current changes, commit and push to all remotes. If the \fI\-e\fP
+or \fI\-\-edit\fP options are specified than config(1) uses \fI$EDITOR\fP to get the
+commit message. Otherwise, the following arguments are used for the commit
+message.
+.RE
+.sp
+\fBadd\fP
+.RS 4
+Add \fIFILE\fP to the list of files that should be tracked by config(1)
+.RE
+.sp
+\fBrm\fP
+.RS 4
+Remove \fIFILE\fP from the list of files that should be tracked by config(1)
+.RE
+.sp
+\fBlist\fP
+.RS 4
+List the files that are tracked by config(1)
+.RE
+.sp
+\fBstatus\fP
+.RS 4
+Show the working tree status
+.RE
+.sp
+Any other command is passed directly to Git. For example,
+.sp
+.if n .RS 4
+.nf
+.fam C
+$ config log
+.fam
+.fi
+.if n .RE
+.sp
+is the same as
+.sp
+.if n .RS 4
+.nf
+.fam C
+$ git log
+.fam
+.fi
+.if n .RE
+.sp
+when run from the appropriate directory.
+.SH "ENVIRONMENT"
+.sp
+\fB$DOTFILES_REPO\fP
+.RS 4
+Specify the location of the bare Git repo where the files
+are stored. Defaults to \fB$XDG_DATA_HOME/dotfiles\fP or
+\fB$HOME/.local/share/dotfiles\fP.
+.RE
+.sp
+\fB$DOTFILES_LIST\fP
+.RS 4
+Specify the location of the list of files that should be
+tracked by config(1). Defaults to \fB$XDG_CONFIG_HOME/dotfiles.list\fP or
+\fB$HOME/.config/dotfiles.list\fP.
+.RE
+.SH "AUTHORS"
+.sp
+\fBconfig\fP was written by Pablo <\c
+.MTO "pablo\-escobar\(atriseup.net" "" ">."
+.SH "COPYING"
+.sp
+Copyright (C) 2021 Pablo.
+Free use of this software is granted under the terms of the GPL\-3.0 License.