Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ci] set current default branch #333

Merged
merged 13 commits into from
Feb 27, 2024
25 changes: 16 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Test
on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master

jobs:
test:
Expand All @@ -22,12 +22,19 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Test
uses: sudo-bot/action-shunit2@latest
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v25
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
nix_path: nixpkgs=channel:nixos-unstable
- run: |
git config --global init.defaultBranch master
git config --global user.name scm_breeze@scm_breeze
git config --global user.email "SCM Breeze"
- name: test
env:
TEST_SHELLS: ${{ matrix.test_shell }}
with:
cli: ./run_tests.sh
run: nix-shell -p ruby $TEST_SHELLS --command ./run_tests.sh
# - run: nix-shell -p shunit2 -i ./run_tests.sh
# - run: nix build
# - run: nix flake check
71 changes: 38 additions & 33 deletions lib/git/shell_shortcuts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# Released under the LGPL (GNU Lesser General Public License)
# ------------------------------------------------------------------------------


if sed -E 's///g' </dev/null &>/dev/null; then
SED_REGEX_ARG="E"
elif sed -r 's///g' </dev/null &>/dev/null; then
Expand All @@ -13,22 +12,21 @@ else
echo "Cannot determine extended regex argument for sed! (Doesn't respond to either -E or -r)"
fi


# Wrap common commands with numeric argument expansion.
# Prepends everything with exec_scmb_expand_args,
# even if commands are already aliases or functions
if [ "$shell_command_wrapping_enabled" = "true" ] || [ "$bash_command_wrapping_enabled" = "true" ]; then
# Do it in a function so we don't bleed variables
function _git_wrap_commands() {
# Define 'whence' for bash, to get the value of an alias
type whence > /dev/null 2>&1 || function whence() { LC_MESSAGES="C" type "$@" | sed -$SED_REGEX_ARG -e "s/.*is aliased to \`//" -e "s/'$//"; }
type whence >/dev/null 2>&1 || function whence() { LC_MESSAGES="C" type "$@" | sed -$SED_REGEX_ARG -e "s/.*is aliased to \`//" -e "s/'$//"; }
local cmd=''
for cmd in $scmb_wrapped_shell_commands; do
for cmd in "${scmb_wrapped_shell_commands[@]}"; do
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: Wrapping $cmd..."; fi

# Special check for 'cd', to make sure SCM Breeze is loaded after RVM
if [ "$cmd" = 'cd' ]; then
if [ -e "$HOME/.rvm" ] && ! type rvm > /dev/null 2>&1; then
if [ -e "$HOME/.rvm" ] && ! type rvm >/dev/null 2>&1; then
echo -e "\\033[0;31mSCM Breeze must be loaded \\033[1;31mafter\\033[0;31m RVM, otherwise there will be a conflict when RVM wraps the 'cd' command.\\033[0m"
echo -e "\\033[0;31mPlease move the line that loads SCM Breeze to the bottom of your ~/.bashrc\\033[0m"
continue
Expand All @@ -39,12 +37,14 @@ if [ "$shell_command_wrapping_enabled" = "true" ] || [ "$bash_command_wrapping_e

# Don't do anything if command already aliased, or not found.
*'exec_scmb_expand_args'*)
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd is already wrapped"; fi;;
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd is already wrapped"; fi
;;

*'not found'*)
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd not found!"; fi;;
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd not found!"; fi
;;

*'aliased to'*|*'is an alias for'*)
*'aliased to'* | *'is an alias for'*)
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd is an alias"; fi
# Store original alias
local original_alias="$(whence $cmd)"
Expand All @@ -53,16 +53,17 @@ if [ "$shell_command_wrapping_enabled" = "true" ] || [ "$bash_command_wrapping_e

# Detect original $cmd type, and escape
case "$(LC_MESSAGES="C" type "$cmd" 2>&1)" in
# Escape shell builtins with 'builtin'
*'is a shell builtin'*) local escaped_cmd="builtin $cmd";;
# Get full path for files with 'find_binary' function
*) local escaped_cmd="$(find_binary $cmd)";;
# Escape shell builtins with 'builtin'
*'is a shell builtin'*) local escaped_cmd="builtin $cmd" ;;
# Get full path for files with 'find_binary' function
*) local escaped_cmd="$(find_binary $cmd)" ;;
esac

