diff options
-rw-r--r-- | bin/Makefile.in | 4 | ||||
-rwxr-xr-x | bin/lsrc | 86 | ||||
-rwxr-xr-x | bin/rcdn | 7 | ||||
-rwxr-xr-x | bin/rcup | 7 | ||||
-rw-r--r-- | man/Makefile.in | 4 | ||||
-rw-r--r-- | man/lsrc.1 | 44 | ||||
-rw-r--r-- | man/rcdn.1 | 21 | ||||
-rw-r--r-- | man/rcm.7 | 8 | ||||
-rw-r--r-- | man/rcrc.5 | 18 | ||||
-rw-r--r-- | man/rcup.1 | 27 | ||||
-rw-r--r-- | share/Makefile.in | 4 | ||||
-rw-r--r-- | share/rcm.sh.in | 10 |
12 files changed, 184 insertions, 56 deletions
diff --git a/bin/Makefile.in b/bin/Makefile.in index cdf3377..42d9875 100644 --- a/bin/Makefile.in +++ b/bin/Makefile.in @@ -180,9 +180,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bin/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign bin/Makefile + $(AUTOMAKE) --gnu bin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -34,13 +34,16 @@ link_dir() { local dest_dir=$2 local dotfiles_dir=$3 local dotted=$4 + local exclude_file_globs="$5" local dest_path=`build_path $dest_dir $dir $dotted` + $DEBUG "link_dir $1 $2 $3 $4 $5" + $VERBOSE "recurring on $dest_path" pushdir $dir for f in *; do $DEBUG "handling the file $f" - handle_file $f $dest_path $dotfiles_dir/$dir 1 + handle_file $f $dest_path $dotfiles_dir/$dir 1 "$exclude_file_globs" done popdir } @@ -64,21 +67,68 @@ handle_file() { local dest_dir=$2 local dotfiles_dir=$3 local dotted=$4 + local exclude_file_globs="$5" - $DEBUG handle_file $1 $2 $3 $4 + $DEBUG "handle_file $1 $2 $3 $4 $5" if [ ! -e $file ]; then $VERBOSE "skipping non-existent file $file" + elif is_excluded $file "$exclude_file_globs"; then + $VERBOSE "skipping excluded file $file" elif [ -d $file ]; then - link_dir $file $dest_dir $dotfiles_dir $dotted + link_dir $file $dest_dir $dotfiles_dir $dotted "$exclude_file_globs" else - dest_file=`build_path $dest_dir $file $dotted` link_file $file $dest_dir $dotfiles_dir $dotted fi } -metafile() { - [ x$2 = 'xhost-' -o x$3 = 'xtag-' ] +is_metafile() { + host_portion=`echo $1 | sed -e 's/host-.*/host-/'` + tag_portion=`echo $1 | sed -e 's/tag-.*/tag-/'` + + [ x$host_portion = 'xhost-' -o x$tag_portion = 'xtag-' ] +} + +dotfiles_dir_excludes() { + local dotfiles_dir=$1 + + $DEBUG "dotfiles_dir_excludes $dotfiles_dir" + $DEBUG " with EXCLUDES: $EXCLUDES" + + for exclude in $EXCLUDES; do + if echo $exclude | grep -q :; then + dotfiles_dir_pat=`echo $exclude | sed 's/:.*//'` + file_glob=`echo $exclude | sed 's/.*://'` + + if [ "x$dotfiles_dir_pat" != "x*" ] && is_relative $dotfiles_dir_pat; then + dotfiles_dir_pat=$PWD/$dotfiles_dir_pat + fi + + if [ "x$dotfiles_dir_pat" = "x*" -o "x$dotfiles_dir_pat" = "x$dotfiles_dir" ]; then + echo $file_glob + fi + else + echo $exclude + fi + done +} + +is_excluded() { + local file=$1 + local exclude_file_globs="$2" + + $DEBUG "is_excluded $file $exclude_file_globs" + + for file_glob in $exclude_file_globs; do + $DEBUG "file_glob: $file_glob" + $DEBUG "file: $file" + + case $file in + $file_glob) return 0;; + esac + done + + return 1 } handle_command_line() { @@ -86,9 +136,11 @@ handle_command_line() { local verbosity=0 local version=0 local dotfiles_dirs= + local excludes= - while getopts Vqvt:d: opt; do + while getopts Vqve:t:d: opt; do case "$opt" in + e) excludes="$excludes $OPTARG";; t) arg_tags="$arg_tags $OPTARG";; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; @@ -101,6 +153,7 @@ handle_command_line() { handle_common_flags lsrc $version $verbosity TAGS=${arg_tags:-$TAGS} DOTFILES_DIRS=${dotfiles_dirs:-$DOTFILES_DIRS} + EXCLUDES=${excludes:-$EXCLUDES} FILES=$@ $DEBUG "TAGS: $TAGS" @@ -119,8 +172,7 @@ handle_command_line $* $DEBUG "DOTFILES_DIRS: $DOTFILES_DIRS" for DOTFILES_DIR in $DOTFILES_DIRS; do - - if echo $DOTFILES_DIR | grep -vq '^/'; then + if is_relative $DOTFILES_DIR; then DOTFILES_DIR=$PWD/$DOTFILES_DIR fi @@ -129,15 +181,18 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do continue fi + exclude_file_globs=`dotfiles_dir_excludes $DOTFILES_DIR` + $DEBUG "exclude_file_globs: $exclude_file_globs" + cd $DOTFILES_DIR DIR_STACK=":$DOTFILES_DIR" for file in ${FILES:-*}; do - host_portion=`echo $file | sed -e 's/host-.*/host-/'` - tag_portion=`echo $file | sed -e 's/tag-.*/tag-/'` - if ! metafile $file $host_portion $tag_portion; then - handle_file $file $DEST_DIR $DOTFILES_DIR 0 + if is_metafile $file; then + continue fi + + handle_file $file $DEST_DIR $DOTFILES_DIR 0 "$exclude_file_globs" done cd $DOTFILES_DIR @@ -146,7 +201,7 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do if [ -d $host_files ]; then pushdir `basename $host_files` for file in ${FILES:-*}; do - handle_file $file $DEST_DIR $host_files 0 + handle_file $file $DEST_DIR $host_files 0 "$exclude_file_globs" done popdir fi @@ -157,7 +212,8 @@ for DOTFILES_DIR in $DOTFILES_DIRS; do if [ -d tag-$tag ]; then pushdir `basename tag-$tag` for file in ${FILES:-*}; do - handle_file $file $DEST_DIR $DOTFILES_DIR/tag-$tag 0 + $DEBUG "TAG: $tag, exclude_file_globs: $exclude_file_globs" + handle_file $file $DEST_DIR $DOTFILES_DIR/tag-$tag 0 "$exclude_file_globs" done popdir fi @@ -9,9 +9,11 @@ handle_command_line() { local version=0 local dotfiles_dirs= local files= + local excludes= - while getopts Vqvt:d: opt; do + while getopts Vqve:t:d: opt; do case "$opt" in + e) excludes="$excludes $OPTARG";; t) arg_tags="$arg_tags $OPTARG" ;; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; @@ -33,6 +35,9 @@ handle_command_line() { for dotfiles_dir in $dotfiles_dirs; do LS_ARGS="$LS_ARGS -d $dotfiles_dir" done + for exclude in $excludes; do + LS_ARGS="$LS_ARGS -e $exclude" + done LS_ARGS="$LS_ARGS $files" $DEBUG "LS_ARGS: $LS_ARGS" @@ -76,11 +76,13 @@ handle_command_line() { local version=0 local dotfiles_dirs= local files= + local excludes= REPLACE_ALL=0 - while getopts Vqvfit:d: opt; do + while getopts Vqvfie:t:d: opt; do case "$opt" in + e) excludes="$excludes $OPTARG";; f) REPLACE_ALL=1 ;; i) REPLACE_ALL=0 ;; t) arg_tags="$arg_tags $OPTARG" ;; @@ -104,6 +106,9 @@ handle_command_line() { for dotfiles_dir in $dotfiles_dirs; do LS_ARGS="$LS_ARGS -d $dotfiles_dir" done + for exclude in $excludes; do + LS_ARGS="$LS_ARGS -e $exclude" + done LS_ARGS="$LS_ARGS $files" $DEBUG "LS_ARGS: $LS_ARGS" diff --git a/man/Makefile.in b/man/Makefile.in index ed1e0db..51cc9de 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -184,9 +184,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign man/Makefile + $(AUTOMAKE) --gnu man/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -9,6 +9,7 @@ .Op Fl vq .Op Fl t Ar tag .Op Fl d Ar dir +.Op Fl e Ar excl_pat .Op files ... .Sh DESCRIPTION This program lists all configuration files, both the sources in the @@ -23,21 +24,52 @@ section, for details on the directory layout. It supports these options: . .Bl -tag -.It Fl v -increase verbosity. This can be repeated for extra verbosity. -. -.It Fl q -decrease verbosity -. .It Fl t Ar TAG list dotfiles according to TAG . .It Fl d Ar DIR list dotfiles from the DIR. This can be specified multiple times. . +.It Fl e Ar excl_pat +Exclude the files that matches the given pattern. See +.Sx EXCLUDE PATTERN +for more details. This option can be repeated. +. +.It Fl v +increase verbosity. This can be repeated for extra verbosity. +. +.It Fl q +decrease verbosity +. .It Ar files ... only list the specified file(s) .El +.Sh EXCLUDE PATTERN +The exclude pattern specifies a colon-separated pair of dotfiles +directory and file glob. The dotfiles directory is optional and, if +omitted, defaults to +.Li * , +which is a special token that matches any dotfiles directory. The file +glob is relative to the dotfiles directory, ignoring meta directories. A +colon combines them. +. +.Pp +For example, to ignore all emacs-related items from the +.Pa thoughtbot-dotfiles +directory, use the exclude pattern: +.Pp +.Dl thoughtbot-dotfiles:*emacs* +.Pp +To ignore any +.Pa bash_profile +file, use the pattern: +.Pp +.Dl *:bash_profile +.Pp +Or more simply: +.Pp +.Dl bash_profile +.Pp .Sh FILES .Pa ~/.dotfiles .Pa ~/.rcrc @@ -19,17 +19,24 @@ and .Fl d flags. .Bl -tag -.It Fl v -increase verbosity. This can be repeated for extra verbosity. +.It Fl d Ar DIR +remove rc files from the +.Ar DIR . +This can be specified multiple times. +.It Fl e Ar EXCL_PAT +do not remove rc files that match +.Ar EXCL_PAT . +This can be repeated with additional patterns. See +.Xr lsrc 1 , +.Sx EXCLUDE PATTERN , +for more details. .It Fl q decrease verbosity .It Fl t Ar TAG remove dotfiles according to .Ar TAG -.It Fl d Ar DIR -remove dotfiles from the -.Ar DIR . -This can be specified multiple times. +.It Fl v +increase verbosity. This can be repeated for extra verbosity. .It Ar files only remove the specified file(s) .El @@ -39,8 +46,8 @@ only remove the specified file(s) .Dl rcdn zshrc .Dl rcdn -t python .Dl rcdn -d ~/corporate-dotfiles +.Dl rcdn -e '*:.zshrc' .Sh FILES -.Pa ~/.dotfiles .Pa ~/.rcrc .Sh SEE ALSO .Xr lsrc 1 , @@ -83,10 +83,9 @@ in the directory directory. This will cause a or .Pa ~/.Makefile symlink to be created in your home -directory. The best option here is to move that file outside of your -dotfiles directory or remove it entirely. +directory. Use an exclusion pattern to ignore these. .Pp -.Dl rm -f install Rakefile Makefile install.sh +.Dl rcup -e install -e Rakefile -e Makefile -e install.sh .Ss COMMON PROBLEM: DOTTED FILENAMES IN DOTFILES DIRECTORY A less common situation is for all the filenames in your dotfiles directory to be prefixed with a period. These files are skipped by the @@ -201,6 +200,9 @@ will take precedence over .Pp .Dl rcup -d .dotfiles -d marriage-dotfiles -d thoughtbot-dotfiles .Pp +An exclusion pattern can be tied to a specific dotfiles directory. +.Pp +.Dl rcup -d .dotfiles -d work-dotfiles -e 'work-dotfiles:powrc' . .Sh HOST-SPECIFIC DOTFILES You can also mark host-specific files. This will go by the hostname. The @@ -17,30 +17,36 @@ .Sh DESCRIPTION The rcm dotfile manager can be configured using a .Pa .rcrc -file in your home directory. The format is POSIX shell, and it is +file in your home directory. The format is POSIX shell. It is sourced in by the .Xr lsrc 1 , .Xr mkrc 1 , +.Xr rcdn 1 , and .Xr rcup 1 programs. .Pp It supports these variables: .Bl -tag -.It Va TAGS -the default tags used by -.Nm rcup .It Va DOTFILES_DIRS the source directories for dotfiles. The first in the list is the canonical source. The default value is .Li ~/.dotfiles +.It Va EXCLUDES +a space-separated list of exclude patterns. Exclude patterns are +explained in detail in +.Xr lsrc 1 +under the section +.Sx EXCLUDE PATTERN . +.It Va TAGS +the default tags. .El .Sh FILES -.Pa ~/.dotfiles .Pa ~/.rcrc .Sh EXAMPLES -.Dl TAGS="freebsd development email git laptop gmail notmuch" .Dl DOTFILES_DIRS="/home/mike/.dotfiles /usr/share/dotfiles" +.Dl EXCLUDES="irbrc *:*emacs* dotfiles:python*" +.Dl TAGS="freebsd development email git laptop gmail notmuch" .Sh SEE ALSO .Xr lsrc 1 , .Xr mkrc 1 , @@ -6,9 +6,9 @@ .Nd update and install dotfiles .Sh SYNOPSIS .Nm rcup -.Op Fl vqfi -.Op Fl t Ar tag +.Op Fl fiqv .Op Fl d Ar dir +.Op Fl t Ar tag .Op Ar files ... .Sh DESCRIPTION This is a program to update and install personal dotfiles. These @@ -23,25 +23,32 @@ for details on the directory layout. .Pp It supports these options: .Bl -tag -.It f +.It Fl d Ar DIR +install dotfiles from the +.Ar DIR +\&. This can be specified multiple times. +.It Fl e Ar EXCL_PAT +do not install rc files that match +.Ar EXCL_PAT . +This can be repeated with additional patterns. See +.Xr lsrc 1 , +.Sx EXCLUDE PATTERN , +for more details. +.It Fl f If the rc file already exists in your home directory but does not match the file in your dotfiles directory, remove the rc file then create the symlink -.It i +.It Fl i If the rc file already exists in your home directory but does not match the file in your dotfiles directory, prompt for how to handle it. This is the default .It Fl t Ar TAG install dotfiles according to .Ar TAG -.It Fl d Ar DIR -install dotfiles from the -.Ar DIR -\&. This can be specified multiple times. -.It Fl v -increase verbosity. This can be repeated for extra verbosity. .It Fl q decrease verbosity +.It Fl v +increase verbosity. This can be repeated for extra verbosity. .It Ar files only install the specified file(s) .El diff --git a/share/Makefile.in b/share/Makefile.in index 8b2661d..448b28c 100644 --- a/share/Makefile.in +++ b/share/Makefile.in @@ -181,9 +181,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign share/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu share/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign share/Makefile + $(AUTOMAKE) --gnu share/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ diff --git a/share/rcm.sh.in b/share/rcm.sh.in index f25665b..6dae15b 100644 --- a/share/rcm.sh.in +++ b/share/rcm.sh.in @@ -28,6 +28,14 @@ echo_error() { exit $exit_status } +echo_stderr() { + echo $* >&2 +} + +is_relative() { + echo $1 | grep -vq '^/' +} + version() { cat << EOV $1 (rcm) $VERSION @@ -47,7 +55,7 @@ handle_common_flags() { version $prog_name exit 0 elif [ $verbosity -ge 2 ]; then - DEBUG=echo + DEBUG=echo_stderr VERBOSE=echo PRINT=echo MV="$MV -v" |