#!/bin/sh # # # worklog -- maintain a ChangeLog style WorkLog. # # addlog -- Add entries to a WorkLog file # showlog -- Concatenate the log file to stdout # editlog -- Lock and edit the WorkLog file # checklog -- Run tests on worklog and report results # #--------------------------------------------------------------------- # # This script is in the PUBLIC DOMAIN. Use at your own risk. # # REMEMBER, THIS IS A SIMPLE HACK. DON'T OVERENGINEER IT. # #--------------------------------------------------------------------- # # Authors: # ^chewie # #--------------------------------------------------------------------- # # From: ^chewie # # Let me know what you think about this hack. If you make improvements, I # can roll them back in. Just send me the patch in an email and get your # name added to the list of authors. # #--------------------------------------------------------------------- # HOW TO USE THIS SCRIPT # # Tie this into your ~/.bash_profile and ~/.bash_logout scripts # # ~/.bash_profile example # # DO_WORKLOG=1 # [ ! -x ~/bin/worklog -o ! -L ~/bin/addlog ] && DO_WORKLOG=0 # case $- in # *i*) # [ $DO_WORKLOG ] && { # # Ask if a more detailed entry should be added. # echo -n "Add an entry to your WorkLog? [N|y] " # read answer # case $answer in # [Yy]*) addlog -i;; # *);; # esac # } # ;; # esac # #--------------------------------------------------------------------- # ChangeLog (Add entries in descending order) # # Tue Feb 12 15:59:16 CST 2002 -- ^chewie # * Fixed a bashism, the 'echo -e' command was replaced with a "here" # document # * Made sure working directory existed # # Tue Feb 12 14:47:36 CST 2002 -- ^chewie # * Didn't like the tmpfile naming based on invocation. No biggie. # * Tried to be more consistend with variable naming # # Tue Feb 12 13:27:50 CST 2002 -- ^chewie # * Added $0 examining, encapsulated invocation specific tasks into # functions: do_addlog, do_editlog, do_showlog. # * Fixed invocation bugs with options. # * Exited upon displaying usage instead of running task # #--------------------------------------------------------------------- # reserved variables __me=`basename $0` hostname=${HOSTNAME:-unknown} # MISC defaults, Error codes & messages TRUE=1 FALSE=0 SUCCEED=0 FAIL=1 # # Edit these defaults # WKLOG_DIR=${WKLOG_DIR:-${HOME}/log/WorkLog} WKLOG_NAME=${WKLOG_NAME:-${USER}-`date +%Y%m%d`.log} WKLOG=${WKLOG:-$WKLOG_DIR/$WKLOG_NAME} WKLOG_TMP=${WKLOG_TMP:-$WKLOG.$USER.$hostname.$$} WKLOG_LCK=lck WKLOG_INTERACTIVE=${WKLOG_INTERACTIVE:-0} WKLOG_INTERVAL=${WKLOG_INTERVAL:-60} WKLOG_ALWAYSAPPEND=${WKLOG_ALWAYSAPPEND:-1} # STD variables EDITOR=${EDITOR:-vim} EDITOR_OPTS=${EDITOR_OPTS:-+} # # perror() -- print string to stderr # perror() { echo $@ 1>&2 } # # Useage for worklog program # do_worklog_usage() { cat << EOUSAGE 1>&2 Usage: addlog [OPTIONS] ["string"] -- Add entries to a WorkLog file showlog -- Concatenate the log file to stdout editlog -- Lock and edit the WorkLog file needlog -- Need a log entry? Based on env var WKLOG_INTERVAL This script is a simple shell wrapper for adding ChangeLog style entries to a WorkLog file. The original file name is 'worklog', where 'showlog', 'addlog', 'editlog', and 'needlog' should be symbolic links to 'worklog'. EOUSAGE } # # Usage for addlog # do_addlog_usage() { cat << EOUSAGE 1>&2 Usage: $__me [OPTIONS] ["Log entry..."] OPTIONS DESCRIPTION -h This message -i Interactive edit This wrapper concatenates the log entry to your designated WKLOG using your prefered EDITOR and EDITOR_OPTS You can set these in your environment variables or by editing the beginning of this shell script. WKLOG=${WKLOG}, EDITOR=${EDITOR}, EDITOR_OPTS=${EDITOR_OPTS} EOUSAGE } # # Usage for editlog # do_editlog_usage() { cat << EOUSAGE 1>&2 Usage: $__me [OPTIONS] OPTIONS DESCRIPTION -h This description Opens $WKLOG in $EDITOR with a lock. EOUSAGE } # # Usage for showlog # do_showlog_usage() { cat << EOUSAGE 1>&2 Usage: $__me Concatenate the Worklog ($WKLOG) to stdout. EOUSAGE } # # Usage for needlog # do_needlog_usage() { cat << EOUSAGE 1>&2 Usage: $__me Check to see whether the WorkLog needs an entry based on the WKLOG_INTERVAL environment variable. Exits with error code $SUCCEED if successful, $FAIL if failed. EOUSAGE } # # maketmp() -- make the temp file # do_maketmp() { umask 002 > $WKLOG_TMP [ $? -eq 0 ] && echo $WKLOG_TMP } # # do_chklock() -- Check for lock file. # do_chklock() { [ -e $WKLOG.$WKLOG_LCK ] && return $FAIL return $SUCCEED } # # do_lock() -- Create the lockfile. Returns with return value of cat. # do_lock() { do_chklock || return $FAIL cat << EOLOCK > $WKLOG.$WKLOG_LCK Host: $hostname User: $USER Date: `date` Process ID: $$ EOLOCK } # # do_unlock() -- Unlock the file # do_unlock() { rm $WKLOG.$WKLOG_LCK } # # do_addlog() -- Do the addlog task # * create a temp file for entry # * Append ARGV contents to entry # * If interactive, open editor. # * Obtain lock and concatenate file # * If no lock, exit # do_addlog() { # Make the temp file [ X`do_maketmp` = X ] && exit $FAIL # Add the basic entry cat << EOENTRY > $WKLOG_TMP `date` -- ${USER}@${hostname} * $@ EOENTRY # Check for interactive flag if [ $WKLOG_INTERACTIVE -eq 1 ] then $EDITOR $EDITOR_OPTS $WKLOG_TMP fi # Add a space echo "" >> $WKLOG_TMP # append the entry do_append_entries $WKLOG_TMP || { perror "Log entry failed." return $FAIL } return $SUCCEED } # # do_append_entries() -- Append worklog entries to worklog # do_append_entries() { entries=$@ # Lock the WorkLog do_lock || return $FAIL # Now, concatenate this to the end of the WorkLog file. cat $entries >> $WKLOG || { perror "Log append entry failed." return $FAIL } # Unlock the WorkLog do_unlock || return $FAIL rm $entries return $SUCCEED } # # do_append_temps() -- Find temp files, append them to worklog # Do not exit on failure. Return control to calling routine. # do_append_temps() { templist=`find $WKLOG_DIR -name ${WKLOG_NAME}.\*.\*.\*` [ X${templist} = X ] && return $FAIL if [ ! $WKLOG_ALWAYSAPPEND -a $WKLOG_INTERACTIVE -eq 1 ] then echo -n "You have old entries waiting to be added. Append them? [Y|n] " read answer case $answer in [n|N]*) return $FAIL ;; *) ;; esac elif [ ! $WKLOG_ALWAYSAPPEND ] then return $FAIL fi do_append_entries $templist || return $FAIL return $SUCCEED } # # do_needlog() -- worklog's lastmodified time # # exits with SUCCEED if last modification >= $WKLOG_INTERVAL, else FAIL # do_needlog() { isold=`find $WKLOG_DIR -name $WKLOG_NAME -mmin +$WKLOG_INTERVAL -print` [ X${isold} = X ] && return $FAIL return $SUCCEED } # # do_editlog -- Edit the WorkLog file itself with a lock. # Assume that this is interactive by default. # do_editlog() { # Lock the WorkLog do_lock || exit $FAIL $EDITOR $EDITOR_OPTS $WKLOG # Unlock the WorkLog do_unlock || exit $FAIL return $SUCCEED } # # do_showlog -- concatenate the WorkLog to stdout # do_showlog() { cat $WKLOG do_chklock || { perror "--------------------------------------" perror "ERROR: There is a lock on the WorkLog." perror `cat $WKLOG.$WKLOG_LCK` perror "--------------------------------------" } } #--------------------------------------------------------------------- # MAIN PROGRAM BODY # # Make sure Worklog directory exists [ ! -d $WKLOG_DIR ] && { mkdir -p $WKLOG_DIR [ $? -ne 0 ] && { echo "Could not make log directory: $WKLOG_DIR" 1>&2 exit 1 } } # # Assume interactive if no arguments # [ $# -eq 0 ] && WKLOG_INTERACTIVE=1 # # Parse command line for interactive # while getopts hi opt do case $opt in i) WKLOG_INTERACTIVE=1; shift;; h) do_${__me}_usage; exit 1; shift;; *);; esac done # Append any temp files we find. do_append_temps # Check for invocation type case $__me in addlog|editlog|showlog) do_$__me $@ ;; needlog) do_${__me} && exit $SUCCEED || exit $FAIL ;; *) do_worklog_usage;; esac exit $?