summaryrefslogtreecommitdiff
path: root/bin/rcdn.in
blob: a2a847281159bcb1516d75f21f76b9da3cf31094 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!@SHELL@

: ${RCM_LIB:=$(dirname "$0")/../share/rcm}
. "$RCM_LIB/rcm.sh"

remove_link() {
  local dest="$1"
  local original="$2"
  local sigil="$3"

  $DEBUG "remove_link $1 $2 $3"

  if [ "x$dest" = "x/" -o "x$dest" = "x$DEST_DIR" ]; then
    $VERBOSE "not a symlink, skipping: $original"
  elif [ -L "$dest" -o "x$sigil" = "xX" ]; then
    rm_v -rf "$dest"
    rmdir -p "$(dirname "$original")" 2>/dev/null
  else
    remove_link "$(dirname "$dest")" "$original"
  fi
}

show_help() {
  local exit_code=${1:-0}

  $PRINT "Usage: rcdn [-hqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT]"
  $PRINT "see rcdn(1) and rcm(7) for more details"

  exit $exit_code
}

handle_command_line() {
  local arg_tags=
  local verbosity=0
  local version=0
  local run_hooks=1
  local dotfiles_dirs=
  local files=
  local excludes=
  local includes=
  local symlink_dirs=
  local never_symlink_dirs=
  local undotted=
  local never_undotted=
  local hostname=

  while getopts :VqvhIKk:x:S:s:U:u:t:d:B: opt; do
    case "$opt" in
      h) show_help ;;
      B) hostname="$OPTARG" ;;
      I) includes="$includes $OPTARG";;
      k) run_hooks=1 ;;
      K) run_hooks=0 ;;
      t) arg_tags="$arg_tags $OPTARG" ;;
      S) symlink_dirs="$symlink_dirs $OPTARG";;
      s) never_symlink_dirs="$never_symlink_dirs $OPTARG";;
      U) undotted="$undotted $OPTARG";;
      u) never_undotted="$never_undotted $OPTARG";;
      v) verbosity=$(($verbosity + 1));;
      q) verbosity=$(($verbosity - 1));;
      d) dotfiles_dirs="$dotfiles_dirs $OPTARG" ;;
      V) version=1 ;;
      x) excludes="$excludes $OPTARG" ;;
      ?) show_help 64 ;;
    esac
  done
  shift $(($OPTIND-1))

  handle_common_flags rcup $version $verbosity
  hostname="$(determine_hostname "$hostname")"

  tags="${arg_tags:-$TAGS}"
  dotfiles_dirs="${dotfiles_dirs:-$DOTFILES_DIRS}"
  files="$@"
  RUN_HOOKS=$run_hooks

  for tag in $tags; do
    LS_ARGS="$LS_ARGS -t $tag"
  done
  for dotfiles_dir in $dotfiles_dirs; do
    LS_ARGS="$LS_ARGS -d $dotfiles_dir"
  done
  for exclude in $excludes; do
    LS_ARGS="$LS_ARGS -x $exclude"
  done
  for include in $includes; do
    LS_ARGS="$LS_ARGS -I $include"
  done
  for symlink_dir in $symlink_dirs; do
    LS_ARGS="$LS_ARGS -S $symlink_dir"
  done
  for never_symlink_dir in $symlink_dirs; do
    LS_ARGS="$LS_ARGS -s $never_symlink_dir"
  done
  for undot in $undotted; do
    LS_ARGS="$LS_ARGS -U $undot"
  done
  for never_undot in $never_undotted; do
    LS_ARGS="$LS_ARGS -u $never_undot"
  done

  LS_ARGS="$LS_ARGS -B $hostname $files"

  $DEBUG "LS_ARGS: $LS_ARGS"
}

LS_ARGS=-F

handle_command_line "$@"
: ${DOTFILES_DIRS:=$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR}

run_hooks pre down

dests_and_srcs="$(lsrc $LS_ARGS)"

saved_ifs="$IFS"
IFS='
'
for dest_and_src in $dests_and_srcs; do
  IFS=:
  set -- $dest_and_src
  IFS="$saved_ifs"
  dest="$1"
  sigil="$3"

  remove_link "$dest" "$dest" "$sigil"
done

IFS="$saved_ifs"
run_hooks post down