Allow for placing addons in subfolders.

Addons can be placed in subfolders with the same name as the action,
in order to be able to e.g. clone git repos into the TODO_ACTIONS_DIR
rather than having to download addons and manage updates manually.

Closes #120
This commit is contained in:
nthorne
2013-11-22 23:20:55 +01:00
committed by Gina Trapani
parent 07b50a07e0
commit 7c92f46c25
4 changed files with 96 additions and 4 deletions

View File

@@ -16,3 +16,21 @@ echo "custom action $1"
EOF EOF
chmod +x ".todo.actions.d/$1" chmod +x ".todo.actions.d/$1"
} }
make_action_in_folder()
{
unset TODO_ACTIONS_DIR
[ -d .todo.actions.d ] || mkdir .todo.actions.d
mkdir .todo.actions.d/$1
cat > ".todo.actions.d/$1/$1" <<EOF
#!/bin/bash
[ "\$1" = "usage" ] && {
echo " $1 ITEM#[, ITEM#, ...] [TERM...]"
echo " This custom action does $1."
echo ""
exit
}
echo "custom action $1 in folder $1"
EOF
chmod +x ".todo.actions.d/$1/$1"
}

View File

@@ -11,6 +11,8 @@ readonly ACTIONS='add a addto addm append app archive command del rm depri dp do
readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x' readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x'
readonly ADDONS='bar baz foobar' readonly ADDONS='bar baz foobar'
readonly CONTAINED='xeno zoolander'
makeCustomActions() makeCustomActions()
{ {
set -e set -e
@@ -31,12 +33,28 @@ makeCustomActions()
chmod -x "$datafile" chmod -x "$datafile"
[ -x "$datafile" ] && rm "$datafile" # Some file systems may always make files executable; then, skip this check. [ -x "$datafile" ] && rm "$datafile" # Some file systems may always make files executable; then, skip this check.
# Add an executable file in a folder with the same name as the file,
# in order to ensure completion
for contained in $CONTAINED
do
mkdir "${1}/$contained"
> "${1}/$contained/$contained"
chmod u+x "${1}/$contained/$contained"
done
set +e set +e
} }
removeCustomActions() removeCustomActions()
{ {
set -e set -e
rmdir "${1}/subdir" rmdir "${1}/subdir"
for contained in $CONTAINED
do
rm "${1}/$contained/$contained"
rmdir "${1}/$contained"
done
rm "${1:?}/"* rm "${1:?}/"*
rmdir "$1" rmdir "$1"
set +e set +e
@@ -46,8 +64,8 @@ removeCustomActions()
# Test resolution of the default TODO_ACTIONS_DIR. # Test resolution of the default TODO_ACTIONS_DIR.
# #
makeCustomActions "$HOME/.todo.actions.d" makeCustomActions "$HOME/.todo.actions.d"
test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS" test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
test_todo_completion 'all arguments after option' 'todo.sh -a ' "$ACTIONS $ADDONS $OPTIONS" test_todo_completion 'all arguments after option' 'todo.sh -a ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
test_todo_completion 'all arguments beginning with b' 'todo.sh b' 'bar baz' test_todo_completion 'all arguments beginning with b' 'todo.sh b' 'bar baz'
test_todo_completion 'all arguments beginning with f after options' 'todo.sh -a -v f' 'foobar' test_todo_completion 'all arguments beginning with f after options' 'todo.sh -a -v f' 'foobar'
test_todo_completion 'nothing after addon action' 'todo.sh foobar ' '' test_todo_completion 'nothing after addon action' 'todo.sh foobar ' ''
@@ -58,7 +76,7 @@ removeCustomActions "$HOME/.todo.actions.d"
# #
mkdir "$HOME/.todo" mkdir "$HOME/.todo"
makeCustomActions "$HOME/.todo/actions" makeCustomActions "$HOME/.todo/actions"
test_todo_completion 'all arguments with actions from .todo/actions/' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS" test_todo_completion 'all arguments with actions from .todo/actions/' 'todo.sh ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
removeCustomActions "$HOME/.todo/actions" removeCustomActions "$HOME/.todo/actions"
# #
@@ -68,7 +86,7 @@ makeCustomActions "$HOME/addons"
cat >> todo.cfg <<'EOF' cat >> todo.cfg <<'EOF'
export TODO_ACTIONS_DIR="$HOME/addons" export TODO_ACTIONS_DIR="$HOME/addons"
EOF EOF
test_todo_completion 'all arguments with actions from addons/' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS" test_todo_completion 'all arguments with actions from addons/' 'todo.sh ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
removeCustomActions "$HOME/addons" removeCustomActions "$HOME/addons"
test_done test_done

View File

@@ -41,4 +41,44 @@ ls
quux quux
EOF EOF
make_action_in_folder "chuck"
# Add a bit of cruft in the action folders in order to ensure that we only
# care about the executables with the same name as the folder in which they
# reside.
touch .todo.actions.d/chuck/mc_hammer # can't touch this
chmod u+x .todo.actions.d/chuck/mc_hammer # better run, better run run
touch .todo.actions.d/chuck/README
make_action_in_folder "norris"
test_todo_session 'custom actions in subfolders' <<EOF
>>> test -f .todo.actions.d/chuck/README
=== 0
>>> test -x .todo.actions.d/chuck/mc_hammer
=== 0
>>> todo.sh listaddons
bar
chuck
ls
norris
quux
EOF
# nthorne: shamelessly stolen from above..
chmod -x .todo.actions.d/norris/norris
# On Cygwin, clearing the executable flag may have no effect, as the Windows ACL
# may still grant execution rights. In this case, we skip the test.
if [ -x .todo.actions.d/norris/norris ]; then
SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.8"
fi
test_todo_session 'nonexecutable action in subfolder' <<EOF
>>> todo.sh listaddons
bar
chuck
ls
quux
EOF
test_done test_done

16
todo.sh
View File

@@ -302,6 +302,14 @@ addonHelp()
didPrintAddonActionsHeader=1 didPrintAddonActionsHeader=1
fi fi
"$action" usage "$action" usage
elif [ -d "$action" -a -x "$action/$(basename $action)" ]; then
if [ ! "$didPrintAddonActionsHeader" ]; then
cat <<-EndAddonActionsHeader
Add-on Actions:
EndAddonActionsHeader
didPrintAddonActionsHeader=1
fi
"$action/$(basename $action)" usage
fi fi
done done
fi fi
@@ -314,6 +322,8 @@ actionUsage()
action="${TODO_ACTIONS_DIR}/${actionName}" action="${TODO_ACTIONS_DIR}/${actionName}"
if [ -f "$action" -a -x "$action" ]; then if [ -f "$action" -a -x "$action" ]; then
"$action" usage "$action" usage
elif [ -d "$action" -a -x "$action/$(basename $action)" ]; then
"$action/$(basename $action)" usage
else else
builtinActionUsage=$(actionsHelp | sed -n -e "/^ ${actionName//\//\\/} /,/^\$/p" -e "/^ ${actionName//\//\\/}$/,/^\$/p") builtinActionUsage=$(actionsHelp | sed -n -e "/^ ${actionName//\//\\/} /,/^\$/p" -e "/^ ${actionName//\//\\/}$/,/^\$/p")
if [ "$builtinActionUsage" ]; then if [ "$builtinActionUsage" ]; then
@@ -964,6 +974,10 @@ then
shift shift
## Reset action to new first argument ## Reset action to new first argument
action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' )
elif [ -d "$TODO_ACTIONS_DIR/$action" -a -x "$TODO_ACTIONS_DIR/$action/$action" ]
then
"$TODO_ACTIONS_DIR/$action/$action" "$@"
exit $?
elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ] elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ]
then then
"$TODO_ACTIONS_DIR/$action" "$@" "$TODO_ACTIONS_DIR/$action" "$@"
@@ -1405,6 +1419,8 @@ note: PRIORITY must be anywhere from A to Z."
do do
if [ -f "$action" -a -x "$action" ]; then if [ -f "$action" -a -x "$action" ]; then
echo "$action" echo "$action"
elif [ -d "$action" -a -x "$action/$action" ]; then
echo "$action"
fi fi
done done
fi fi