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