# Expand original command into full path, to avoid infinite loops
local expanded_alias="$(echo $original_alias | sed -$SED_REGEX_ARG "s%(^| )$cmd($| )%\\1$escaped_cmd\\2%")"
# Wrap previous alias with escaped command
alias $cmd="exec_scmb_expand_args $expanded_alias";;
alias $cmd="exec_scmb_expand_args $expanded_alias"
;;

*'is a'*'function'*)
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd is a function"; fi
Expand All @@ -71,30 +72,32 @@ if [ "$shell_command_wrapping_enabled" = "true" ] || [ "$bash_command_wrapping_e
# Remove function
unset -f "$cmd"
# Create function that wraps old function
eval "${cmd}(){ exec_scmb_expand_args __original_${cmd} \"\$@\"; }";;
eval "${cmd}(){ exec_scmb_expand_args __original_${cmd} \"\$@\"; }"
;;

*'is a shell builtin'*)
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd is a shell builtin"; fi
# Handle shell builtin commands
alias $cmd="exec_scmb_expand_args builtin $cmd";;
alias $cmd="exec_scmb_expand_args builtin $cmd"
;;

*)
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: $cmd is an executable file"; fi
# Otherwise, command is a regular script or binary,
# and the full path can be found with 'find_binary' function
alias $cmd="exec_scmb_expand_args '$(find_binary $cmd)'";;
alias $cmd="exec_scmb_expand_args '$(find_binary $cmd)'"
;;
esac
done
# Clean up
declare -f whence > /dev/null && unset -f whence
declare -f whence >/dev/null && unset -f whence
}
_git_wrap_commands
fi


# Function wrapper around 'll'
# Adds numbered shortcuts to output of ls -l, just like 'git status'
if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby > /dev/null 2>&1; then
if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby >/dev/null 2>&1; then
# BSD ls is different to Linux (GNU) ls
# Test for BSD ls
if ! (ls --version 2>/dev/null || echo "BSD") | grep GNU >/dev/null 2>&1; then
Expand All @@ -103,18 +106,19 @@ if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby > /dev/nu
fi

# Test if readlink supports -f option, test for greadlink on Mac, then fallback to perl
if \readlink -f / > /dev/null 2>&1; then
if \readlink -f / >/dev/null 2>&1; then
_abs_path_command=(readlink -f)
elif greadlink -f / > /dev/null 2>&1; then
elif greadlink -f / >/dev/null 2>&1; then
_abs_path_command=(greadlink -f)
else
_abs_path_command=(perl -e 'use Cwd abs_path; print abs_path(shift)')
fi

