web--browse: look at the BROWSER env var
[git] / git-web--browse.sh
1 #!/bin/sh
2 #
3 # This program launch a web browser on the html page
4 # describing a git command.
5 #
6 # Copyright (c) 2007 Christian Couder
7 # Copyright (c) 2006 Theodore Y. Ts'o
8 #
9 # This file is heavily stolen from git-mergetool.sh, by
10 # Theodore Y. Ts'o (thanks) that is:
11 #
12 # Copyright (c) 2006 Theodore Y. Ts'o
13 #
14 # This file is licensed under the GPL v2, or a later version
15 # at the discretion of Junio C Hamano or any other official
16 # git maintainer.
17 #
18
19 USAGE='[--browser=browser|--tool=browser] [--config=conf.var] url/file ...'
20
21 # This must be capable of running outside of git directory, so
22 # the vanilla git-sh-setup should not be used.
23 NONGIT_OK=Yes
24 . git-sh-setup
25
26 valid_custom_tool()
27 {
28         browser_cmd="$(git config "browser.$1.cmd")"
29         test -n "$browser_cmd"
30 }
31
32 valid_tool() {
33         case "$1" in
34         firefox | iceweasel | seamonkey | iceape | \
35         chrome | google-chrome | chromium | chromium-browser |\
36         konqueror | opera | w3m | elinks | links | lynx | dillo | open | start)
37                 ;; # happy
38         *)
39                 valid_custom_tool "$1" || return 1
40                 ;;
41         esac
42 }
43
44 init_browser_path() {
45         browser_path=$(git config "browser.$1.path")
46         if test -z "$browser_path" &&
47            test "$1" = chromium &&
48            type chromium-browser >/dev/null 2>&1
49         then
50                 browser_path=chromium-browser
51         fi
52         : ${browser_path:="$1"}
53 }
54
55 # check if a given executable is a browser we like
56 valid_browser_executable() {
57         testexe="$1"
58
59         # check the executable name first, trying to follow symlinks if possible
60         if type readlink > /dev/null 2>&1 ; then
61                 basename="$(basename $(readlink -f "$testexe"))"
62         else
63                 basename="$(basename "$testexe")"
64         fi
65         if valid_tool "$basename" ; then
66                 browser="$basename"
67                 browser_path="$testexe"
68                 return 0
69         fi
70
71         # if the linked executable doesn't match a browser name we know about,
72         # look at the version string
73
74         # even though most browsers (and applications, in fact) will show their
75         # name and version on the first line of the --version output, this is
76         # not true in particular for the KDE apps (e.g. konqueror and kfmclient),
77         # which display their name and version on the LAST line. So we cannot
78         # clip the version string at the first line when retrieving it. Rather,
79         # we keep it whole and then limit it when we know what we're dealing with.
80
81         verstring="$("$testexe" --version 2> /dev/null)"
82         browser="$(echo "$verstring" | head -n 1 | cut -f1 -d' ' | tr A-Z a-z)"
83         case "$browser" in
84                 mozilla)
85                         verstring="$(echo "$verstring" | head -n 1)"
86                         browser="$(echo "$verstring" | cut -f2 -d' ' | tr A-Z a-z)"
87                         ;;
88                 google)
89                         verstring="$(echo "$verstring" | head -n 1)"
90                         browser="google-chrome"
91                         ;;
92                 qt:)
93                         # konqueror, kfmclient or other KDE app
94                         verstring="$(echo "$verstring" | tail -n 1)"
95                         browser="$(echo "$verstring" | cut -f1 -d:)"
96                         ;;
97                 *)
98                         verstring="$(echo "$verstring" | head -n 1)"
99                         ;;
100
101         esac
102         if valid_tool "$browser" ; then
103                 browser_path="$i"
104                 return 0
105         fi
106
107         echo >&2 "$testexe (detected as $browser) is not a supported browser, skipping"
108         browser=""
109         return 1
110 }
111
112 while test $# != 0
113 do
114         case "$1" in
115         -b|--browser*|-t|--tool*)
116                 case "$#,$1" in
117                 *,*=*)
118                         browser=`expr "z$1" : 'z-[^=]*=\(.*\)'`
119                         ;;
120                 1,*)
121                         usage ;;
122                 *)
123                         browser="$2"
124                         shift ;;
125                 esac
126                 ;;
127         -c|--config*)
128                 case "$#,$1" in
129                 *,*=*)
130                         conf=`expr "z$1" : 'z-[^=]*=\(.*\)'`
131                         ;;
132                 1,*)
133                         usage ;;
134                 *)
135                         conf="$2"
136                         shift ;;
137                 esac
138                 ;;
139         --)
140                 break
141                 ;;
142         -*)
143                 usage
144                 ;;
145         *)
146                 break
147                 ;;
148         esac
149         shift
150 done
151
152 test $# = 0 && usage
153
154 if test -z "$browser"
155 then
156         for opt in "$conf" "web.browser"
157         do
158                 test -z "$opt" && continue
159                 browser="`git config $opt`"
160                 test -z "$browser" || break
161         done
162         if test -n "$browser" && ! valid_tool "$browser"; then
163                 echo >&2 "git config option $opt set to unknown browser: $browser"
164                 echo >&2 "Resetting to default..."
165                 unset browser
166         fi
167 fi
168
169 # The BROWSER environment variable is a colon-separated list of commands
170 # to (try and) execute to launch the browser. Each entry can contain a %s
171 # placeholder that will be replaced by the URL to be opened.
172 # If an entry contains a %s we run it as-is, without doing any detection, on
173 # the premise that it represents the exact way the user expects the browser to
174 # be called. If the execution fails, we do not bail out, since the
175 # failure might be due to the entry being for a graphical browser and
176 # the GUI not being available, which is the reason why multiple entries
177 # can be specified in BROWSER in the first place.
178 # An entry without a %s is only taken as indication of the preferred
179 # browser, so we proceed with our usual detection logic.
180 if test -z "$browser" -a -n "$BROWSER"; then
181         OLDIFS="$IFS"
182         IFS=:
183         for i in $BROWSER; do
184                 case "$i" in
185                         *sensible-browser*)
186                                 ;; # skip
187                         *%s*)
188                                 IFS="$OLDIFS"
189                                 cmd=$(printf "$i\n" "$*")
190                                 $cmd && exit 0
191                                 ;;
192                         *)
193                                 prog=$(which "$i" 2> /dev/null)
194                                 if test -n "$prog" -a -x "$prog" && valid_browser_executable "$prog" ; then
195                                         break
196                                 fi
197                                 ;;
198                 esac
199         done
200         IFS="$OLDIFS"
201 fi
202
203 # Debian and derivatives use gnome-www-browser, x-www-browser or www-browser to
204 # set the default browser for the system. If the user did not specify a tool and
205 # we detect that one of the *www-browser links to a supported one, we pick it.
206 # Otherwise, we warn the user about them being unsupported and proceed to look
207 # for a supported browser.
208 if test -z "$browser" ; then
209         wwwbrowser="/usr/bin/www-browser"
210         if test -n "$DISPLAY"; then
211                 wwwbrowser="/usr/bin/x-www-browser $wwwbrowser"
212                 if test -n "$GNOME_DESKTOP_SESSION_ID"; then
213                         wwwbrowser="/usr/bin/gnome-www-browser $wwwbrowser"
214                 fi
215         fi
216         for i in $wwwbrowser; do
217                 if test -x $i && valid_browser_executable $i ; then
218                         break
219                 fi
220         done
221 fi
222
223 if test -z "$browser" ; then
224         if test -n "$DISPLAY"; then
225                 browser_candidates="firefox iceweasel google-chrome chrome chromium chromium-browser konqueror opera seamonkey iceape w3m elinks links lynx dillo"
226                 if test "$KDE_FULL_SESSION" = "true"; then
227                         browser_candidates="konqueror $browser_candidates"
228                 fi
229         else
230                 browser_candidates="w3m elinks links lynx"
231         fi
232         # SECURITYSESSIONID indicates an OS X GUI login session
233         if test -n "$SECURITYSESSIONID" \
234                 -o "$TERM_PROGRAM" = "Apple_Terminal" ; then
235                 browser_candidates="open $browser_candidates"
236         fi
237         # /bin/start indicates MinGW
238         if test -x /bin/start; then
239                 browser_candidates="start $browser_candidates"
240         fi
241
242         for i in $browser_candidates; do
243                 init_browser_path $i
244                 if type "$browser_path" > /dev/null 2>&1; then
245                         browser=$i
246                         break
247                 fi
248         done
249         test -z "$browser" && die "No known browser available."
250 else if test -z "$browser_path"; then
251         valid_tool "$browser" || die "Unknown browser '$browser'."
252
253         init_browser_path "$browser"
254
255         if test -z "$browser_cmd" && ! type "$browser_path" > /dev/null 2>&1; then
256                 die "The browser $browser is not available as '$browser_path'."
257         fi
258 fi fi
259
260 case "$browser" in
261 firefox|iceweasel|seamonkey|iceape)
262         # Check version because firefox < 2.0 does not support "-new-tab".
263         test -z "$verstring" && verstring="$($browser_path -version)"
264         vers=$(expr "$verstring" : '.* \([0-9][0-9]*\)\..*')
265         NEWTAB='-new-tab'
266         test "$vers" -lt 2 && NEWTAB=''
267         "$browser_path" $NEWTAB "$@" &
268         ;;
269 google-chrome|chrome|chromium|chromium-browser)
270         # No need to specify newTab. It's default in chromium
271         eval "$browser_path" "$@" &
272         ;;
273 konqueror)
274         case "$(basename "$browser_path")" in
275         konqueror)
276                 # It's simpler to use kfmclient to open a new tab in konqueror.
277                 browser_path="$(echo "$browser_path" | sed -e 's/konqueror$/kfmclient/')"
278                 type "$browser_path" > /dev/null 2>&1 || die "No '$browser_path' found."
279                 eval "$browser_path" newTab "$@"
280                 ;;
281         kfmclient)
282                 eval "$browser_path" newTab "$@"
283                 ;;
284         *)
285                 "$browser_path" "$@" &
286                 ;;
287         esac
288         ;;
289 w3m|elinks|links|lynx|open)
290         eval "$browser_path" "$@"
291         ;;
292 start)
293         exec "$browser_path" '"web-browse"' "$@"
294         ;;
295 opera|dillo)
296         "$browser_path" "$@" &
297         ;;
298 *)
299         if test -n "$browser_cmd"; then
300                 ( eval $browser_cmd "$@" )
301         fi
302         ;;
303 esac