diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..e12f80d --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,3 @@ +v1.1 +Added merge, rename options +Enabled gpg-agent diff --git a/DEBUG b/DEBUG new file mode 100644 index 0000000..9c323a3 --- /dev/null +++ b/DEBUG @@ -0,0 +1,30 @@ +Vim Note System, v1.1 + +The following is a table of exit codes + +Code In Function Meaning +----------------------------------------------------- +10 vns Invalid argument given + +20 sanityCheck Missing dependencies +21 sanityCheck VNS store not initialized + +30 rm Insufficient arguments +31 rm Note does not exist + +40 create Insufficient arguments +41 create Note already exists + +50 edit Insufficient arguments +51 edit Note not found + +60 print Insufficient arguments + +70 mv Insufficient arguments +71 mv Couldn't read source note +72 mv Destination note already exists + +81 merge No output specified +82 merge Output file already exists. +83 merge could not open note + diff --git a/vns b/vns old mode 100755 new mode 100644 index 527cce3..deba1a4 --- a/vns +++ b/vns @@ -1,37 +1,38 @@ #!/usr/bin/env bash -XL_PRODUCT="Vim Note System" -XL_VER="1.0" +# Vim Note System v1.1, a simple script for managing encrypted plaintext notes +# Copyright (C) 2018 Jon Lewis -# Environment Constants -readonly VNS_STORE="$HOME/.config/vns" +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. -readonly IFS=$'\n\t' +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. -# ASCII Color Codes -readonly VNS_RED_COLOR='\033[0;31m' -readonly VNS_BLUE_COLOR='\033[0;34m' -readonly VNS_RESET_COLOR='\033[0m' +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# Fail on unsuccessful command pipes and unset variables -set -euo pipefail +set -euo pipefail # Terminate the script if anything goes wrong + # http://redsymbol.net/articles/unofficial-bash-strict-mode/ -# 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 | +readonly VNS_PRODUCT="Vim Note System, v1.1" # String to print for reports +readonly VNS_STORE="$HOME/.config/vns" # Where vns expects its note store +readonly GPG_TTY="$(tty)" # Sets up gpg-agent for use 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 + + local -r VNS_RED_COLOR='\033[0;31m' + local -r VNS_RESET_COLOR='\033[0m' + + printf "%s, %s\\n\\n" "$VNS_PRODUCT" + printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\\n" "$1" 1>&2 exit "$2" } @@ -68,12 +69,11 @@ vns_sanityCheck () { # --- 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 + vns_raise "The vns store needs to be initialized (hint: -i)" 21 fi } -#---- vns_init () { # initStore @@ -91,18 +91,18 @@ vns_printHelp (){ # Prints help information to stdout printf "%s" "usage: vns [-cedlp] " - printf "\n%s" " vns -i" - printf "\n%s" " vns -h" - printf "\n%s" " vns git ..." - printf "\n" - 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 : Initialize note store" - printf "\n%s" " -l | --list : List all notes in " - printf "\n%s" " -p | --print : Print note to console" - printf "\n\n" + printf "\\n%s" " vns -i" + printf "\\n%s" " vns -h" + printf "\\n%s" " vns git ..." + printf "\\n" + 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 : Initialize note store" + printf "\\n%s" " -l | --list : List all notes in " + printf "\\n%s" " -p | --print : Print note to console" + printf "\\n\\n" } @@ -118,11 +118,11 @@ vns_list () { if [ -z "${*:1:1}" ]; then readonly NOTEBOOK="" if [ "$(numNotes)" != "0" ];then - printf "%s\n" "Store" + printf "%s\\n" "Store" fi else readonly NOTEBOOK="$1" - printf "%s\n" "$1" + printf "%s\\n" "$1" fi tree -C --noreport --prune "$VNS_STORE/$NOTEBOOK"\ @@ -136,20 +136,23 @@ vns_rm () { # rm (note) # removes (note) from the store + local -r VNS_BLUE_COLOR='\033[0;34m' + local -r VNS_RESET_COLOR='\033[0m' + # Verify $1 is bound - if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi + if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 30; fi # Verify the note exists if [ ! -r "$VNS_STORE/$1.gpg" ]; then - vns_raise "Note does not exist" 41; + vns_raise "Note does not exist" 31; 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" + printf "%s, %s\\n\\n" "$VNS_PRODUCT" + printf "$VNS_BLUE_COLOR!$VNS_RESET_COLOR - %s\\n" "Deleted $VNS_STORE/$1" } @@ -158,11 +161,14 @@ vns_create () { # create (note) # Create a new note and open it for editing + local -r VNS_RED_COLOR='\033[0;31m' + local -r VNS_RESET_COLOR='\033[0m' + # Verify $1 is bound - if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi + if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 40; fi # Refuse to overwrite a note - if [ -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note already exists" 31; fi + if [ -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note already exists" 41; fi # If the note belongs to a new notebook, create the notebook if [ ! -d "$(dirname "$1")" ]; then mkdir -p "$VNS_STORE/$(dirname "$1")"; fi @@ -172,7 +178,7 @@ vns_create () { # Warn the user if the note failed to encrypt if ! grep "PGP" <<< "$(file "$VNS_STORE/$1.gpg")" > /dev/null; then - printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\n %s\n"\ + printf "$VNS_RED_COLOR!$VNS_RESET_COLOR - %s\\n %s\\n"\ "The created note was not encrypted."\ "Check your vim-gnupg setup." fi @@ -189,10 +195,10 @@ vns_edit () { # Open (note) for editing in Vim # Verify $1 is bound - if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 11; fi + if [ -z "${*:1:1}" ]; then vns_raise "Insufficient arguments" 50; fi # Refuse to edit non-existent notes - if [ ! -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note not found: $1" 41; fi + if [ ! -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Note not found: $1" 51; fi # Edit the specified note vim "$VNS_STORE/$1.gpg" @@ -215,7 +221,52 @@ vns_print () { } -# ---- +vns_mv () { + + # mv (src) (dest) + # If (src) is a note in the vns store, mv src dest moves src to dest + + if [ -z "${*:2}" ]; then vns_raise "Insufficient arguments" 70; fi + if [ ! -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Cannot read $1" 71; fi + if [ -r "$VNS_STORE/$2.gpg" ]; then vns_raise "Note $2 already exists" 72; fi + + git mv "$VNS_STORE/$1.gpg" "$VNS_STORE/$2.gpg" + +} + +vns_merge () { + + # merge (output) (notes[]) + # If notes[] is an array of note names and output is a new note name, + # merge (output) (notes[]) concatenates notes[] into output. + + if [ -z "${*:1}" ]; then vns_raise "No output specified" 81; fi + if [ -r "$VNS_STORE/$1.gpg" ]; then vns_raise "Output file already exists." 82; fi + + # Make output file + if [ ! -r "$VNS_STORE/$2.gpg" ]; then vns_raise "Could not read $2" 83; fi + cp "$VNS_STORE/$2.gpg" "$VNS_STORE/$1.gpg" + + local -r GPG_RECIP="$(gpg --list-only -v -d "$VNS_STORE/$1.gpg" 2>&1 | cut -f 5 -d " ")" + + for note in "${@:3}"; do + if [ ! -r "$VNS_STORE/$note.gpg" ]; then + rm "$VNS_STORE/$1.gpg" + vns_raise "Could not read $note" 83; + fi + + gpg2 --batch --yes -r "$GPG_RECIP" -o "$VNS_STORE/$1.gpg" -e <<< "$(gpg2 -d "$VNS_STORE/$1.gpg") $(gpg2 -d "$VNS_STORE/$note.gpg")" + done + + for note in "${@:2}"; do + git rm "$VNS_STORE/$note.gpg" + done + + git add "$VNS_STORE/$1.gpg" + + git commit -m "merged files ${*:2} into $1" +} + vns () { # Bypass sanity check if told to initialize store @@ -224,7 +275,6 @@ vns () { # Change Directory to Store for Git passthrough cd "$VNS_STORE" || exit; fi - # Default action is to list all notes @@ -234,8 +284,8 @@ vns () { 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" ) + ["-m"]="vns_merge" ["-p"]="vns_print"\ + ["-r"]="vns_mv" ["git"]="git" ) # If given an invalid argument, inform the user and exit on code 10 # Otherwise, perform the corresponding action