Reorganize internal functions

This commit is contained in:
2013-10-03 22:59:38 +01:00
parent ffdfc5f889
commit 4efde780d4
11 changed files with 188 additions and 146 deletions

View File

@@ -37,8 +37,11 @@ source "../lib/trim.sh"
# Internal functions
#
source "../lib/parse-dotfile-options.sh"
source "../lib/internals.sh"
source "../lib/internals/compile-dotfile.sh"
source "../lib/internals/create-symlink.sh"
source "../lib/internals/locate-dotfile.sh"
source "../lib/internals/locate-target.sh"
source "../lib/internals/parse-dotfile-options.sh"
#
# Command functions

View File

@@ -1,93 +0,0 @@
locate-dotfile() {
if [ -n "$DOTFILE" ]; then
if [ ! -f "$DOTFILE" ]; then
echo "ERROR: \"$DOTFILE\" does not exist." >&2
return 1
fi
elif [ -f "$(pwd)/Dotfile" ]; then
DOTFILE="$(pwd)/Dotfile"
else
echo "ERROR: \"$(pwd)\" does not have a Dotfile." >&2
return 1
fi
}
locate-target() {
if [ -n "$TARGET" ]; then
if [ ! -d "$TARGET" ]; then
echo "ERROR: Target \"$TARGET\" is not a directory." >&2
return 1
fi
elif [ -n "$HOME" ] && [ -d "$HOME" ]; then
TARGET="$HOME"
elif [ -d ~ ]; then
TARGET=~
else
echo "ERROR: Your \$HOME folder could not be found." >&2
return 1
fi
}
create-symlink() {
local source="$1"
local target="$2"
}
execute-dotfile() {
parse-dotfile-options
local root_dir="$(dirname "$DOTFILE")"
local cwd="$(pwd)"
cd "$root_dir"
create-symlink "$root_dir" "$TARGET/$OPT_ROOT_LINK"
if [ -n "$?" ]; then return 1; fi
while read line; do
parse-dotfile-line "$line"
if [ -n "$?" ]; then return 1; fi
done < "$DOTFILE"
cd "$cwd"
}
parse-dotfile-line() {
local line="$(trim "$1")"
local dotfile="$DOTFILE"
if [ -n "$2" ]; then dotfile="$2"; fi
# Ignore comment lines starting with "#".
if [[ "$line" == "#"* ]]; then return 0; fi
# Ignore Dotfile options.
if [[ "$line" == "root_link "* ]]; then return 0; fi
if [[ "$line" == "default_action "* ]]; then return 0; fi
# Handle include command.
if [[ "$line" == "include "* ]]; then
include-dotfile "$(trim "${line/#include /}")"
return "$?"
fi
echo "$line"
}
include-dotfile() {
local dotfile="$1"
local root_dir="$(dirname "$dotfile")"
local cwd="$(pwd)"
cd "$root_dir"
if [ ! -f "$dotfile" ]; then
echo "ERROR: Can not include \"$dotfile\", it does not exist." >&2
return 1
fi
while read line; do
parse-dotfile-line "$line" "$dotfile"
if [ -n "$?" ]; then return 1; fi
done < "$dotfile"
cd "$cwd"
}

View File

@@ -0,0 +1,31 @@
compile-dotfile() {
local dotfile="$1"
if [ -z "$dotfile" ]; then dotfile="$DOTFILE"; fi
local output=""
local line=""
while IFS= read line; do
# Ignore comments and blank lines.
if [[ "$line" =~ ^(\ *\#.*|\ *)$ ]]; then
continue
# Parse "<action>: <source> -> <target>" lines.
elif [[ "$line" =~ ^(\ +)?([a-zA-Z0-9_-]+):\ (.+)\ +-[\>]\ +(.+)$ ]]; then
output="${output}${BASH_REMATCH[1]}dotify-action ${BASH_REMATCH[2]} "
output="${output}$(trim "${BASH_REMATCH[3]}") "
output="${output}$(trim "${BASH_REMATCH[4]}")\n"
# Parse "<source> -> <target>" lines.
elif [[ "$line" =~ ^(\ +)?(.+)\ -[\>]\ (.+)$ ]]; then
output="${output}${BASH_REMATCH[1]}dotify-action default "
output="${output}$(trim "${BASH_REMATCH[2]}") "
output="${output}$(trim "${BASH_REMATCH[3]}")\n"
# Append line without modifications.
else
output="${output}${line}\n"
fi
done < "$dotfile"
echo -e "$output"
}

View File

@@ -0,0 +1,18 @@
create-symlink() {
local source="$1"
local target="$2"
if [ ! -e "$target" ] && [ ! -h "$target" ]; then
ln -s "$source" "$target"
return 0
elif [ -h "$target" ]; then
if [ "$(readlink "$target")" != "$source" ]; then
echo "ERROR: \"$target\" exists, is a symlink to:" \
"$(readlink "$target")" >&2
return 1
fi
else
echo "ERROR: \"$target\" exists" >&2
return 1
fi
}

View File

@@ -0,0 +1,13 @@
locate-dotfile() {
if [ -n "$DOTFILE" ]; then
if [ ! -f "$DOTFILE" ]; then
echo "ERROR: \"$DOTFILE\" does not exist." >&2
return 1
fi
elif [ -f "$(pwd)/Dotfile" ]; then
DOTFILE="$(pwd)/Dotfile"
else
echo "ERROR: \"$(pwd)\" does not have a Dotfile." >&2
return 1
fi
}

View File

@@ -0,0 +1,15 @@
locate-target() {
if [ -n "$TARGET" ]; then
if [ ! -d "$TARGET" ]; then
echo "ERROR: Target \"$TARGET\" is not a directory." >&2
return 1
fi
elif [ -n "$HOME" ] && [ -d "$HOME" ]; then
TARGET="$HOME"
elif [ -d ~ ]; then
TARGET=~
else
echo "ERROR: Your \$HOME folder could not be found." >&2
return 1
fi
}

View File

@@ -1,7 +1,17 @@
# Parse Dotfile options and set relevant global variables.
parse-dotfile-options() {
OPT_ROOT_LINK="$(parse-dotfile-root_link-option)"
OPT_DEFAULT_ACTION="$(parse-dotfile-default_action-option)"
DOTIFY_OPT_ROOT_LINK="$(parse-dotfile-root_link-option)"
DOTIFY_OPT_DEFAULT_ACTION="$(parse-dotfile-default_action-option)"
}
# Parse root_link option.
parse-dotfile-root_link-option() {
echo "$(parse-dotfile-option "root_link" ".dotfiles" "$1")"
}
# Parse default_action option.
parse-dotfile-default_action-option() {
echo "$(parse-dotfile-option "default_action" "link" "$1")"
}
# Extract a specific option from Dotfile.
@@ -17,6 +27,7 @@ parse-dotfile-option() {
local dotfile="$3"
if [ -z "$dotfile" ]; then dotfile="$DOTFILE"; fi
local line=""
while read line; do
if [[ "$line" == "$name "* ]]; then
value="$(trim "${line/#$name }")"
@@ -26,11 +37,3 @@ parse-dotfile-option() {
echo "$value"
}
parse-dotfile-root_link-option() {
echo "$(parse-dotfile-option "root_link" ".dotfiles" "$1")"
}
parse-dotfile-default_action-option() {
echo "$(parse-dotfile-option "default_action" "link" "$1")"
}

View File

@@ -0,0 +1,50 @@
#! /usr/bin/env bash
source "../../test-helper.sh"
source "../../../src/lib/internals.sh"
#
# create-symlink() tests
#
# Create temp files/folders used for create-symlink() tests.
mkdir -p "tmp/source" "tmp/target"
touch "tmp/source/profile"
# Creates a normal symlink.
assert_raises 'create-symlink ../source tmp/target/.dotfiles' 0
assert 'readlink tmp/target/.dotfiles' "../source"
rm "tmp/target/.dotfiles"
# When target exists an is a symlink to the same source.
ln -s "../source" "tmp/target/.dotfiles"
assert_raises 'create-symlink ../source tmp/target/.dotfiles' 0
assert 'create-symlink ../source tmp/target/.dotfiles 2>&1' ""
rm "tmp/target/.dotfiles"
# When target exists and is a symlink to a different source.
ln -s "../other" "tmp/target/.dotfiles"
assert_raises 'create-symlink ../source tmp/target/.dotfiles' 1
assert 'create-symlink ../source tmp/target/.dotfiles' ""
assert 'create-symlink ../source tmp/target/.dotfiles 2>&1' \
"ERROR: \"tmp/target/.dotfiles\" exists, is a symlink to: ../other"
rm "tmp/target/.dotfiles"
# When target exists and is a file.
touch "tmp/target/.profile"
assert_raises 'create-symlink ../source/profile tmp/target/.profile' 1
assert 'create-symlink ../source/profile tmp/target/.profile' ""
assert 'create-symlink ../source/profile tmp/target/.profile 2>&1' \
"ERROR: \"tmp/target/.profile\" exists"
rm "tmp/target/.profile"
# When target exists and is a directory.
assert_raises 'create-symlink ../source tmp/target' 1
assert 'create-symlink ../source tmp/target' ""
assert 'create-symlink ../source tmp/target 2>&1' \
"ERROR: \"tmp/target\" exists"
# Remove temp files/folders used for locate-dotfile() tests.
rm "tmp/source/profile"
rmdir "tmp/source" "tmp/target" "tmp"
assert_end 'create-symlink()'

View File

@@ -1,9 +1,9 @@
#! /usr/bin/env bash
source "../test-helper.sh"
source "../../src/lib/internals.sh"
source "../../test-helper.sh"
source "../../../src/lib/internals.sh"
#
# locate-dotfile()
# locate-dotfile() tests
#
# Create temp files/folders used for locate-dotfile() tests.
@@ -49,37 +49,3 @@ assert_raises "test -d test-tmp" 1
# End of locate-dotfile() tests.
assert_end 'locate-dotfile()'
#
# locate-target()
#
# When $TARGET is empty.
TARGET=""
assert_raises 'locate-target' 0
assert 'locate-target; echo "$TARGET"' "$HOME"
unset TARGET
# When $TARGET is not empty and is a directory.
TARGET="$(pwd)"
assert_raises 'locate-target' 0
assert 'locate-target; echo "$TARGET"' "$(pwd)"
unset TARGET
# When $TARGET is not empty and is not a directory.
TARGET="/tmp/this/does/not/exist"
assert_raises 'locate-target' 1
assert 'locate-target 2>&1' "ERROR: Target \"$TARGET\" is not a directory."
assert 'locate-target; echo "$TARGET"' "$TARGET"
unset TARGET
# If neither $TARGET or $HOME is set, ~ is expanded to find home folder
original_home="$HOME"
unset HOME
assert_raises 'locate-target' 0
assert 'locate-target; echo "$TARGET"' "$original_home"
HOME="$original_home"
# End of locate-target() tests.
assert_end 'locate-target()'

View File

@@ -0,0 +1,36 @@
#! /usr/bin/env bash
source "../../test-helper.sh"
source "../../../src/lib/internals.sh"
#
# locate-target() tests
#
# When $TARGET is empty.
TARGET=""
assert_raises 'locate-target' 0
assert 'locate-target; echo "$TARGET"' "$HOME"
unset TARGET
# When $TARGET is not empty and is a directory.
TARGET="$(pwd)"
assert_raises 'locate-target' 0
assert 'locate-target; echo "$TARGET"' "$(pwd)"
unset TARGET
# When $TARGET is not empty and is not a directory.
TARGET="/tmp/this/does/not/exist"
assert_raises 'locate-target' 1
assert 'locate-target 2>&1' "ERROR: Target \"$TARGET\" is not a directory."
assert 'locate-target; echo "$TARGET"' "$TARGET"
unset TARGET
# If neither $TARGET or $HOME is set, ~ is expanded to find home folder
original_home="$HOME"
unset HOME
assert_raises 'locate-target' 0
assert 'locate-target; echo "$TARGET"' "$original_home"
HOME="$original_home"
# End of locate-target() tests.
assert_end 'locate-target()'

View File

@@ -4,7 +4,7 @@ source "../../src/lib/parse-dotfile-options.sh"
source "../../src/lib/trim.sh"
#
# parse-dotfile-options()
# parse-dotfile-options() tests
#
stub "parse-dotfile-root_link-option"
@@ -24,7 +24,7 @@ assert_end "parse-dotfile-options()"
#
# parse-dotfile-option()
# parse-dotfile-option() tests
#
# Create temp files/folders used for locate-dotfile() tests.
@@ -62,7 +62,7 @@ assert_end "parse-dotfile-option()"
#
# parse-dotfile-root_link-option()
# parse-dotfile-root_link-option() tests
#
stub "parse-dotfile-option"
@@ -76,7 +76,7 @@ assert_end "parse-dotfile-root_link-option()"
#
# parse-dotfile-default_action-option()
# parse-dotfile-default_action-option() tests
#
stub "parse-dotfile-option"