]> arthur.barton.de Git - ax-zsh.git/blob - bin/axzshctl
Allow plugins to indicate "ignored" and "optional" state
[ax-zsh.git] / bin / axzshctl
1 #!/bin/zsh
2 #
3 # AX-ZSH: Alex' Modular ZSH Configuration
4 # Copyright (c) 2015-2016 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-plugin <name|directory> [<name|directory> [...]]"
25         echo "    Enable plugin(s)."
26         echo
27         echo "  disable-plugin <name> [<name> [...]]"
28         echo "    Disable plugin(s)."
29         echo
30         echo "  reset-plugins"
31         echo "    Reset active plugins to the default set."
32         echo
33         echo "  enable-default-plugins"
34         echo "    Enable all default plugins."
35         echo
36         echo "  check-plugins"
37         echo "    Detect plugins which are \"useful\" on this system."
38         echo
39         echo "  set-theme <name>|-"
40         echo "    Set active theme to <name>, or to the default."
41         echo
42         echo "  upgrade"
43         echo "    Upgrade AX-ZSH installation (requires Git)."
44         echo
45         exit 2
46 }
47
48 function NormalizedPluginName {
49         if [[ "$1" =~ "^[[:alnum:]-]+/[[:alnum:]_-]+$" ]]; then
50                 echo "$1" | sed -e 's|/|#|g'
51         elif [[ "$1" =~ "/" ]]; then
52                 basename "$1"
53         else
54                 echo "$1"
55         fi
56 }
57
58 function EnablePlugin {
59         local plugin=$(NormalizedPluginName "$1")
60         local dir="$AXZSH/active_plugins"
61
62         if [[ -h "$dir/$plugin" ]]; then
63                 ax_msg 1 "Plugin \"$1\" already active!"
64                 return 1
65         fi
66
67         if [[ "$1" =~ "^[[:alnum:]-]+/[[:alnum:]_-]+$" ]]; then
68                 # GitHub plugin
69                 mkdir -p "$AXZSH/repos"
70                 if [[ ! -e "$AXZSH/repos/$plugin" ]]; then
71                         ax_msg - "Cloning plugin from GitHub ..."
72                         git clone "https://github.com/$1.git" \
73                          "$AXZSH/repos/$plugin"
74                 fi
75         fi
76
77         for dname (
78                 "$plugin:A"
79                 "$AXZSH_PLUGIN_D/$plugin"
80                 "$ZSH_CUSTOM/$plugin"
81                 "$AXZSH/custom_plugins/$plugin"
82                 "$AXZSH/repos/$plugin"
83                 "$AXZSH/plugins/$plugin"
84                 "$AXZSH/default_plugins/$plugin"
85                 "$AXZSH/core/$plugin"
86         ); do
87                 [[ ! -d "$dname" ]] && continue
88                 mkdir -p "$dir"
89                 (
90                         cd "$dir" || exit 9
91                         ln -sv "$dname" "$PWD"
92                 )
93                 return $?
94         done
95
96         ax_msg 2 "Plugin \"$1\" not found!"
97         return 1
98 }
99
100 function DisablePlugin {
101         local plugin=$(NormalizedPluginName "$1")
102         local dir="$AXZSH/active_plugins"
103
104         if [[ ! -h "$dir/$plugin" ]]; then
105                 ax_msg 1 "Plugin \"$1\" not active?"
106                 return 1
107         fi
108
109         rm -v "$dir/$plugin"; r=$?
110         [ $r -eq 0 ] && rm -fr "$AXZSH/repos/$plugin"
111         return $r
112 }
113
114 function ResetPlugins {
115         local dir="$AXZSH/active_plugins"
116         local r1=0, r2=0
117
118         if [[ -e "$dir" ]]; then
119                 ax_msg - "Removing all symbolic links in $dir ..."
120                 find "$dir" -type l -print -delete; r1=$?
121         fi
122
123         ax_msg - "Removing all external repositories in \"$AXZSH/repos\" ..."
124         rm -fr "$AXZSH/repos"; r2=$?
125
126         [[ $r1 == 0 && $r2 == 0 ]] && return 0 || return 1
127 }
128
129 function EnableDefaultPlugins {
130         local dir="$AXZSH/active_plugins"
131
132         ax_msg - "Activating (linking) default plugins ..."
133         mkdir -p "$dir"
134         (
135                 cd "$dir" || exit 9
136                 ln -sfv "$AXZSH/default_plugins/"* "$PWD"
137         )
138         return $?
139 }
140
141 function SetTheme {
142         local link_name="$AXZSH/active_theme"
143
144         if [ $# -ne 1 ]; then
145                 echo "Usage: axzsh_set_theme <name|->"
146                 return 1
147         fi
148
149         rm -f "$link_name" || return 1
150
151         if [ "$1" = "-" ]; then
152                 echo "Theme settings have been reset."
153                 return 0
154         fi
155
156         if [ -r "$1" ]; then
157                 theme="$1"
158         elif [ -r "$AXZSH/custom_themes/$1.axzshtheme" ]; then
159                 theme="$AXZSH/custom_themes/$1.axzshtheme"
160         elif [ -r "$AXZSH/themes/$1.axzshtheme" ]; then
161                 theme="$AXZSH/themes/$1.axzshtheme"
162         else
163                 echo "Theme \"$1\" not found!"
164                 return 1
165         fi
166         ln -sv "$theme" "$link_name" || return 1
167         return $?
168 }
169
170 function UpgradeAXZSH {
171         if [[ $+commands[git] -eq 0 ]]; then
172                 ax_msg 2 "The git(1) command is not available!"
173                 return 1
174         fi
175         if [[ ! -d "$AXZSH/.git" ]]; then
176                 ax_msg 2 "AX-ZSH seems not to be installed using Git. Can't upgrade!"
177                 return 1
178         fi
179
180         ax_msg - "Upgrading AX-ZSH in \"$AXZSH\" using git(1) ..."
181         ( cd "$AXZSH" && git pull --ff-only )
182 }
183
184 function UpgradeForeignPlugins {
185         if [[ $+commands[git] -eq 0 ]]; then
186                 ax_msg 2 "The git(1) command is not available!"
187                 return 1
188         fi
189
190         for dir ($AXZSH/repos/*(N)); do
191                 name=$(basename "$dir" | sed -e 's|#|/|g')
192                 if [ -d "$dir/.git" ]; then
193                         ax_msg - "Upgrading \"$name\" [git] ..."
194                         (
195                                 cd "$dir"
196                                 git pull --ff-only || ax_msg 2 "Pull failed!"
197                         )
198                 else
199                         ax_msg 2 "Unknown repository type!"
200                 fi
201         done
202 }
203
204 function CheckPlugins {
205         missing_plugins=()
206         invalid_plugins=()
207
208         ax_msg - "Checking plugins ..."
209         for dir ($AXZSH/plugins/*(N)); do
210                 plugin=$(basename "$dir")
211
212                 # Test if plugin is already enabled
213                 [[ -e "$AXZSH/active_plugins/$plugin" ]] \
214                         && enabled=" (enabled)" \
215                         || unset enabled
216
217                 # Test plugin ...
218                 printf " - \"%s\"%s ... " "$plugin" "$enabled"
219                 new_plugin=""
220                 for script ($AXZSH/plugins/$plugin/$plugin.{zshrc,zprofile}); do
221                         [[ -r "$script" ]] || continue
222                         zsh -i -c "AXZSH_PLUGIN_CHECK=1 source $script"; r=$?
223                         if [[ $r -eq 0 ]]; then
224                                 new_plugin=$plugin
225                                 break
226                         fi
227                 done
228                 if [[ -n "$new_plugin" ]]; then
229                         detected_plugins+=($new_plugin)
230                         [[ -n "$enabled" ]] || missing_plugins+=($new_plugin)
231                         ax_msg 0 "OK."
232                 elif [[ $r -eq 91 ]]; then
233                         ax_msg 1 "ignored."
234                 elif [[ $r -eq 92 ]]; then
235                         ax_msg 1 "optional."
236                 else
237                         [[ -n "$enabled" ]] && invalid_plugins+=($plugin)
238                         ax_msg 2 "failed."
239                 fi
240         done
241         echo
242
243         result=0
244         if [[ -n "$missing_plugins" ]]; then
245                 ax_msg 1 "Run the following command to enable all missing plugins:"
246                 echo "$AXZSH/bin/axzshctl enable-plugin" $missing_plugins
247                 echo
248                 result=1
249         else
250                 ax_msg 0 "All detected plugins are already enabled."
251         fi
252
253         if [[ -n "$invalid_plugins" ]]; then
254                 ax_msg 1 "Run the following command to disable all failed plugins:"
255                 echo "$AXZSH/bin/axzshctl disable-plugin" $invalid_plugins
256                 result=1
257         else
258                 ax_msg 0 "No failed plugins are enabled."
259         fi
260
261         echo
262         return $result
263 }
264
265 NAME="$0:t"
266
267 [[ $# -gt 0 ]] || Usage
268
269 if [[ -z "$AXZSH" || ! -d "$AXZSH" ]]; then
270         ax_msg 2 "Oops, \"AXZSH\" is not set or invalid!"
271         exit 3
272 fi
273
274 cmd="$1"
275 shift
276
277 case "$cmd" in
278         "enable-plugin")
279                 [[ $# -gt 0 ]] || Usage
280                 for plugin in "$@"; do
281                         EnablePlugin "$plugin"
282                 done
283                 ;;
284         "disable-plugin")
285                 [[ $# -gt 0 ]] || Usage
286                 for plugin in "$@"; do
287                         DisablePlugin "$plugin"
288                 done
289                 ;;
290         "reset-plugins")
291                 [[ $# -eq 0 ]] || Usage
292                 ResetPlugins
293                 EnableDefaultPlugins
294                 ;;
295         "enable-default-plugins")
296                 [[ $# -eq 0 ]] || Usage
297                 EnableDefaultPlugins
298                 ;;
299         "check-plugins")
300                 [[ $# -eq 0 ]] || Usage
301                 CheckPlugins
302                 ;;
303         "set-theme")
304                 [[ $# -eq 1 ]] || Usage
305                 SetTheme "$1"
306                 ;;
307         "upgrade")
308                 [[ $# -eq 0 ]] || Usage
309                 UpgradeAXZSH
310                 UpgradeForeignPlugins
311                 ;;
312         *)
313                 Usage
314 esac