Permalink
Browse files

Allow substring match, plus various cleanups

  • Loading branch information...
1 parent 2189619 commit 71cec16a65e47ee6dc739b00a7777206ef082058 @ttencate committed Jan 12, 2013
View
@@ -6,24 +6,33 @@ if [[ -t 1 ]]; then
else
DEFAULT_COMMAND=echo
fi
+DEFAULT_PROGRESS_FILE=.playnextrc
function print_usage() {
# 12345678901234567890123456789012345678901234567890123456789012345678901234567890
- echo "Usage: $SCRIPT_NAME [OPTION]... [DIR]"
+ echo "Usage: $SCRIPT_NAME [OPTION]... DIR"
echo
- echo "Plays the next episode in the given directory. If no directory is given, uses"
- echo "the current directory."
+ echo "Plays the next episode in the given directory."
+ echo
+ echo "If you previously played something from a particular directory, you can"
+ echo "supply any unique substring of that directory as the DIR argument, e.g.:"
+ echo
+ echo " $SCRIPT_NAME \"$HOME/My Wonderful Podcast\""
+ echo " $SCRIPT_NAME Wonder"
echo
echo "If not connected to a terminal, prints the filename instead of playing it."
echo "This allows you to do things like:"
echo
- echo " cp "\`playnext\`" /mnt/ipod"
+ echo " cp \"\`$SCRIPT_NAME\`\" /mnt/ipod"
+ echo
+ echo "History is tracked in the 'progress file' which is a plain text file listing one"
+ echo "absolute path name per line for each previously played episode."
echo
echo "Options:"
- echo " -c, --command=command command to use to play file echo (default: "
- echo " mplayer if connected to a tty, echo otherwise)"
- echo " -e, --episode=filename output given episode and remember this"
- echo " -f, --progress-file=filename configuration file name (default: ~/.playnextrc)"
+ echo " -c, --command=command command to use to play file (default: mplayer"
+ echo " if connected to a tty, echo otherwise)"
+ echo " -e, --episode=filename play given episode and remember this"
+ echo " -f, --progress-file=filename progress file name (default: ~/$DEFAULT_PROGRESS_FILE)"
echo " -h, --help show this help"
echo " -l, --list print the list of last episodes played"
echo " -n, --next skip episode (can be repeated)"
@@ -51,6 +60,31 @@ function read_progress_file() {
IFS=$'\n' progress=( $(< "$progress_file") )
}
+function find_media_dir() {
+ local matches=( )
+ for episode in "${progress[@]}"; do
+ if [[ $episode == *$media_dir* ]]; then
+ matches+=( $episode )
+ fi
+ done
+
+ if (( ${#matches[@]} == 0 )); then
+ exit_error "$media_dir is neither an existing directory nor a substring of a previously used directory"
+ fi
+ if (( ${#matches[@]} > 1 )); then
+ local message="'$media_dir' is not unique; did you mean any of the following?"
+ for match in "${matches[@]}"; do message="$message"$'\n'" $match"; done
+ exit_error "$message"
+ fi
+
+ local new_media_dir="${matches[0]}"
+ while [[ ${new_media_dir%/*} == *$media_dir* ]]; do
+ new_media_dir="${new_media_dir%/*}"
+ done
+
+ media_dir="$new_media_dir"
+}
+
function find_previous_episode() {
for episode in "${progress[@]}"; do
if [[ $episode == $media_dir* ]]; then
@@ -176,8 +210,7 @@ while (( $# > 0 )); do
shift
done
-progress_file=${progress_file-$HOME/.playnextrc}
-media_dir=${media_dir-.}
+progress_file=${progress_file-$HOME/$DEFAULT_PROGRESS_FILE}
command=${command-$DEFAULT_COMMAND}
offset=$(( offset + 1 ))
@@ -191,10 +224,24 @@ if (( list )); then
exit 0
fi
+[[ -z $media_dir ]] && usage_error "No directory given"
+
+if [[ -d $media_dir ]]; then
+ print_verbose "Media directory found"
+elif [[ -f $media_dir ]]; then
+ print_verbose "Media directory $media_dir is a file; treating as current episode"
+ current_episode="$(readlink -f "$media_dir")"
+ media_dir="$(dirname "$current_episode")"
+else
+ print_verbose "Media directory does not exist; trying substring match"
+ find_media_dir
+fi
media_dir="$(readlink -f "$media_dir")"
print_verbose "Using directory $media_dir"
+cd "$media_dir"
current_episode="$(readlink -f "$current_episode")"
+print_verbose "Canonical current episode is $current_episode"
if [[ ! -z $current_episode ]]; then
if [[ $current_episode != $media_dir* ]]; then
exit_error "The given file $current_episode does not reside in $media_dir"
View
130 test.sh
@@ -3,18 +3,27 @@
playnext=$(dirname $(readlink -f $0))/playnext
function fail() {
- echo "FAIL: $@"
- echo "Last command: $last_command"
+ echo "$@"
echo "Backtrace:"
i=0
while caller $(( i++ )); do true; done
exit 1
}
function playnext() {
- args="-f $progress_file"
- last_command="$playnext $args $@"
- $playnext $args "$@"
+ (
+ echo "Running command:"
+ echo -n "$playnext -f $progress_file -v"
+ for arg in "$@"; do
+ if [[ $arg =~ "^[a-zA-Z0-9]*$" ]]; then
+ echo -n " $arg"
+ else
+ echo -n " '$arg'"
+ fi
+ done
+ echo
+ ) >&2
+ $playnext -f $progress_file "$@"
}
function assert_output() {
@@ -23,11 +32,9 @@ function assert_output() {
local actual="$(playnext "$@")"
if (( $? )); then
fail "Nonzero exit code"
- exit 1
fi
if [[ $expected != $actual ]]; then
- fail "Expected: $expected, actual: $actual"
- exit 1
+ fail "Expected: $expected"$'\n'"Actual: $actual"
fi
}
@@ -38,81 +45,71 @@ function assert_fail() {
}
function set_up_fixture() {
- media_dir_1=$(mktemp -d)
- cd $media_dir_1
- mkdir "Dir 1"
- touch "Dir 1/File 1"
- touch "Dir 1/file 2"
- touch "Dir 1/File 3"
- mkdir "Dir 2"
- mkdir "Dir 3"
- touch "Dir 3/File 1"
- touch ".dotfile"
- mkdir ".dotdir"
- touch ".dotdir/file"
-
- media_dir_2=$(mktemp -d)
- cd $media_dir_2
- mkdir "Dir 4"
- touch "Dir 4/File 1"
- touch "File 2"
-
- media_dir_3=$(mktemp -d)
-
- progress_file=$(mktemp)
+ cd "$(dirname $0)/testdata"
+ media_dir_1=$(readlink -f t1)
+ media_dir_2=$(readlink -f t2)
+ media_dir_3=$(readlink -f t3)
}
function tear_down_fixture() {
- rm -r "$media_dir_1" "$media_dir_2" "$media_dir_3"
+ true
}
function set_up() {
- cd ${TMPDIR-/tmp}
+ progress_file=$(mktemp)
}
function tear_down() {
rm -f $progress_file
}
function test_with_empty_dir() {
- cd $media_dir_3
- assert_fail "Did not fail with empty dir"
+ assert_fail "Did not fail with empty dir" $media_dir_3
}
function test_with_some_files() {
- cd $media_dir_1
- assert_output "$media_dir_1/Dir 1/File 1"
- assert_output "$media_dir_1/Dir 1/file 2"
- assert_output "$media_dir_1/Dir 1/File 3"
- assert_output "$media_dir_1/Dir 3/File 1"
+ assert_output "$media_dir_1/Dir 1/File 1" $media_dir_1
+ assert_output "$media_dir_1/Dir 1/file 2" $media_dir_1
+ assert_output "$media_dir_1/Dir 1/File 3" $media_dir_1
+ assert_output "$media_dir_1/Dir 3/File 1" $media_dir_1
assert_fail "Did not run out of files"
}
function test_multiple_episodes_in_progress() {
- cd $media_dir_1
- playnext "Dir 1" -e "Dir 1/File 1" > /dev/null
- playnext "Dir 3" -e "Dir 3/File 1" > /dev/null
+ playnext "$media_dir_1/Dir 1" -e "Dir 1/File 1" > /dev/null
+ playnext "$media_dir_1/Dir 3" -e "Dir 3/File 1" > /dev/null
assert_fail "Did not warn about multiple episodes in progress"
}
function test_multiple_media_dirs() {
- cd $media_dir_1
- playnext > /dev/null
- cd $media_dir_2
- playnext > /dev/null
+ playnext $media_dir_1 > /dev/null
+ playnext $media_dir_2 > /dev/null
assert_output "$(echo -e "$media_dir_1/Dir 1/File 1\n$media_dir_2/Dir 4/File 1")" -l
}
function test_directory_argument() {
assert_output "$media_dir_1/Dir 1/File 1" $media_dir_1
+ assert_fail "Did not fail without directory argument"
assert_fail "Did not fail with multiple directories" $media_dir_1 $media_dir_2
}
-function test_episode_option() {
+function test_directory_substring() {
+ playnext $media_dir_1 > /dev/null
+ playnext $media_dir_2 > /dev/null
+ assert_output "$media_dir_1/Dir 1/file 2" "r 1"
+ assert_fail "Did not complain about multiple substring matches" 1
+}
+
+function test_filename_argument() {
cd $media_dir_1
- assert_output "$media_dir_1/Dir 1/file 2" -e "Dir 1/file 2"
- assert_output "$media_dir_1/Dir 1/File 3"
- assert_fail "Invalid file for -e was accepted" -e /dev/null
+ assert_output "$media_dir_1/Dir 1/file 2" "Dir 1/file 2"
+ assert_output "$media_dir_1/Dir 1/File 3" $media_dir_1
+}
+
+function test_episode_option() {
+ assert_output "$media_dir_1/Dir 1/file 2" $media_dir_1 -e "Dir 1/file 2"
+ assert_output "$media_dir_1/Dir 1/File 3" $media_dir_1
+ assert_fail "Invalid file for -e was accepted" $media_dir_1 -e /dev/null
}
function test_help_option() {
@@ -127,31 +124,38 @@ function test_list_option() {
}
function test_next_option() {
- cd $media_dir_1
- assert_output "$media_dir_1/Dir 1/file 2" -n
- assert_output "$media_dir_1/Dir 3/File 1" -n
+ assert_output "$media_dir_1/Dir 1/file 2" $media_dir_1 -n
+ assert_output "$media_dir_1/Dir 3/File 1" $media_dir_1 -n
}
function test_previous_option() {
- cd $media_dir_1
- playnext > /dev/null
- assert_output "$media_dir_1/Dir 1/File 1" -p
- assert_output "$media_dir_1/Dir 1/file 2"
- assert_output "$media_dir_1/Dir 1/File 1" -p -p
+ playnext $media_dir_1 > /dev/null
+ assert_output "$media_dir_1/Dir 1/File 1" $media_dir_1 -p
+ assert_output "$media_dir_1/Dir 1/file 2" $media_dir_1
+ assert_output "$media_dir_1/Dir 1/File 1" $media_dir_1 -p -p
}
function test_command_option() {
- cd $media_dir_1
- assert_output "" -c cat
- assert_output "$media_dir_1/Dir 1/file 2" -c echo
+ assert_output "" $media_dir_1 -c cat
+ assert_output "$media_dir_1/Dir 1/file 2" $media_dir_1 -c echo
}
+pass_count=0
+fail_count=0
set_up_fixture
trap tear_down_fixture EXIT
while read function; do
[[ ! $function = test* ]] && continue
set_up
- $function
+ output=$($function 2>&1)
+ if (( $? )); then
+ echo "FAIL: $function"
+ echo "$output"
+ (( fail_count++ ))
+ else
+ echo "PASS: $function"
+ (( pass_count++ ))
+ fi
tear_down
- echo "PASS: $function"
done < <(declare -F | cut -d' ' -f3)
+echo "$pass_count passes, $fail_count failures"
View
No changes.
View
No changes.
View
No changes.
View
No changes.
View
No changes.
View
No changes.
View
No changes.
View
No changes.

0 comments on commit 71cec16

Please sign in to comment.