unalias ll > /dev/null 2>&1; unset -f ll > /dev/null 2>&1
unalias ll >/dev/null 2>&1
unset -f ll >/dev/null 2>&1
function ls_with_file_shortcuts {
local ll_output
local ll_command # Ensure sort ordering of the two invocations is the same
local ll_command # Ensure sort ordering of the two invocations is the same
if [ "$_ls_bsd" != "BSD" ]; then
ll_command=(\ls -hv --group-directories-first)
ll_output="$("${ll_command[@]}" -l --color "$@")"
Expand All @@ -139,11 +143,11 @@ if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby > /dev/nu
if [[ -z $rel_path ]]; then # We are seeing our first pathname
if [[ -d $arg ]]; then # It's a directory
rel_path=$arg
else # It's a file, expand the current directory
else # It's a file, expand the current directory
rel_path=.
fi
elif [[ -d $arg || ( -f $arg && $rel_path != . ) ]]; then
if [[ -f $arg ]]; then arg=$PWD; fi # Get directory for current argument
elif [[ -d $arg || (-f $arg && $rel_path != .) ]]; then
if [[ -f $arg ]]; then arg=$PWD; fi # Get directory for current argument
# We've already seen a different directory. Quit to avoid damage (issue #274)
printf 'scm_breeze: Cannot list relative to both directories:\n %s\n %s\n' "$arg" "$rel_path" >&2
printf 'Currently only listing a single directory is supported. See issue #274.\n' >&2
Expand All @@ -159,7 +163,7 @@ if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby > /dev/nu
if [ -e "$HOME"/.user_sym ]; then
# Little bit of ruby golf to rejustify the user/group/size columns after replacement
# TODO(ghthor): Convert this to a cat <<EOF to improve readibility
function rejustify_ls_columns(){
function rejustify_ls_columns() {
ruby -e "o=STDIN.read;re=/^(([^ ]* +){2})(([^ ]* +){3})/;\
u,g,s=o.lines.map{|l|l[re,3]}.compact.map(&:split).transpose.map{|a|a.map(&:size).max+1};\
puts o.lines.map{|l|l.sub(re){|m|\"%s%-#{u}s %-#{g}s%#{s}s \"%[\$1,*\$3.split]}}"
Expand All @@ -168,12 +172,12 @@ if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby > /dev/nu
local USER_SYM=$(/bin/cat $HOME/.user_sym)
if [ -f "$HOME/.staff_sym" ]; then
local STAFF_SYM=$(/bin/cat $HOME/.staff_sym)
ll_output=$(echo "$ll_output" | \
\sed -$SED_REGEX_ARG "s/ $USER staff/ $USER_SYM $STAFF_SYM /g" | \
ll_output=$(echo "$ll_output" |
\sed -$SED_REGEX_ARG "s/ $USER staff/ $USER_SYM $STAFF_SYM /g" |
rejustify_ls_columns)
else
ll_output=$(echo "$ll_output" | \
\sed -$SED_REGEX_ARG "s/ $USER/ $USER_SYM /g" | \
ll_output=$(echo "$ll_output" |
\sed -$SED_REGEX_ARG "s/ $USER/ $USER_SYM /g" |
rejustify_ls_columns)
fi
fi
Expand All @@ -186,7 +190,8 @@ if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby > /dev/nu
fi

# Use ruby to inject numbers into ls output
echo "$ll_output" | ruby -e "$( \cat <<EOF
echo "$ll_output" | ruby -e "$(
\cat <<EOF
output = STDIN.read
e = 1
re = /^(([^ ]* +){8})/
Expand All @@ -196,7 +201,7 @@ output.lines.each do |line|
e += 1
end
EOF
)"
)"

# Set numbered file shortcut in variable
local e=1
Expand Down
5 changes: 4 additions & 1 deletion run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@

failed=false

env | grep ^SHELL

# allow list of shells to run tests in to be overriden by environment variable
# if empty or null, use defaults
if [ -z "$TEST_SHELLS" ]; then
TEST_SHELLS="bash zsh"
fi
echo "== Will run all tests with following shells: ${TEST_SHELLS}"

cd -P -- "${0%/*}" # Change to directory this script lives in
cd -P -- "${0%/*}" # Change to directory this script lives in
for test in $(find test/lib -name *_test.sh); do
for shell in $TEST_SHELLS; do
echo "== Running tests with [$shell]: $test"
$shell $test || failed=true
printf '==\n\n'
done
done

Expand Down
53 changes: 33 additions & 20 deletions test/lib/git/shell_shortcuts_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
#
# Unit tests for shell command wrapping

export scmbDir="$( cd -P "$( dirname "$0" )" && pwd )/../../.."
export scmbDir="$(cd -P "$(dirname "$0")" && pwd)/../../.."

# Zsh compatibility
if [ -n "${ZSH_VERSION:-}" ]; then
shell="zsh"; SHUNIT_PARENT=$0; setopt shwordsplit
shell="zsh"
SHUNIT_PARENT=$0
setopt shwordsplit
else
# Bash needs this option so that 'alias' works in a non-interactive shell
shopt -s expand_aliases
Expand All @@ -25,7 +27,7 @@ source "$scmbDir/lib/scm_breeze.sh"
#-----------------------------------------------------------------------------
oneTimeSetUp() {
export shell_command_wrapping_enabled="true"
export scmb_wrapped_shell_commands="not_found cat rm cp mv ln cd sed"
export scmb_wrapped_shell_commands=("not_found" "cat" "rm" "cp" "mv" "ln" "cd" "sed")
export shell_ls_aliases_enabled="true"

alias rvm="test" # Ensure tests run if RVM isn't loaded but $HOME/.rvm is present
Expand All @@ -47,42 +49,47 @@ oneTimeSetUp() {
# Test already wrapped commands
alias cat="exec_scmb_expand_args $cat_path"

root_test_dir=/aaa
if [ "$(uname)" = "Darwin" ]; then
root_test_dir=/Applications
else
sudo mkdir $root_test_dir
fi

# Run shortcut wrapping
source "$scmbDir/lib/git/shell_shortcuts.sh"

# Define 'whence' function for Bash.
# Must come after sourcing shell_shortcuts
type whence > /dev/null 2>&1 || function whence() { type "$@" | sed -e "s/.*is aliased to \`//" -e "s/'$//"; }
type whence >/dev/null 2>&1 || function whence() { type "$@" | sed -e "s/.*is aliased to \`//" -e "s/'$//"; }
}

# Helper function to test that alias is defined properly.
# (Works for both zsh and bash)
assertAliasEquals(){
assertAliasEquals() {
assertEquals "$1" "$(whence $2)"
}


#-----------------------------------------------------------------------------
# Setup and tear down
#-----------------------------------------------------------------------------

setUp() {
unset QUOTING_STYLE # Use default quoting style for ls
unset QUOTING_STYLE # Use default quoting style for ls
}


#-----------------------------------------------------------------------------
# Unit tests
#-----------------------------------------------------------------------------

test_shell_command_wrapping() {
assertAliasEquals "exec_scmb_expand_args nocorrect $mv_path" "mv"
assertAliasEquals "exec_scmb_expand_args $rm_path --option" "rm"
assertAliasEquals "exec_scmb_expand_args $sed_path" "sed"
assertAliasEquals "exec_scmb_expand_args $cat_path" "cat"
assertAliasEquals "exec_scmb_expand_args builtin cd" "cd"
assertIncludes "$(declare -f ln)" "ln ()"
assertIncludes "$(declare -f ln)" "exec_scmb_expand_args __original_ln"
assertAliasEquals "exec_scmb_expand_args $rm_path --option" "rm"
assertAliasEquals "exec_scmb_expand_args $sed_path" "sed"
assertAliasEquals "exec_scmb_expand_args $cat_path" "cat"
assertAliasEquals "exec_scmb_expand_args builtin cd" "cd"
assertIncludes "$(declare -f ln)" "ln ()"
assertIncludes "$(declare -f ln)" "exec_scmb_expand_args __original_ln"
}

test_ls_with_file_shortcuts() {
Expand All @@ -105,7 +112,7 @@ test_ls_with_file_shortcuts() {
# Run command in shell, load output from temp file into variable
# (This is needed so that env variables are exported in the current shell)
temp_file=$(mktemp -t scm_breeze.XXXXXXXXXX)
ls_with_file_shortcuts > "$temp_file"
ls_with_file_shortcuts >"$temp_file"
ls_output=$(<"$temp_file" strip_colors)

# Compare as fixed strings (F), instead of normal grep behavior
Expand All @@ -116,14 +123,14 @@ test_ls_with_file_shortcuts() {
assertIncludes "$ls_output" '[5] test_file' F

# Test filenames with single or double quotes escaped
assertEquals "$TEST_DIR/"'a "b"' "$e1"
assertEquals "$TEST_DIR/a 'b'" "$e2"
assertEquals "$TEST_DIR/a [b]" "$e3"
assertEquals "$TEST_DIR/"'a "b"' "$e1"
assertEquals "$TEST_DIR/a 'b'" "$e2"
assertEquals "$TEST_DIR/a [b]" "$e3"
assertEquals "$TEST_DIR/test file" "$e4"
assertEquals "$TEST_DIR/test_file" "$e5"

# Test ls with subdirectory
ls_with_file_shortcuts 'a "b"' > $temp_file
ls_with_file_shortcuts 'a "b"' >$temp_file
ls_output=$(<$temp_file strip_colors)
assertIncludes "$ls_output" '[1] c' F
# Test that env variable is set correctly
Expand All @@ -141,10 +148,16 @@ test_ls_with_file_shortcuts() {
assertFalse 'Fails on <directory> <directory>/<file>' 'ls_with_file_shortcuts 1 1/file'

# Files under the root directory
assertTrue 'Shortcuts under /' 'ls_with_file_shortcuts / > /dev/null && [[ $e1 =~ ^/[^/]+$ ]]'
assertTrue 'Shortcuts under /' 'ls_with_file_shortcuts / >/dev/null && [[ $e1 =~ ^/[^/]+$ ]]'

ls_with_file_shortcuts / >/dev/null
assertTrue "$e1 == $root_test_dir" '[[ "$e1" == "$root_test_dir" ]]'

cd -
rm -r "$TEST_DIR" "$temp_file"
if [ "$(uname)" != "Darwin" ]; then
sudo rmdir "$root_test_dir"
fi
}

# load and run shUnit2
Expand Down
Loading