Find git executable at run time
[git-darcs-import.git] / tools / cygwin-wrapper.bash
blobeaffd31a0f4811920d9aaf0ce9b0795f2c326423
1 #! /bin/bash
3 DIRNAME=`dirname "${0}"`
4 if [ "${DIRNAME:0:1}" = "/" ] ; then
5 DARCSPACKAGEDIR="${DIRNAME}"
6 else
7 DARCSPACKAGEDIR="${PWD}/${DIRNAME}"
8 fi
10 # If the DARCSPACKAGEDIR assignment above doesn't work for some funny reason,
11 # you could set these variables by hand. Or fix the script to work
12 # automatically and submit a patch.
14 # Should be set to the full Cygwin path to the directory containing the
15 # putty executables.
16 putty_binary_dir="${DARCSPACKAGEDIR}"
17 # Should be set to the full Cygwin path to the directory containing the
18 # Windows binary "darcs.exe".
19 darcs_binary_dir="$putty_binary_dir"
20 # Should be set to the full Cygwin path to the Windows binary
21 # "darcs.exe".
22 darcs_binary="${darcs_binary_dir}/realdarcs.exe"
24 #---------------------------------------------------------------------
25 # Darcs Wrapper for Cygwin
27 # A Bash script that allows Cywin paths on the command line when using
28 # a version of Darcs compiled for Windows. Darcs will still use still
29 # Windows paths internally.
31 #---------------------------------------------------------------------
32 # Usage
34 # Edit this file and set the variables above. Then, rename this
35 # script to "darcs" and put it in your PATH somewhere before the
36 # original binary.
38 # Darcs needs to launch itself for some operations and so the original
39 # binary needs to be in your Windows PATH. Do not rename it.
41 #---------------------------------------------------------------------
42 # Known Issues
44 # This script is just a stopgap measure. Things don't work perfectly.
45 # We really need a Cygwin build of Darcs.
47 # No path conversion is performed on:
48 # - Any preferences set with "setpref"
49 # - The "COMMAND" argument to "darcs trackdown"
51 # When Darcs launches external programs, it uses a Windows system call
52 # to do so. This means you may not be able to run "hash bang" scripts
53 # directly. For example, to run the Bash script "myscript", you'll
54 # have to tell Darcs to run "bash myscript".
56 # --------------------------------------------------------------------
59 PATH="$putty_binary_dir:$darcs_binary_dir:${PATH}"
61 debug=false
63 cmd="$1"
65 # Print each argument to stderr on a separate line. Then exit.
66 function die() {
67 local line
68 for line in "$@"; do
69 echo "$line" > /dev/stderr
70 done
71 exit 2
74 # Make sure 'darcs_binary_dir' is set.
75 if [ ! -d "$darcs_binary_dir" ]; then
76 die "Please edit this script and set the 'darcs_binary_dir' variable" \
77 "to refer to a valid directory." \
78 " script path = '$0'" \
79 " darcs_binary_dir = '$darcs_binary_dir'"
82 # Special case for when the first argument is an option.
83 if expr match "$cmd" '-' > /dev/null; then
84 if $debug; then
85 # echo "SIMPLE CASE:"
86 for arg in "$@"; do
87 echo " arg = '$arg'"
88 done
89 else
90 # echo about to exec -a darcs "$darcs_binary" "$@"
91 exec -a darcs "$darcs_binary" "$@"
95 # Shift off the darcs command name
96 shift
98 function is_opaque_opt() {
99 local opt
100 for opt in "${opaque_binary_opts[@]}"; do
101 if [ "$opt" == "$1" ]; then
102 return 0
104 done
105 return 1
108 function is_file_opt() {
109 local opt
110 for opt in "${file_binary_opts[@]}"; do
111 if [ "$opt" == "$1" ]; then
112 return 0
114 done
115 return 1
118 # Options are not dealt with in a command-specific way. AFAIK, Darcs
119 # doesn't use the same option in two different ways, so we should be
120 # fine.
122 # List of "opaque" binary options. These are options where we don't
123 # treat the option argument like a file.
124 declare -a opaque_binary_opts=( \
125 '--repo-name' \
126 '--to-match' '--to-patch' '--to-tag' \
127 '--from-match' '--from-patch' '--from-tag' \
128 '-t' '--tag' '--tags' '--tag-name' \
129 '-p' '--patch' '--patches' \
130 '-m' '--patch-name' \
131 '--matches' '--match' \
132 '--token-chars' \
133 '-A' '--author' '--from' '--to' '--cc' \
134 '--sign-as' '--creator-hash' \
135 '--last' '--diff-opts' \
136 '-d' '--dist-name' \
137 '--log-file' \
138 '--apply-as' \
141 # List of binary options that take file arguments that need to be converted.
142 declare -a file_binary_opts=( \
143 '--repodir' '--repo' '--sibling' \
144 '--context' \
145 '--logfile' '-o' '--output' \
146 '--external-merge' \
147 '--sign-ssl' '--verify' '--verify-ssl' \
150 # --------------------------------------------------------------------
151 # The three command categories. We only use the first one, but the
152 # others are listed to make sure we've covered everything. Luckily,
153 # there aren't any commands that have some args that need to be
154 # converted and some that don't.
156 # Commands whose arguments are file paths that need to be translated.
157 cmds_convert_nonoption_args='|get|put|pull|push|send|apply'
159 # Commands who's arguments should be left alone. File paths that
160 # refer to files in the repo should NOT be converted because they
161 # are relative paths, which Darcs will handle just fine. Cygwin
162 # sometimes makes them absolute paths, which confuses Darcs.
163 #cmds_no_convert_nonoption_paths='|add|remove|mv|replace|record|whatsnew|changes|setpref|trackdown|amend-record|revert|diff|annotate'
165 # Commands that don't accept non-option arguments
166 #cmds_no_nonoption_args='|initialize|tag|check|optimize|rollback|unrecord|unpull|resolve|dist|repair'
168 # See if we need to convert the non-option args for the current
169 # command. This matches some prefix of one of the commands in the
170 # list. The match may not be unambiguous, we can rely on Darcs to
171 # deal with that correctly.
172 if expr match "$cmds_convert_nonoption_args" ".*|$cmd" > /dev/null; then
173 convert_nonoption_args=true
174 else
175 convert_nonoption_args=false
178 function convert_path() {
179 # echo "converting path ${*} ..." >> /tmp/log
180 if expr match "$1" '[-@._A-Za-z0-9]*:' > /dev/null; then
181 # Some sort of URL or remote ssh pathname ("xxx:/")
182 echo "$1"
183 # echo "converting path ${*} ... to ${1}" >> /tmp/log
184 elif [ "$1" == '.' ]; then
185 # Compensate for stupid 'cygpath' behavior.
186 echo '.'
187 # echo "converting path ${*} ... to ." >> /tmp/log
188 else
189 cygpath -wl -- "$1"
190 # echo "converting path ${*} ... to `cygpath -wl -- ${1}`" >> /tmp/log
194 declare -a params=("$cmd")
196 num_nonoption_args=0
198 while [ $# -gt 0 ]; do
199 arg=$1
200 shift
201 if expr match "$arg" '-' > /dev/null; then
202 # It's an option. Check to see if it's an opaque binary option.
204 if expr match "$arg" '.*=' > /dev/null; then
205 # The option has an '=' in it.
206 opt=`expr match "$arg" '\([^=]*\)'`
207 opt_arg=`expr match "$arg" '[^=]*=\(.*\)'`
208 if is_opaque_opt "$opt"; then
209 true;
210 elif is_file_opt "$opt"; then
211 opt_arg=`convert_path "$opt_arg"`
212 else
213 die "darcs-wrapper: I don't think '$opt' accepts an argument." \
214 "[ If it does, then there is a bug in the wrapper script. ]"
216 params[${#params[*]}]="$opt=$opt_arg"
218 else
219 # The option doesn't have an '='
220 opt="$arg"
221 if is_opaque_opt "$opt"; then
222 if [ $# -eq 0 ]; then
223 die "darcs-wrapper: I think '$arg' requires an argument." \
224 "[ If it doesn't, then there is a bug in the wrapper script. ]"
226 opt_arg="$1"
227 shift
228 params[${#params[*]}]="$opt"
229 params[${#params[*]}]="$opt_arg"
230 elif is_file_opt "$opt"; then
231 if [ $# -eq 0 ]; then
232 die "darcs-wrapper: I think '$arg' requires an argument." \
233 "[ If it doesn't, then there is a bug in the wrapper script. ]"
235 opt_arg=`convert_path "$1"`
236 shift
237 params[${#params[*]}]="$opt"
238 params[${#params[*]}]="$opt_arg"
239 else
240 params[${#params[*]}]="$opt"
244 else
245 if $convert_nonoption_args; then
246 arg=`convert_path "$arg"`
248 params[${#params[*]}]="$arg"
249 (( num_nonoption_args += 1 ))
251 done
253 # DEBUG
254 if $debug; then
255 echo "ARGS:"
256 for arg in "${params[@]}"; do
257 echo " arg = '$arg'"
258 done
259 else
260 # echo about to exec -a darcs "$darcs_binary" "${params[@]}"
261 exec -a darcs "$darcs_binary" "${params[@]}"