Files
vns/vns
2018-02-05 17:50:44 -06:00

251 lines
6.6 KiB
Bash
Executable File

#!/usr/bin/env bash
XL_PRODUCT="Vim Note System"
XL_VER="1.0b1"
# Environment Constants
readonly VNS_STORE="$HOME/.config/vns"
readonly IFS=$'\n\t'
# ASCII Color Codes
readonly VNS_RED_COLOR='\033[0;31m'
readonly VNS_BLUE_COLOR='\033[0;34m'
readonly VNS_RESET_COLOR='\033[0m'
# Fail on unsuccessful command pipes and unset variables
set -euo pipefail
# Erroneous Exit Codes
# |Code| Meaning |
# |----|-----------------------------------------|
# | 5 | The vns store needs to be initialized |
# | 11 | Insufficient arguments |
# | 15 | No editor specified in environment |
# | 20 | Missing dependency |
# | 31 | Note already exists |
# | 41 | Note not found |
vns_raise (){
# raise (message) (exit code)
# Prints error (message) to stderr, then exits with (exit code)
printf "%s, %s\n\n" "$XL_PRODUCT" "$XL_VER"
printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\n" "$1" 1>&2
exit "$2"
}
vns_checkDeps (){
# checkDeps
# Prints a list of unbound variables
readonly VNS_DEPS=("vim" "gpg2" "tree" "git")
for DEP in "${VNS_DEPS[@]}"; do
if test ! -e "$(which "$DEP" 2>/dev/null)"; then
printf "%s " "$DEP"
fi
done
}
vns_sanityCheck () {
# sanityCheck
# Terminates script if environment is not suitable for vns
# --- Dependencies ---
# Get list of missing dependencies
local MISSING; MISSING="$(vns_checkDeps)"
# If that list is not empty, inform the user and exit on code 20
if [ -n "$MISSING" ]; then
vns_raise "Missing Dependencies: $MISSING" 20
fi
# --- Store ---
# Verify that the note store has been initialized
if [ ! -d "$VNS_STORE" ]; then
vns_raise "The vns store needs to be initialized (hint: -i)" 5
fi
}
#----
vns_init () {
# initStore
# Prepares $VNS_STORE for use
mkdir -p "$VNS_STORE"
cd "$VNS_STORE" || exit
git init >/dev/null
}
vns_printHelp (){
# printHelp
# Prints help information to stdout
printf "%s" "usage: vns [-cedlp] <notebook/section/name>"
printf "\n%s" " vns -i <gnupg recipient>"
printf "\n%s" " vns -h"
printf "\n%s%s%s" "usage: vns " "git" " ..."
printf "\n%s" " -c | --create : Create note"
printf "\n%s" " -d | --delete : Delete note"
printf "\n%s" " -e | --edit : Open note for editing"
printf "\n%s" " -h | --help : Display this message"
printf "\n%s" " -i | --init : Write default config and initalize VNS store"
printf "\n%s" " -l | --list : List all notes in NOTEBOOK"
printf "\n%s" " -p | --print : Print note to console"
printf "\n\n"
}
vns_list () {
# list (notebook)
# Prints a tree containing all notes in the notebook
# If no notebook is specified, the entire store is used
# Check for default behavior
if [ -z "${*:1:1}" ]; then
readonly NOTEBOOK=""
printf "%s\n" "Store"
else
readonly NOTEBOOK="$1"
printf "%s\n" "$1"
fi
tree -C --noreport --prune "$VNS_STORE/$NOTEBOOK"\
| tail -n +2\
| sed s/\.gpg//g
}
vns_rm () {
# rm (note)
# removes (note) from the store
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi
# Verify the note exists
if [ ! -r "$VNS_STORE/$1.gpg" ]; then
vns_raise "Note does not exist" 41;
fi
# Delete the Note
git rm "$VNS_STORE/$1.gpg" > /dev/null
git commit -m "Deleted $1" > /dev/null
# Report success
printf "%s, %s\n\n" "$XL_PRODUCT" "$XL_VER"
printf "$VNS_BLUE_COLOR!$VNS_RESET_COLOR - %s\n" "Deleted $VNS_STORE/$1"
}
vns_create () {
# create (note)
# Edit a previously non-existant note
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi
# Refuse to overwrite a note
if [ -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note already exists" 31; fi
# If the note belongs to a new notebook, create the notebook
if [ ! -d "$(dirname "$1")" ]; then mkdir -p "$VNS_STORE/$(dirname "$1")"; fi
# Create-Edit the note
vim "$VNS_STORE/$1.gpg"
# Warn the user if the note failed to encrypt
if ! grep "PGP" <<< "$(file "$VNS_STORE/$1")" > /dev/null; then
printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\n %s\n"\
"The created note was not encrypted."\
"Check your vim-gnupg setup."
fi
# Update Git
git add "$VNS_STORE/$1.gpg" > /dev/null
git commit -m "Added $1" > /dev/null
}
vns_edit () {
# edit (note)
# edit (note) in the store
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi
# Refuse to edit non-existant notes
if [ ! -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note not found: $1" 41; fi
# Edit the specified note
vim "$VNS_STORE/$1.gpg"
# Update Git
git add "$VNS_STORE/$1.gpg" > /dev/null
git commit -m "Edited $1" > /dev/null
}
vns_print () {
# print (note)
# print the given note to stdout
# Verify $1 is bound
if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi
# Decrypt the specified note
gpg2 -d "$VNS_STORE/$1.gpg"
}
# ----
vns () {
# Bypass sanity check if told to initialize store
if [ "$*" != "-i" ]; then
vns_sanityCheck;
# Change Directory to Store for Git passthrough
cd "$VNS_STORE" || exit;
fi
# Default action is to list all notes
if [ -z "${*:1:1}" ]; then vns_list ""; exit 0; fi
# List of valid arguments
declare -A -r ACTIONS=( ["-c"]="vns_create" ["-d"]="vns_rm"\
["-e"]="vns_edit" ["-l"]="vns_list"\
["-h"]="vns_printHelp" ["-i"]="vns_init"\
["-p"]="vns_print"\
["git"]="git" )
# If given an invalid argument, inform the user and exit on code 10
# Otherwise, perform the corresponding action
if ! test "${ACTIONS["$1"]+isset}"; then
vns_raise "Invalid argument: $1" 10
else
"${ACTIONS["$1"]}" "${@:2}"
fi
# Print an extra newline just in case
# printf "\n";
exit 0;
}
vns "$@"