Script appears complete
This commit is contained in:
28
errors.md
Normal file
28
errors.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Simple Note System, version 2
|
||||||
|
## Error Code Reference
|
||||||
|
|
||||||
|
### General Codes
|
||||||
|
| Name | Code | Meaning |
|
||||||
|
|--------------|------|---------------------------------------|
|
||||||
|
| ERR_NO_STORE | 5 | the SNS store needs to be initialized |
|
||||||
|
| | | |
|
||||||
|
| ERR_NO_OPTS | 10 | No mode argument was specified |
|
||||||
|
| | | |
|
||||||
|
| ERR_NO_ARGS | 11 | A mode requiring an argument was |
|
||||||
|
| | | specified without an argument |
|
||||||
|
| | | |
|
||||||
|
|
||||||
|
### Encryption-related codes
|
||||||
|
|Name | Code | Meaning |
|
||||||
|
|------------|------|-----------------------------------------|
|
||||||
|
| ERR_NO_GPG | 100 | Encryption is enabled, but GPG is not |
|
||||||
|
| | | installed |
|
||||||
|
| | | |
|
||||||
|
| ERR_NO_KEY | 110 | Encryption is enabled, but no recipient |
|
||||||
|
| | | was specified |
|
||||||
|
|
||||||
|
### Creation-related codes
|
||||||
|
|Name | Code | Meaning |
|
||||||
|
|-----------------|------|------------------------------------|
|
||||||
|
| ERR_NOTE_EXiSTS | 200 | The specified note already exists |
|
||||||
|
| ERR_NOTE_NO_READ| 205 | The specified note cannot be read |
|
||||||
189
sns.sh
189
sns.sh
@@ -2,14 +2,44 @@
|
|||||||
XL_PRODUCT="Simple Note System"
|
XL_PRODUCT="Simple Note System"
|
||||||
XL_VER="v2a"
|
XL_VER="v2a"
|
||||||
|
|
||||||
# Environment
|
# Environment Constants
|
||||||
readonly SNS_STORE="$HOME/.local/sns"
|
readonly SNS_STORE="$HOME/.local/sns"
|
||||||
readonly SNS_KEYFILE="$SNS_STORE/.pubkey"
|
readonly SNS_KEYFILE="$SNS_STORE/.pubkey"
|
||||||
readonly SNS_DEPS=("gpg" "tree" "git")
|
readonly SNS_DEPS=("gpg2" "tree" "git")
|
||||||
readonly IFS=$'\n\t'
|
readonly IFS=$'\n\t'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
readonly SNS_RED_COLOR='\033[1;31m'
|
||||||
|
readonly SNS_YELLOW_COLOR='\033[1;33m'
|
||||||
|
readonly SNS_RESET_COLOR='\033[0m'
|
||||||
|
|
||||||
|
# Erroneous Exit Constants
|
||||||
|
|
||||||
|
# Invocation Errors
|
||||||
|
readonly SNS_ERR_NO_STORE=5 # The sns store needs to be initialized
|
||||||
|
readonly SNS_ERR_NO_OPTS=10 # No mode argument was specified
|
||||||
|
readonly SNS_ERR_NS_ARGS=11 # The specified mode requires an argument
|
||||||
|
|
||||||
|
# Dependency Errors
|
||||||
|
readonly SNS_ERR_DEPS=20 # Base error - add the following codes
|
||||||
|
readonly SNS_ERR_NO_gpg2=1 # GPG is not installed
|
||||||
|
readonly SNS_ERR_NO_tree=2 # Tree is not installed
|
||||||
|
readonly SNS_ERR_NO_git=3 # Git is not installed
|
||||||
|
|
||||||
|
# Global Variables
|
||||||
|
typeset -i SNS_SID="$RANDOM"
|
||||||
|
typeset -a SNS_ACTION=("")
|
||||||
|
typeset -a MISSING_DEPS
|
||||||
|
typeset -i SNS_EXIT=0
|
||||||
|
declare SNS_PUBKEY=
|
||||||
|
|
||||||
# Function Definitions
|
# Function Definitions
|
||||||
|
# sns_printError Prints an error message
|
||||||
|
# sns_NoteHeader Prints standard note header to stdout
|
||||||
|
# sns_checkDeps Checks the system for required dependencies
|
||||||
|
# sns_checkStore Checks if $SNS_STORE exists
|
||||||
|
# sns_sanityCheck Wrapper for sns_checkDeps and sns_checkStore
|
||||||
|
# ----
|
||||||
# sns_initStore Initializes the SNS Store ( -i)
|
# sns_initStore Initializes the SNS Store ( -i)
|
||||||
# sns_printHelp Prints help page ( -h)
|
# sns_printHelp Prints help page ( -h)
|
||||||
# sns_list Lists all notes in `tree` format ( *)
|
# sns_list Lists all notes in `tree` format ( *)
|
||||||
@@ -18,40 +48,18 @@ set -euo pipefail
|
|||||||
# sns_print Prints note to stdout ( -p)
|
# sns_print Prints note to stdout ( -p)
|
||||||
# sns_rm Deletes note from store ( -d)
|
# sns_rm Deletes note from store ( -d)
|
||||||
# sns_gitPassthrough Passes through all instructions to git (git)
|
# sns_gitPassthrough Passes through all instructions to git (git)
|
||||||
# sns_checkDeps Checks the system for required dependencies
|
|
||||||
# sns_checkStore Checks if $SNS_STORE exists
|
|
||||||
# sns_sanityCheck Wrapper for sns_checkDeps and sns_checkStore
|
|
||||||
|
|
||||||
function sns_initStore {
|
function sns_printError(){
|
||||||
mkdir -p "$SNS_STORE"
|
printf "$SNS_RED_COLOR!$SNS_RESET_COLOR - %s\n" "$@"
|
||||||
echo $* | awk '{print $1}' > "$SNS_KEYFILE"
|
|
||||||
}
|
}
|
||||||
function sns_printHelp(){
|
function sns_NoteHeader(){
|
||||||
printf "%s" "Import helpfile from sns v2"
|
printf "%s\n%s\n" "Title:" "Date:"
|
||||||
}
|
|
||||||
function sns_list(){
|
|
||||||
cd "$SNS_STORE" || exit
|
|
||||||
tree -C --noreport "$(echo $* | awk '{print $1}')"
|
|
||||||
}
|
|
||||||
function sns_create(){
|
|
||||||
gpg -r "$SNS_PUBKEY" -o "echo $* | awk '{print $1}'" < /dev/null
|
|
||||||
sns_edit "echo $* | awk '{print $1}'"
|
|
||||||
}
|
|
||||||
function sns_print(){
|
|
||||||
gpg -d "echo $* | awk '{print $1}'"
|
|
||||||
}
|
|
||||||
function sns_rm(){
|
|
||||||
rm -f "echo $* | awk '{print $1}'"
|
|
||||||
}
|
|
||||||
function sns_gitPassthrough(){
|
|
||||||
cd "$SNS_STORE" || exit;
|
|
||||||
git "$@";
|
|
||||||
}
|
}
|
||||||
function sns_checkDeps(){
|
function sns_checkDeps(){
|
||||||
local SNS_RETURN="true";
|
local SNS_RETURN="true";
|
||||||
for DEP in "${SNS_DEPS[@]}"; do
|
for DEP in "${SNS_DEPS[@]}"; do
|
||||||
if test ! -e "$(which gpg 2>/dev/null)"; then
|
if test ! -e "$(which "$DEP" 2>/dev/null)"; then
|
||||||
echo "Dependency missing: $DEP";
|
MISSING_DEPS+=("$DEP")
|
||||||
SNS_RETURN="false";
|
SNS_RETURN="false";
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -62,18 +70,112 @@ function sns_checkStore(){
|
|||||||
}
|
}
|
||||||
function sns_sanityCheck {
|
function sns_sanityCheck {
|
||||||
if ! sns_checkDeps; then
|
if ! sns_checkDeps; then
|
||||||
exit 10
|
SNS_EXIT="$SNS_ERR_DEPS"
|
||||||
|
for DEP in "${MISSING_DEPS[@]}"; do
|
||||||
|
local SNS_DEP_EC="\$ERR_NO_$DEP"
|
||||||
|
printError "Dependency %s not in path." "$DEP";
|
||||||
|
SNS_EXIT+=${!SNS_DEP_EC}
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
if ! sns_checkStore; then
|
|
||||||
if [ "$(echo "$SNS_ACTION" | awk '{print $1;}')" != "sns_initStore" ]; then
|
if [ -r "$SNS_STORE/.pubkey" ]; then
|
||||||
printf "%s\n" "Please run \`sns -i\` to initialize sns."
|
SNS_PUBKEY="$(cat "$SNS_STORE/.pubkey")"
|
||||||
exit 20
|
elif ! sns_checkStore; then
|
||||||
|
if [ "$(echo "${SNS_ACTION[@]}" | awk '{print $1;}')" != "sns_initStore" ]; then
|
||||||
|
printError "The sns store does not exist."
|
||||||
|
printf " - %s\n" "Please run \`sns -i [gpg-key]\` to initialize sns."
|
||||||
|
SNS_EXIT="$SNS_ERR_NO_STORE"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
#----
|
||||||
|
function sns_initStore {
|
||||||
|
mkdir -p "$SNS_STORE"
|
||||||
|
echo "$@" | awk '{print $1}' > "$SNS_KEYFILE"
|
||||||
|
}
|
||||||
|
function sns_printHelp(){
|
||||||
|
printf "%s" "usage: sns [-cedlp] <notebook/section/name>"
|
||||||
|
printf "\n%s%s%s" "usage: sns " "git" " ..."
|
||||||
|
printf "\n%s" " sns [-hi]"
|
||||||
|
|
||||||
|
printf "\n%s" " -c | --create : Create note"
|
||||||
|
printf "\n%s" " -C | --config : Edit Config"
|
||||||
|
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 SNS store"
|
||||||
|
printf "\n%s" " -l | --list : List all notes in NOTEBOOK"
|
||||||
|
printf "\n%s" " -p | --print : Print note to console"
|
||||||
|
printf "\n\n"
|
||||||
|
}
|
||||||
|
function sns_list(){
|
||||||
|
# Change directories to fix tree header
|
||||||
|
cd "$SNS_STORE" || exit; cd .. || exit;
|
||||||
|
# Print the tree
|
||||||
|
tree -C --noreport --prune "$(echo "$@" | awk '{print $1}')"
|
||||||
|
}
|
||||||
|
function sns_create(){
|
||||||
|
# Make sure the note doesn't already exist
|
||||||
|
if [ -r "$SNS_STORE/$(echo "$@" | awk '{print $1}')" ]; then
|
||||||
|
sns_printError "Note already exists."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Print the standard header to a temporary note
|
||||||
|
sns_NoteHeader > /tmp/"$SNS_SID"
|
||||||
|
|
||||||
|
# Edit the new note
|
||||||
|
sns_edit "$(echo "$@" | awk '{print $1}')"
|
||||||
|
}
|
||||||
|
function sns_edit(){
|
||||||
|
# Make the function more readable
|
||||||
|
local readonly SNS_NOTE="$SNS_STORE/$(echo "$@" | awk '{print $1}')"
|
||||||
|
|
||||||
|
# Test if edit was called from create
|
||||||
|
if [ ! -r /tmp/"$SNS_SID" ]; then gpg2 -d -o /tmp/"$SNS_SID" "$SNS_NOTE"; fi
|
||||||
|
|
||||||
|
# Edit the note
|
||||||
|
vim /tmp/"$SNS_SID"
|
||||||
|
|
||||||
|
# Make sure the notebook/section exists
|
||||||
|
if [ ! -d "$(dirname "$SNS_NOTE")" ]; then mkdir -p "$(dirname "$SNS_NOTE")"; fi
|
||||||
|
|
||||||
|
# If the note previously existed, make a backup.
|
||||||
|
if [ -r "$SNS_NOTE" ]; then mv "$SNS_NOTE" "$SNS_NOTE.bk"; fi
|
||||||
|
|
||||||
|
# Re-encrypt it to the store
|
||||||
|
gpg2 -r "$SNS_PUBKEY" -o "$SNS_NOTE" -e /tmp/"$SNS_SID"
|
||||||
|
|
||||||
|
# If all went well, remove the backup
|
||||||
|
if [ -r "$SNS_NOTE" ]; then rm "$SNS_NOTE.bk"; fi
|
||||||
|
}
|
||||||
|
function sns_print(){
|
||||||
|
gpg2 -d "$SNS_STORE/$(echo "$@" | awk '{print $1}')"
|
||||||
|
}
|
||||||
|
function sns_rm(){
|
||||||
|
rm -f "$SNS_STORE/$(echo "$@" | awk '{print $1}')"
|
||||||
|
}
|
||||||
|
function sns_gitPassthrough(){
|
||||||
|
cd "$SNS_STORE" || exit;
|
||||||
|
git "$@";
|
||||||
|
}
|
||||||
|
# ----
|
||||||
function sns_argParse(){
|
function sns_argParse(){
|
||||||
declare -ga SNS_ACTION=()
|
ARGS=($@)
|
||||||
|
#echo "${#ARGS}"
|
||||||
|
SNS_ACTION=()
|
||||||
while getopts ":i:hc:e:p:d:" OPT; do
|
while getopts ":i:hc:e:p:d:" OPT; do
|
||||||
|
|
||||||
|
# If an option requiring an argument was passed without an argument,
|
||||||
|
# inform the user and set exit code to "$SNS_ERR_NS_ARGS"
|
||||||
|
case "${ARGS[!OPTIND]}" in
|
||||||
|
-i|-c|-e|-p|-d)
|
||||||
|
if [ "${#ARGS}" -lt 2 ]; then
|
||||||
|
printError "A required argument was not given."
|
||||||
|
SNS_EXIT="$SNS_ERR_NS_ARGS"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
esac
|
||||||
case "$OPT" in
|
case "$OPT" in
|
||||||
i)
|
i)
|
||||||
SNS_ACTION=("sns_initStore" "$OPTARG");;
|
SNS_ACTION=("sns_initStore" "$OPTARG");;
|
||||||
@@ -89,12 +191,15 @@ function sns_argParse(){
|
|||||||
SNS_ACTION=("sns_rm $OPTARG");;
|
SNS_ACTION=("sns_rm $OPTARG");;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "${#SNS_ACTION[@]}" -eq 0 ]; then
|
if [ "${#SNS_ACTION[@]}" -eq 0 ]; then
|
||||||
if [ "$(echo "$@" | awk '{print $1}')" == "git" ]; then
|
if [ "$(echo "$@" | awk '{print $1}')" == "git" ]; then
|
||||||
SNS_ACTION=($@)
|
SNS_ACTION=($@)
|
||||||
else
|
else
|
||||||
if [ -d "$SNS_STORE/$*" ]; then
|
if [ -d "$SNS_STORE/$*" ]; then
|
||||||
SNS_ACTION=("sns_list" "./$*")
|
SNS_ACTION=("sns_list" "sns/$@")
|
||||||
|
else
|
||||||
|
SNS_ACTION=("sns_list" "sns")
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -102,6 +207,14 @@ function sns_argParse(){
|
|||||||
|
|
||||||
# Entry Point
|
# Entry Point
|
||||||
printf "%s\n%s\n" "$XL_PRODUCT" "$XL_VER"
|
printf "%s\n%s\n" "$XL_PRODUCT" "$XL_VER"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
sns_argParse "$@"
|
sns_argParse "$@"
|
||||||
sns_sanityCheck
|
sns_sanityCheck
|
||||||
"${SNS_ACTION[@]}"
|
if [ "$SNS_EXIT" -eq 0 ]; then
|
||||||
|
eval "${SNS_ACTION[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
exit "$SNS_EXIT"
|
||||||
|
|||||||
Reference in New Issue
Block a user