From a27d2aba0cc2870be5b96e836efbc998ba78735d Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 11:30:39 -0700 Subject: [PATCH 01/12] Clean up list_pages * Use bash arrays to load and iterate over paths * Use bash builtin regex and paramater expansion to filter files * Drop the dependency to perl in this function --- bin/mad | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/bin/mad b/bin/mad index b381fcb..1f949ee 100755 --- a/bin/mad +++ b/bin/mad @@ -6,25 +6,31 @@ REMOTE_MAD=git://github.com/visionmedia/mad.git CONFIG=$(dirname $0)/../etc/mad.conf MAD_CONFIG=${MAD_CONFIG:-$CONFIG} +shopt -s nocasematch + # # List all # - list_pages() { - IFS=":" local paths="$MAD_PATH:/usr/local/share/mad:/usr/share/mad" + local readme_re='^readme' + # load paths into array + local path_array= + IFS=: read -a path_array <<< "$paths" echo printf " \033[1mmad pages:\033[0m\n" echo - for path in $paths; do - test ! -z $path \ - && test -d $path \ - && find $path -type f -print0 \ - | xargs -0 basename -a \ - | grep -iv 'readme*' \ - | grep '.md$' \ - | perl -pe 's|^(.*)\.md$| \1|;' + for path in ${path_array[@]}; do + [[ -z "$path" || ! -d "$path" ]] && continue + while read -r -d '' file; do + file=${file##*/} # basename + ext=${file##*.} # extension + raw_file=${file%.*} # filename w/o extension + if [[ "$ext" == "md" && ! "$raw_file" =~ $readme_re ]]; then + printf ' %s\n' "$raw_file" + fi + done< <(find "$path" -type f -print0) done echo } From 371f443cf5bd6a820d272004bb9f2f52eda7c694 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 11:52:53 -0700 Subject: [PATCH 02/12] Cleaning up get() * UUOC http://partmaps.org/era/unix/award.html#cat --- bin/mad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/mad b/bin/mad index 1f949ee..ee6ddd4 100755 --- a/bin/mad +++ b/bin/mad @@ -64,7 +64,7 @@ display() { # get() { - cat $MAD_CONFIG | grep $1 | awk '{ print $2 }' + grep "$1" "$MAD_CONFIG" | awk '{ print $2 }' } # From fe4eb3d1aa337c41bf374aedf8cd7d4001a91c24 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 11:55:54 -0700 Subject: [PATCH 03/12] Using bash builtin instead of external commands * test, [ are limited commands, [[ is built in ** http://mywiki.wooledge.org/BashFAQ/031 --- bin/mad | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/mad b/bin/mad index ee6ddd4..c6bae0f 100755 --- a/bin/mad +++ b/bin/mad @@ -47,8 +47,8 @@ display() { for path in $paths; do local file=$path/$page local ext=$path/$page.md - test -f $file && display_file $file - test -f $ext && display_file $ext + [[ -f "$file" ]] && display_file $file + [[ -f "$ext" ]] && display_file $ext done echo @@ -144,7 +144,7 @@ install_mad() { # file required -test $# -eq 0 && display_mad_usage +[[ -z "$1" ]] && display_mad_usage # parse args From 117b03f369ec24f307122998a3a96c3a83238293 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 12:28:33 -0700 Subject: [PATCH 04/12] Replacing external programs with bash builtins * Dirname can be done with parameter expansion * All variables should be quoted to avoid wordsplitting ** http://mywiki.wooledge.org/BashFAQ/028 --- bin/mad | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/mad b/bin/mad index c6bae0f..596036a 100755 --- a/bin/mad +++ b/bin/mad @@ -3,7 +3,7 @@ VERSION="0.4.0" REMOTE=git://github.com/visionmedia/mad-pages.git REMOTE_MAD=git://github.com/visionmedia/mad.git -CONFIG=$(dirname $0)/../etc/mad.conf +CONFIG=${0%/*}/../etc/mad.conf MAD_CONFIG=${MAD_CONFIG:-$CONFIG} shopt -s nocasematch @@ -42,7 +42,7 @@ list_pages() { display() { IFS=":" local page=$1 - local paths=".:$MAD_PATH:$(dirname $0)/../share/mad:/usr/share/mad" + local paths=".:$MAD_PATH:${0%/*}/../share/mad:/usr/share/mad" for path in $paths; do local file=$path/$page @@ -105,7 +105,7 @@ display_file() { # display_mad_usage() { - display_file $(dirname $0)/../share/mad/mad.md + display_file "${0%/*}/../share/mad/mad.md" exit } @@ -114,7 +114,7 @@ display_mad_usage() { # install_all_remote() { - local path=$(dirname $0)/../share/mad + local path=${0%/*}/../share/mad echo echo " ... cloning repo" cd /tmp && rm -fr mad-pages From b64bd64a7a08d5b17da8e91a448cb4c31e2c419d Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 13:23:32 -0700 Subject: [PATCH 05/12] Cleanup display * Use bash arrays to load and iterate over paths safely --- bin/mad | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/mad b/bin/mad index 596036a..5f0f168 100755 --- a/bin/mad +++ b/bin/mad @@ -40,11 +40,13 @@ list_pages() { # display() { - IFS=":" local page=$1 local paths=".:$MAD_PATH:${0%/*}/../share/mad:/usr/share/mad" + # load paths into array + local path_array= + IFS=: read -a path_array <<< "$paths" - for path in $paths; do + for path in ${path_array[@]}; do local file=$path/$page local ext=$path/$page.md [[ -f "$file" ]] && display_file $file From 4a53bf1108ee5a3a7b72e06d7b6d95fdb1984a56 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 13:24:30 -0700 Subject: [PATCH 06/12] Prefer PAGER env variable and fallback on less(1) --- bin/mad | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/mad b/bin/mad index 5f0f168..96353cc 100755 --- a/bin/mad +++ b/bin/mad @@ -5,6 +5,7 @@ REMOTE=git://github.com/visionmedia/mad-pages.git REMOTE_MAD=git://github.com/visionmedia/mad.git CONFIG=${0%/*}/../etc/mad.conf MAD_CONFIG=${MAD_CONFIG:-$CONFIG} +PAGER=${PAGER:-less} shopt -s nocasematch @@ -98,7 +99,7 @@ display_file() { s| (.+)| \e[$code\1\e[0m|g; \ s|<(.+?)>||g; \ s|^| |;" \ - | less -R + | "$PAGER" -R exit } From 08c85cd7bb10f411de0f57582c241daefd0e0d24 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 13:26:49 -0700 Subject: [PATCH 07/12] Cleaning up display() * UUOC http://partmaps.org/era/unix/award.html#cat --- bin/mad | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/bin/mad b/bin/mad index 96353cc..f274620 100755 --- a/bin/mad +++ b/bin/mad @@ -88,17 +88,16 @@ display_file() { local strong=$(get strong) local em=$(get em) - cat $1 \ - | perl -pe " - s|^#+ *(.+)|\e[$heading\1\e[0m|g; \ - s|\`(.+?)\`|\e[$code\1\e[0m|g; \ - s|\*\*(.+?)\*\*|\e[$strong\1\e[0m|g; \ - s|__(.+?)__|\e[$strong\1\e[0m|g; \ - s|\*(.+?)\*|\e[$em\1\e[0m|g; \ - s|_(.+?)_|\e[$em\1\e[0m|g; \ - s| (.+)| \e[$code\1\e[0m|g; \ - s|<(.+?)>||g; \ - s|^| |;" \ + < "$1" perl -pe " + s|^#+ *(.+)|\e[$heading\1\e[0m|g; \ + s|\`(.+?)\`|\e[$code\1\e[0m|g; \ + s|\*\*(.+?)\*\*|\e[$strong\1\e[0m|g; \ + s|__(.+?)__|\e[$strong\1\e[0m|g; \ + s|\*(.+?)\*|\e[$em\1\e[0m|g; \ + s|_(.+?)_|\e[$em\1\e[0m|g; \ + s| (.+)| \e[$code\1\e[0m|g; \ + s|<(.+?)>||g; \ + s|^| |;" \ | "$PAGER" -R exit } From df278fa876339cfbc1e312ce8cd223a38ab1bd04 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 13:32:25 -0700 Subject: [PATCH 08/12] Passing exit code from PAGER properly, removing unnecessary call to exit --- bin/mad | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/mad b/bin/mad index f274620..df9d7e3 100755 --- a/bin/mad +++ b/bin/mad @@ -99,7 +99,7 @@ display_file() { s|<(.+?)>||g; \ s|^| |;" \ | "$PAGER" -R - exit + exit $? } # @@ -108,7 +108,6 @@ display_file() { display_mad_usage() { display_file "${0%/*}/../share/mad/mad.md" - exit } # From 296fd390df4cb9ee382cf6786c7cf65963304222 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 13:53:14 -0700 Subject: [PATCH 09/12] Calls to chdir(2) should be error checked * Bad things can happen if you don't sanity check cd --- bin/mad | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/bin/mad b/bin/mad index df9d7e3..999a29f 100755 --- a/bin/mad +++ b/bin/mad @@ -118,14 +118,16 @@ install_all_remote() { local path=${0%/*}/../share/mad echo echo " ... cloning repo" - cd /tmp && rm -fr mad-pages - git clone --depth 1 $REMOTE mad-pages - cd mad-pages - for page in *.md; do - echo " ... installing $page" - cp -f $page $path/$page - done - echo " ... complete" + cd /tmp && rm -fr mad-pages || exit 2 + if git clone --depth 1 $REMOTE mad-pages && cd mad-pages; then + for page in *.md; do + echo " ... installing $page" + cp -f $page $path/$page + done + echo " ... complete" + else + echo " ... failed!" >&2 + fi echo } @@ -136,10 +138,13 @@ install_all_remote() { install_mad() { echo echo " ... cloning repo" - cd /tmp && rm -fr mad + cd /tmp && rm -fr mad || exit 3 git clone --depth 1 $REMOTE_MAD mad - cd mad && make install - echo " ... updated to $(mad --version)" + if cd mad && make install; then + echo " ... updated to $(mad --version)" + else + echo " ... failed to update!" >&2 + fi echo } From 46015283a42e6bc9aa867b8e8d010f10c8d60866 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 14:04:29 -0700 Subject: [PATCH 10/12] Case insensitivity should be set within functional scope --- bin/mad | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/mad b/bin/mad index 999a29f..396609f 100755 --- a/bin/mad +++ b/bin/mad @@ -7,8 +7,6 @@ CONFIG=${0%/*}/../etc/mad.conf MAD_CONFIG=${MAD_CONFIG:-$CONFIG} PAGER=${PAGER:-less} -shopt -s nocasematch - # # List all # @@ -19,6 +17,8 @@ list_pages() { local path_array= IFS=: read -a path_array <<< "$paths" + shopt -s nocasematch + echo printf " \033[1mmad pages:\033[0m\n" echo From 021d276ad08974f45ab034ddc20916c742b210c1 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 14:06:50 -0700 Subject: [PATCH 11/12] Quote all potentially dangerous expansions --- bin/mad | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bin/mad b/bin/mad index 396609f..7e59b82 100755 --- a/bin/mad +++ b/bin/mad @@ -50,8 +50,8 @@ display() { for path in ${path_array[@]}; do local file=$path/$page local ext=$path/$page.md - [[ -f "$file" ]] && display_file $file - [[ -f "$ext" ]] && display_file $ext + [[ -f "$file" ]] && display_file "$file" + [[ -f "$ext" ]] && display_file "$ext" done echo @@ -119,10 +119,10 @@ install_all_remote() { echo echo " ... cloning repo" cd /tmp && rm -fr mad-pages || exit 2 - if git clone --depth 1 $REMOTE mad-pages && cd mad-pages; then + if git clone --depth 1 "$REMOTE" mad-pages && cd mad-pages; then for page in *.md; do echo " ... installing $page" - cp -f $page $path/$page + cp -f "$page" "$path/$page" done echo " ... complete" else @@ -139,7 +139,7 @@ install_mad() { echo echo " ... cloning repo" cd /tmp && rm -fr mad || exit 3 - git clone --depth 1 $REMOTE_MAD mad + git clone --depth 1 "$REMOTE_MAD" mad if cd mad && make install; then echo " ... updated to $(mad --version)" else @@ -154,9 +154,9 @@ install_mad() { # parse args -case $1 in +case "$1" in -v|--version) - echo $VERSION + echo "$VERSION" ;; -h|--help|help) display_mad_usage @@ -174,6 +174,6 @@ case $1 in display_from_stdin ;; *) - display $1 + display "$1" ;; esac From 1ad6769540caea064dd394ef20e4d837853a40d5 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Fri, 25 May 2012 14:10:31 -0700 Subject: [PATCH 12/12] Quotes around array expansion --- bin/mad | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/mad b/bin/mad index 7e59b82..5ca70c7 100755 --- a/bin/mad +++ b/bin/mad @@ -22,7 +22,7 @@ list_pages() { echo printf " \033[1mmad pages:\033[0m\n" echo - for path in ${path_array[@]}; do + for path in "${path_array[@]}"; do [[ -z "$path" || ! -d "$path" ]] && continue while read -r -d '' file; do file=${file##*/} # basename @@ -47,7 +47,7 @@ display() { local path_array= IFS=: read -a path_array <<< "$paths" - for path in ${path_array[@]}; do + for path in "${path_array[@]}"; do local file=$path/$page local ext=$path/$page.md [[ -f "$file" ]] && display_file "$file"