summaryrefslogtreecommitdiff
path: root/bin/rcdn.in
blob: ae7aad8910ebfab685a248219b1834e630eef49c (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
#!@SHELL@

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

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

  if [ "x$dest" = "x/" ]; 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