diff --git a/bin/sgit b/bin/sgit index c5ccb9f61..f6c72db25 100755 --- a/bin/sgit +++ b/bin/sgit @@ -16,22 +16,32 @@ # - Cody Boone Ferguson (@xexyl) # -export SGIT_VERSION="0.0.2-1 13-02-2023" # format: major.minor.patch-release DD-MM-YYYY +export SGIT_VERSION="0.0.4-1 15-02-2023" # format: major.minor.patch-release DD-MM-YYYY -USAGE="usage: $(basename "$0") [-h] [-V] [-v level] [-x] [-e command] +USAGE="usage: $(basename "$0") [-h] [-V] [-v level] [-x] [-I] [-o sed_options] [-s sed] [-e command] -h print help and exit -V print version and exit - -x turn on tracing (set -x) -v level set verbosity level + -x turn on tracing (set -x) + -I disable in place editing + -o sed options (don't pass '-') + -s sed set path to sed -e command append sed command to execute on globs sgit version: $SGIT_VERSION" +SED="$(type -P sed)" +export SED +export SED_OPTIONS="" +export I_FLAG= export VERBOSITY=0 + +# we need an array for sed commands +declare -a SED_COMMANDS # parse args # -while getopts :hVxv:e: flag; do +while getopts :hVv:xIo:s:e: flag; do case "$flag" in h) echo "$USAGE" 1>&2 exit 2 @@ -39,9 +49,15 @@ while getopts :hVxv:e: flag; do V) echo "$SGIT_VERSION" 1>&2 exit 2 ;; + v) VERBOSITY="$OPTARG"; + ;; x) set -x ;; - v) VERBOSITY="$OPTARG"; + I) I_FLAG="-I" + ;; + o) SED_OPTIONS="-$OPTARG" + ;; + s) SED="$OPTARG" ;; e) SED_COMMANDS+=(-e "$OPTARG") ;; @@ -67,6 +83,25 @@ if [[ -z "${SED_COMMANDS[*]}" ]]; then exit 2 fi +# check that sed is executable + +if [[ -z "$SED" ]]; then + echo "$(basename "$0"): ERROR: sed cannot be empty" 1>&2 + echo 1>&2 + echo "$USAGE" 1>&2 + exit 2 +elif [[ ! -f "$SED" ]]; then + echo "$(basename "$0"): ERROR: sed is not a regular file: $SED" 1>&2 + echo 1>&2 + echo "$USAGE" 1>&2 + exit 2 +elif [[ ! -x "$SED" ]]; then + echo "$(basename "$0"): ERROR: sed is not an executable file: $SED" 1>&2 + echo 1>&2 + echo "$USAGE" 1>&2 + exit 2 +fi + # also check number of remaining args if [[ "$#" -eq 0 ]]; then echo "$(basename "$0"): ERROR: you must specify at least one glob" 1>&2 @@ -84,14 +119,14 @@ if [[ "$status" -ne 0 ]]; then fi if [[ $VERBOSITY -gt 1 ]]; then - echo "debug[2]: sed commands: ${SED_COMMANDS}[*]" 1>&2 + echo "debug[2]: sed commands: ${SED_COMMANDS[*]}" 1>&2 fi -# This is not the best performance because it does this on all files of the glob -# rather than only those files matched by the glob with matching text but it's -# better than it used to be (it used to run git ls-files on the repo for each -# sed command so the more you had the slow it would become as it had to get the -# list of files each time!). +# This might not the best performance because it does this on all files of the +# glob rather than only those files matched by the glob with matching text but +# it's better than it used to be (it used to run git ls-files on the repo for +# each sed command so the more you had the slow it would become as it had to get +# the list of files each time!). # # A better approach would be to somehow use git grep to find files that match # but this would complicate the command line (at least in anyway I can think of @@ -110,12 +145,34 @@ while [[ "$i" -le "$#" ]]; do echo "debug[2]: found glob: $1" 1>&2 fi if [[ "$VERBOSITY" -ge 1 ]]; then - echo "debug[1]: about to run: git ls-files $1 | xargs sed -i\"\" ${SED_COMMANDS[*]}" 1>&2 + if [[ -z "$I_FLAG" ]]; then + if [[ -n "$SED_OPTIONS" ]]; then + echo "debug[1]: about to run: git ls-files $1 | xargs $SED -i\"\" $SED_OPTIONS ${SED_COMMANDS[*]}" 1>&2 + else + echo "debug[1]: about to run: git ls-files $1 | xargs $SED -i\"\" ${SED_COMMANDS[*]}" 1>&2 + fi + else + if [[ -n "$SED_OPTIONS" ]]; then + echo "debug[1]: about to run: git ls-files $1 | xargs $SED $SED_OPTIONS ${SED_COMMANDS[*]}" 1>&2 + else + echo "debug[1]: about to run: git ls-files $1 | xargs $SED ${SED_COMMANDS[*]}" 1>&2 + fi + fi + fi + + if [[ -z "$I_FLAG" ]]; then + if [[ -n "$SED_OPTIONS" ]]; then + git ls-files "$1" | xargs "$SED" -i"" "$SED_OPTIONS" "${SED_COMMANDS[*]}" + else + git ls-files "$1" | xargs "$SED" -i"" "${SED_COMMANDS[*]}" + fi + else + if [[ -n "$SED_OPTIONS" ]]; then + git ls-files "$1" | xargs "$SED" "$SED_OPTIONS" "${SED_COMMANDS[*]}" + else + git ls-files "$1" | xargs "$SED" "${SED_COMMANDS[*]}" + fi fi - # shellcheck disable=SC2086 - # SC2086 (info): Double quote to prevent globbing and word splitting. We can't - # quote this because we need to have word splitting. - git ls-files "$1" | xargs sed -i"" "${SED_COMMANDS[@]}" ((i++)) shift 1 done