summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Mike Burns and Eric Collins <mike@mike-burns.com>2016-12-23 16:18:40 -0500
committerGravatar Mike Burns and Eric Collins <mike@mike-burns.com>2016-12-26 16:39:20 -0500
commit147a7b66554b2b13bcbf6fec1204e0cc0a1790bf (patch)
tree6539b10986afe5babef3decb2991cd5bb11ac08b
parent0651e4f5e0e71b57d6564f2f2887ab98f13f1995 (diff)
Handle spaces in dotfile name
In mkrc, separate the list of files with newlines instead of spaces. Change the `$IFS` when iterating to handle this. We hand the file off to rcup, which encodes the file name by replacing spaces with the bell character (`\a`). rcup then sends the file name off to lsrc, which decodes the bell back into a space. The test makes sure an `a` character is in the filename, in case some encoding goes wrong. We use tr(1) instead of sed(1) because tr(1) handles `\a`. Shoutout to Sublime Text 3 for forcing this issue.
-rw-r--r--Makefile.am2
-rw-r--r--NEWS.md.in1
-rwxr-xr-xbin/lsrc.in9
-rwxr-xr-xbin/mkrc.in9
-rwxr-xr-xbin/rcup.in5
-rw-r--r--share/rcm.sh.in14
-rw-r--r--test/lsrc-spaces.t8
-rw-r--r--test/mkrc-spaces.t30
8 files changed, 73 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am
index fd760ad..149db29 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,6 +15,7 @@ TESTS = \
test/lsrc-sigils.t \
test/lsrc.t \
test/lsrc-symlink-dirs.t \
+ test/lsrc-spaces.t \
test/lsrc-tags.t \
test/lsrc-usage.t \
test/lsrc-undotted.t \
@@ -24,6 +25,7 @@ TESTS = \
test/mkrc-host-file.t \
test/mkrc-hostname.t \
test/mkrc-simple-output.t \
+ test/mkrc-spaces.t \
test/mkrc-symlink-dirs.t \
test/mkrc-tagged-file.t \
test/mkrc-usage.t \
diff --git a/NEWS.md.in b/NEWS.md.in
index 8f6b8a1..e6d4f72 100644
--- a/NEWS.md.in
+++ b/NEWS.md.in
@@ -1,5 +1,6 @@
rcm (@PACKAGE_VERSION@) unstable; urgency=low
+ * BUGFIX: Handle dotfile names with spaces in them (Eric Collins, Mike Burns).
* BUGFIX: Relative exclude globs now work (Eric Collins, Mike Burns).
* BUGFIX: Use $LOGNAME instead of $USER for compatibility (Mike Burns).
* BUGFIX: rcdn(1) stops at DEST_DIR (Kyle Cook, Mike Burns).
diff --git a/bin/lsrc.in b/bin/lsrc.in
index 8fb1fcd..b0dc30a 100755
--- a/bin/lsrc.in
+++ b/bin/lsrc.in
@@ -347,7 +347,8 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do
host_files="$DOTFILES_DIR/host-$HOSTNAME"
if [ -d "$host_files" ]; then
pushdir "$(basename "$host_files")"
- for file in ${FILES:-*}; do
+ for escaped_file in ${FILES:-*}; do
+ file="$(decode "$escaped_file")"
dotted=0
if is_excluded "$file" "$undotted_file_globs" "$never_undotted_file_globs"; then
dotted=1
@@ -363,7 +364,8 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do
for tag in $TAGS; do
if [ -d "tag-$tag" ]; then
pushdir "$(basename "tag-$tag")"
- for file in ${FILES:-*}; do
+ for escaped_file in ${FILES:-*}; do
+ file="$(decode "$escaped_file")"
$DEBUG "TAG: $tag, exclude_file_globs: $exclude_file_globs"
dotted=0
if is_excluded "$file" "$undotted_file_globs" "$never_undotted_file_globs"; then
@@ -377,7 +379,8 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do
cd "$DOTFILES_DIR"
- for file in ${FILES:-*}; do
+ for escaped_file in ${FILES:-*}; do
+ file="$(decode "$escaped_file")"
dotted=0
if is_metafile "$file"; then
continue
diff --git a/bin/mkrc.in b/bin/mkrc.in
index da22a63..5b2dea5 100755
--- a/bin/mkrc.in
+++ b/bin/mkrc.in
@@ -82,7 +82,10 @@ if [ $always_copy -eq 1 ]; then
INSTALL="$INSTALL -C"
fi
-files=$@
+files=""
+for i; do
+ files="$(printf "$files\n$i")"
+done
if [ $force_symlink -eq 1 ]; then
for file in $files; do
@@ -108,7 +111,11 @@ elif [ $undotted -eq 0 ]; then
done
fi
+saved_IFS="$IFS"
+IFS='
+'
for file in $files; do
+ IFS="$saved_IFS"
case "$file" in
/*) : ;;
*) [ -e "$PWD/$file" ] && file="$PWD/$file" ;;
diff --git a/bin/rcup.in b/bin/rcup.in
index de11751..932ac56 100755
--- a/bin/rcup.in
+++ b/bin/rcup.in
@@ -260,7 +260,10 @@ handle_command_line() {
tags="${arg_tags:-$TAGS}"
DOTFILES_DIRS="${dotfiles_dirs:-$DOTFILES_DIRS}"
RUN_HOOKS=$run_hooks
- files="$@"
+ files=
+ for file; do
+ files="$files $(encode "$file")"
+ done
for tag in $tags; do
LS_ARGS="$LS_ARGS -t $tag"
diff --git a/share/rcm.sh.in b/share/rcm.sh.in
index f0d3364..80e9e91 100644
--- a/share/rcm.sh.in
+++ b/share/rcm.sh.in
@@ -147,6 +147,20 @@ de_dot() {
echo "$1" | sed -e "s|$DEST_DIR/||" | sed -e 's/^\.//'
}
+DELIMITER="\a"
+
+encode() {
+ local file="$1"
+
+ echo "$file" | tr " " "$DELIMITER"
+}
+
+decode() {
+ local file="$1"
+
+ echo "$file" | tr "$DELIMITER" " "
+}
+
: ${RCRC:=$HOME/.rcrc}
if [ -r "$RCRC" ]; then
diff --git a/test/lsrc-spaces.t b/test/lsrc-spaces.t
new file mode 100644
index 0000000..fa406e2
--- /dev/null
+++ b/test/lsrc-spaces.t
@@ -0,0 +1,8 @@
+ $ . "$TESTDIR/helper.sh"
+
+Should handle dotfiles with spaces
+
+ $ touch ".dotfiles/sublame text 3.config"
+
+ $ lsrc
+ /*/.sublame text 3.config:/*/.dotfiles/sublame text 3.config (glob)
diff --git a/test/mkrc-spaces.t b/test/mkrc-spaces.t
new file mode 100644
index 0000000..ebf8d5d
--- /dev/null
+++ b/test/mkrc-spaces.t
@@ -0,0 +1,30 @@
+ $ . "$TESTDIR/helper.sh"
+
+Should handle dotfiles with spaces
+
+ $ touch ".sublime text 3.config" .example
+ $ touch .some\ other.config
+
+ $ mkrc ".sublime text 3.config" .example .some\ other.config
+
+ $ assert_linked "$HOME/.sublime text 3.config" "$HOME/.dotfiles/sublime text 3.config"
+ > assert_linked "$HOME/.example" "$HOME/.dotfiles/example"
+ > assert_linked "$HOME/.some other.config" "$HOME/.dotfiles/some other.config"
+
+Should handle hostnamed dotfiles with spaces
+
+ $ touch ".sublime text 4.config" .example2
+
+ $ mkrc -o ".sublime text 4.config" .example2
+
+ $ assert_linked "$HOME/.sublime text 4.config" "$HOME/.dotfiles/host-$(hostname)/sublime text 4.config"
+ > assert_linked "$HOME/.example2" "$HOME/.dotfiles/host-$(hostname)/example2"
+
+Should handle tagged dotfiles with spaces
+
+ $ touch ".sublime text 5.config" .example3
+
+ $ mkrc -t whatever ".sublime text 5.config" .example3
+
+ $ assert_linked "$HOME/.sublime text 5.config" "$HOME/.dotfiles/tag-whatever/sublime text 5.config"
+ > assert_linked "$HOME/.example3" "$HOME/.dotfiles/tag-whatever/example3"