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