]> arthur.barton.de Git - ax-zsh.git/blob - bin/axzshctl
axzshctl: Regenerate plugin cache, not only drop it
[ax-zsh.git] / bin / axzshctl
1 #!/usr/bin/env zsh
2 #
3 # AX-ZSH: Alex' Modular ZSH Configuration
4 # Copyright (c) 2015-2017 Alexander Barton <alex@barton.de>
5 #
6
7 # Include "ax-common.sh", if available:
8 for dir ("$HOME/lib" "$HOME/.ax" /usr/local /opt/ax /usr); do
9         [[ -z "$ax_common_sourced" ]] || break
10         ax_common="${dir}/lib/ax/ax-common.sh"
11         [[ -r "$ax_common" ]] && source "$ax_common"
12 done
13 if [[ -z "$ax_common_sourced" ]]; then
14         function ax_msg {
15                 shift
16                 echo "$@"
17         }
18 fi
19 unset dir ax_common ax_common_sourced
20
21 function Usage {
22         echo "Usage: $NAME <command> [...]"
23         echo
24         echo "  enable"
25         echo "    Enable AX-ZSH altogether."
26         echo "  disable"
27         echo "    Disable AX-ZSH altogether."
28         echo
29         echo "  enable-plugin <name|directory> [<name|directory> [...]]"
30         echo "    Enable plugin(s)."
31         echo "  disable-plugin <name> [<name> [...]]"
32         echo "    Disable plugin(s)."
33         echo "  list-enabled"
34         echo "    List enabled plugins."
35         echo
36         echo "  reset-plugins"
37         echo "    Reset active plugins to the default set."
38         echo "  enable-default-plugins"
39         echo "    Enable all default plugins."
40         echo "  check-plugins"
41         echo "    Detect plugins which are \"useful\" on this system."
42         echo
43         echo "  set-theme <name>|-"
44         echo "    Set active theme to <name>, or to the default."
45         echo
46         echo "  upgrade"
47         echo "    Upgrade AX-ZSH installation (requires Git)."
48         echo
49         exit 2
50 }
51
52 function UpdatePluginCache {
53         [[ -r "$AXZSH/cache" ]] || return 0
54
55         ax_msg - "Updating plugin cache ..."
56         rm -rf \
57                 $AXZSH/cache/zlogin.cache \
58                 $AXZSH/cache/zlogout.cache \
59                 $AXZSH/cache/zprofile.cache \
60                 $AXZSH/cache/zshrc.cache \
61                 || return 1
62         echo "Regenerating cache files ..."
63         zsh -ilc '' >/dev/null
64 }
65
66 function NormalizedPluginName {
67         if [[ "$1" =~ "^[[:alnum:]-]+/[[:alnum:]_-]+$" ]]; then
68                 echo "${1:gs/\//#}"
69         elif [[ "$1" =~ "/" ]]; then
70                 echo "${1:t}"
71         else
72                 echo "$1"
73         fi
74 }
75
76 function EnableAXZSH {
77         for f (~/.zlogin ~/.zlogout ~/.zprofile ~/.zshrc); do
78                 ln -sv "$AXZSH/ax.zsh" "$f" \
79                         || ax_msg 2 "Failed to create symbolic link for \"$f\"!"
80         done
81 }
82
83 function DisableAXZSH {
84         for f (~/.zlogin ~/.zlogout ~/.zprofile ~/.zshrc); do
85                 if [ -h "$f" ]; then
86                         rm -v "$f" || ax_msg 2 "Failed to remove \"$f\"!"
87                 elif [ -e "$f" ]; then
88                         ax_msg 2 "Error: Not removing \"$f\", it is not a symbolic link!"
89                 else
90                         ax_msg 1 "Warning: \"$f\" already does not exist. Ok."
91                 fi
92         done
93 }
94
95 function EnablePlugin {
96         local plugin=$(NormalizedPluginName "$1")
97         local dir="$AXZSH/active_plugins"
98
99         if [[ -h "$dir/$plugin" ]]; then
100                 ax_msg 1 "Plugin \"$1\" already active!"
101                 return 1
102         fi
103
104         if [[ "$1" =~ "^[[:alnum:]-]+/[[:alnum:]_-]+$" ]]; then
105                 # GitHub plugin
106                 mkdir -p "$AXZSH/repos"
107                 if [[ ! -e "$AXZSH/repos/$plugin" ]]; then
108                         ax_msg - "Cloning plugin from GitHub ..."
109                         git clone "https://github.com/$1.git" \
110                          "$AXZSH/repos/$plugin"
111                 fi
112         fi
113
114         for dname (
115                 "$plugin:A"
116                 "$AXZSH_PLUGIN_D/$plugin"
117                 "$ZSH_CUSTOM/$plugin"
118                 "$AXZSH/custom_plugins/$plugin"
119                 "$AXZSH/repos/$plugin"
120                 "$AXZSH/plugins/$plugin"
121                 "$AXZSH/default_plugins/$plugin"
122                 "$AXZSH/core/$plugin"
123         ); do
124                 [[ ! -d "$dname" ]] && continue
125                 mkdir -p "$dir"
126                 (
127                         cd "$dir" || exit 9
128                         ln -sv "$dname" "$PWD"
129                 )
130                 return $?
131         done
132
133         ax_msg 2 "Plugin \"$1\" not found!"
134         return 1
135 }
136
137 function DisablePlugin {
138         local plugin=$(NormalizedPluginName "$1")
139         local dir="$AXZSH/active_plugins"
140
141         if [[ ! -h "$dir/$plugin" ]]; then
142                 ax_msg 1 "Plugin \"$1\" not active?"
143                 return 1
144         fi
145
146         rm -v "$dir/$plugin"; r=$?
147         [ $r -eq 0 ] && rm -fr "$AXZSH/repos/$plugin"
148         return $r
149 }
150
151 function ListEnabledPlugins {
152         for plugin ($AXZSH/active_plugins/*(N)); do
153                 print ${plugin:t:s/#/\//}
154         done
155         return 0
156 }
157
158 function ResetPlugins {
159         local dir="$AXZSH/active_plugins"
160         local r1=0, r2=0
161
162         if [[ -e "$dir" ]]; then
163                 ax_msg - "Removing all symbolic links in $dir ..."
164                 find "$dir" -type l -print -delete; r1=$?
165         fi
166
167         ax_msg - "Removing all external repositories in \"$AXZSH/repos\" ..."
168         rm -fr "$AXZSH/repos"; r2=$?
169
170         [[ $r1 == 0 && $r2 == 0 ]] && return 0 || return 1
171 }
172
173 function EnableDefaultPlugins {
174         local dir="$AXZSH/active_plugins"
175
176         ax_msg - "Activating (linking) default plugins ..."
177         mkdir -p "$dir"
178         (
179                 cd "$dir" || exit 9
180                 ln -sfv "$AXZSH/default_plugins/"* "$PWD"
181         )
182         return $?
183 }
184
185 function SetTheme {
186         local link_name="$AXZSH/active_theme"
187
188         if [ $# -ne 1 ]; then
189                 echo "Usage: axzsh_set_theme <name|->"
190                 return 1
191         fi
192
193         rm -f "$link_name" || return 1
194
195         if [ "$1" = "-" ]; then
196                 echo "Theme settings have been reset."
197                 return 0
198         fi
199
200         if [ -r "$1" ]; then
201                 theme="$1"
202         elif [ -r "$AXZSH/custom_themes/$1.axzshtheme" ]; then
203                 theme="$AXZSH/custom_themes/$1.axzshtheme"
204         elif [ -r "$AXZSH/themes/$1.axzshtheme" ]; then
205                 theme="$AXZSH/themes/$1.axzshtheme"
206         else
207                 echo "Theme \"$1\" not found!"
208                 return 1
209         fi
210         ln -sv "$theme" "$link_name" || return 1
211         return $?
212 }
213
214 function UpgradeAXZSH {
215         if [[ $+commands[git] -eq 0 ]]; then
216                 ax_msg 2 "The git(1) command is not available!"
217                 return 1
218         fi
219         if [[ ! -d "$AXZSH/.git" ]]; then
220                 ax_msg 2 "AX-ZSH seems not to be installed using Git. Can't upgrade!"
221                 return 1
222         fi
223
224         ax_msg - "Upgrading AX-ZSH in \"$AXZSH\" using git(1) ..."
225         ( cd "$AXZSH" && git pull --ff-only )
226 }
227
228 function UpgradeForeignPlugins {
229         if [[ $+commands[git] -eq 0 ]]; then
230                 ax_msg 2 "The git(1) command is not available!"
231                 return 1
232         fi
233
234         for dir ($AXZSH/repos/*(N)); do
235                 name=${dir:t:s/#/\//}
236                 if [ -d "$dir/.git" ]; then
237                         ax_msg - "Upgrading \"$name\" [git] ..."
238                         (
239                                 cd "$dir"
240                                 git pull --ff-only || ax_msg 2 "Pull failed!"
241                         )
242                 else
243                         ax_msg 2 "Unknown repository type!"
244                 fi
245         done
246 }
247
248 function CheckPlugins {
249         missing_plugins=()
250         invalid_plugins=()
251
252         ax_msg - "Checking plugins ..."
253         for dir ($AXZSH/plugins/*(N)); do
254                 plugin=${dir:t}
255
256                 # Test if plugin is already enabled
257                 [[ -e "$AXZSH/active_plugins/$plugin" ]] \
258                         && enabled=" (enabled)" \
259                         || unset enabled
260
261                 # Test plugin ...
262                 printf " - \"%s\"%s ... " "$plugin" "$enabled"
263                 new_plugin=""
264                 for script ($AXZSH/plugins/$plugin/$plugin.{zshrc,zprofile}); do
265                         [[ -r "$script" ]] || continue
266                         AXZSH_PLUGIN_CHECK=1 zsh -i -c "source $script"; r=$?
267                         if [[ $r -eq 0 ]]; then
268                                 new_plugin=$plugin
269                                 break
270                         fi
271                 done
272                 if [[ -n "$new_plugin" ]]; then
273                         detected_plugins+=($new_plugin)
274                         [[ -n "$enabled" ]] || missing_plugins+=($new_plugin)
275                         ax_msg 0 "OK."
276                 elif [[ $r -eq 91 ]]; then
277                         ax_msg 1 "ignored."
278                 elif [[ $r -eq 92 ]]; then
279                         ax_msg 1 "optional."
280                 else
281                         [[ -n "$enabled" ]] && invalid_plugins+=($plugin)
282                         ax_msg 2 "failed."
283                 fi
284         done
285         echo
286
287         result=0
288         if [[ -n "$missing_plugins" ]]; then
289                 ax_msg 1 "Run the following command to enable all missing plugins:"
290                 echo "$AXZSH/bin/axzshctl enable-plugin" $missing_plugins
291                 echo
292                 result=1
293         else
294                 ax_msg 0 "All detected plugins are already enabled."
295         fi
296
297         if [[ -n "$invalid_plugins" ]]; then
298                 ax_msg 1 "Run the following command to disable all failed plugins:"
299                 echo "$AXZSH/bin/axzshctl disable-plugin" $invalid_plugins
300                 result=1
301         else
302                 ax_msg 0 "No failed plugins are enabled."
303         fi
304
305         echo
306         return $result
307 }
308
309 NAME="$0:t"
310
311 [[ $# -gt 0 ]] || Usage
312
313 if [[ -z "$AXZSH" || ! -r "$AXZSH/ax.zsh" ]]; then
314         [[ -r "$HOME/.axzsh/ax.zsh" ]] && AXZSH="$HOME/.axzsh"
315         if [[ ! -r "$AXZSH/ax.zsh" ]]; then
316                 ax_msg 2 "Oops, \"AXZSH\" is not set or invalid and can't be autodetected!"
317                 exit 3
318         fi
319 fi
320
321 cmd="$1"
322 shift
323
324 case "$cmd" in
325         "enable")
326                 [[ $# -eq 0 ]] || Usage
327                 EnableAXZSH
328                 ;;
329         "disable")
330                 [[ $# -eq 0 ]] || Usage
331                 DisableAXZSH
332                 ;;
333         "enable-plugin")
334                 [[ $# -gt 0 ]] || Usage
335                 for plugin in "$@"; do
336                         EnablePlugin "$plugin"
337                 done
338                 UpdatePluginCache
339                 ;;
340         "disable-plugin")
341                 [[ $# -gt 0 ]] || Usage
342                 for plugin in "$@"; do
343                         DisablePlugin "$plugin"
344                 done
345                 UpdatePluginCache
346                 ;;
347         "list-enabled")
348                 [[ $# -eq 0 ]] || Usage
349                 ListEnabledPlugins
350                 ;;
351         "reset-plugins")
352                 [[ $# -eq 0 ]] || Usage
353                 ResetPlugins
354                 EnableDefaultPlugins
355                 UpdatePluginCache
356                 ;;
357         "enable-default-plugins")
358                 [[ $# -eq 0 ]] || Usage
359                 EnableDefaultPlugins
360                 UpdatePluginCache
361                 ;;
362         "check-plugins")
363                 [[ $# -eq 0 ]] || Usage
364                 CheckPlugins
365                 ;;
366         "set-theme")
367                 [[ $# -eq 1 ]] || Usage
368                 SetTheme "$1"
369                 UpdatePluginCache
370                 ;;
371         "upgrade")
372                 [[ $# -eq 0 ]] || Usage
373                 UpgradeAXZSH
374                 UpgradeForeignPlugins
375                 UpdatePluginCache
376                 ;;
377         *)
378                 Usage
379 esac