]> git.donarmstrong.com Git - lilypond.git/blob - scripts/auxiliar/lilycontrib.tcl
Add --whitespace=fix to scripts/auxiliar/lilycontrib.tcl
[lilypond.git] / scripts / auxiliar / lilycontrib.tcl
1 #!/usr/bin/wish
2
3 # GUI interface for common LilyPond git repository commands
4 # Copyright 2009 by Johannes Schindelin and Carl Sorensen
5 #
6
7 set version 0.57
8
9 # set to 1 to set up for translation, to 0 for other
10 set translator 0
11
12 if {$translator == 1} {
13         set windowTitle \
14           "LilyPond Translator's Git Interface version $version"
15         set updateButtonText "1. Update translation"
16         set initializeButtonText "1. Get translation"
17         set originHead "lilypond/translation"
18         set rebase 0
19 } else {
20         set windowTitle \
21           "LilyPond Contributor's Git Interface version $version"
22         set updateButtonText "1. Update source"
23         set initializeButtonText "1. Get source"
24         set originHead "master"
25         set rebase 1
26 }
27
28 package require Tk
29
30 # Helper functions
31
32 set lily_dir $env(HOME)/lilypond
33 if {[file exists $lily_dir]} {
34         cd $lily_dir
35 }
36
37 set abort_dir "./aborted_edits"
38
39 proc write_to_output {s} {
40         .output.text insert insert $s
41         .output.text see end
42 }
43
44 proc write_file_to_output {f} {
45         if {[eof $f]} {
46                 global git_command
47                 fconfigure $f -blocking true
48                 if {[catch {close $f} err]} {
49                         tk_messageBox -type ok -message \
50                           "Command returned an error: $err\n\nCheck output text for details"
51                 }
52                 unset git_command
53         } else {
54                 write_to_output [read $f 24]
55         }
56 }
57
58 proc git {args} {
59         global lily_dir git_command
60         set git_command [linsert $args 0 "|git" "--git-dir=$lily_dir/.git"]
61         set git_command "$git_command 2>@1"
62         .output.text insert end "$git_command\n"
63         set git [open $git_command r]
64         fconfigure $git -blocking false
65         fileevent $git readable [list write_file_to_output $git]
66         vwait git_command
67 }
68
69 proc config {args} {
70         global lily_dir
71         set p [open [linsert $args 0 "|git" --git-dir=$lily_dir/.git config] r]
72         set result [regsub "\n\$" [read $p] ""]
73         if {[catch {close $p} err]} {
74                 tk_messageBox -type ok -message "config failed: $err"
75         }
76         return $result
77 }
78
79 proc config_quiet {args} {
80         global lily_dir
81         set p [open [linsert $args 0 "|git" --git-dir=$lily_dir/.git config] r]
82         set result [regsub "\n\$" [read $p] ""]
83         if {[catch {close $p} err]} {
84                 set result ""
85         }
86         return $result
87 }
88
89 proc update_lilypond_rebase {} {
90   update_lilypond 1
91 }
92
93 proc commit {} {
94   global commit_message
95   global commit_canceled
96   set commit_canceled 0
97   get_commit_message
98   tkwait visibility .commitMessage
99   tkwait window .commitMessage
100   if {$commit_canceled != 1} {
101     if {$commit_message == ""} {
102       tk_messageBox -message "You must enter a commit message!" \
103       -type ok -icon error
104     } else {
105       git commit -a -m $commit_message
106       git rebase --whitespace=fix HEAD^
107     set commit_message ""
108     }
109   }
110 }
111
112 # This won't work, because --amend needs an editor
113 #  lilyconfig users are on their own.
114 proc commit_amend {} {
115   git commit -a --amend
116   git rebase --whitespace=fix HEAD^
117 }
118
119 proc update_lilypond_norebase {} {
120   update_lilypond 0
121 }
122
123 proc update_lilypond_with_rebase {} {
124   global rebase
125   update_lilypond $rebase
126 }
127
128 proc update_lilypond {rebase} {
129         global lily_dir
130         global originHead
131         . config -cursor watch
132         if {![file exists $lily_dir]} {
133                 write_to_output "Cloning LilyPond (this can take some time) ...\n"
134                 file mkdir $lily_dir
135                 cd $lily_dir
136                 git init
137                 git config core.bare false
138                 git remote add -t $originHead \
139                         origin git://git.sv.gnu.org/lilypond.git
140                 git fetch --depth 1
141                 git reset --hard origin/$originHead
142                 git config branch.$originHead.remote origin
143                 git config branch.$originHead.merge refs/heads/$originHead
144                 .buttons.commit configure -state normal
145                 .buttons.update configure -text buttonUpdateText
146                 .buttons.patch configure -state normal
147                 .buttons.panic configure -state normal
148                 toggle_rebase
149         } else {
150                 write_to_output "Updating LilyPond...\n"
151                 git fetch origin
152                 if {$rebase} {
153                         git rebase origin/$originHead
154                 } else {
155                         git merge origin/$originHead
156                 }
157         }
158         write_to_output "Done.\n"
159         . config -cursor ""
160 }
161
162 proc patch_from_origin {} {
163   global rebase
164   make_patch_from_origin $rebase
165   if {![llength [glob -nocomplain 0*.patch]]} {
166         tk_messageBox -type ok -message \
167                 "No patches created; did you make a local commit?"
168   }
169 }
170
171 proc make_patch_from_origin {rebase} {
172   global lily_dir
173   global originHead
174   . config -cursor watch
175   update_lilypond $rebase
176   write_to_output "Creating patch...\n"
177   git format-patch origin/$originHead
178   write_to_output "Done.\n"
179   . config -cursor ""
180 }
181
182 proc abort_changes {} {
183   global abort_dir
184   global originHead
185   set answer [tk_messageBox -type okcancel \
186                -message "This will copy all changed files to $abort_dir and reset the repository." \
187                -default cancel]
188   switch -- $answer {
189     ok {
190       write_to_output "abort_dir: $abort_dir \n"
191       if {![file exists $abort_dir]} {
192         set return_code [exec mkdir $abort_dir]
193       }
194       set return_code [catch {exec git diff origin/$originHead} gitdiff]
195       set return_code [regexp {diff --git a/(\S*)} $gitdiff match modified_file]
196       while {$return_code != 0} {
197         write_to_output "Copying $modified_file to $abort_dir.\n"
198         set return_code [catch {exec cp $modified_file $abort_dir} result]
199         set return_code [regsub {diff --git a/(\S*)} $gitdiff "" gitdiff]
200         set return_code [regexp {diff --git a/(\S*)} $gitdiff match modified_file]
201       }
202       set return_code [git reset --hard origin/$originHead]
203       write_to_output "Repository reset. \n"
204     }
205   }
206 }
207
208 proc toggle_rebase {} {
209         global rebase
210         global lily_dir
211         global originHead
212         global updateButtonText
213         global initializeButtonText
214         if {[file exists $lily_dir]} {
215           config --bool branch.$originHead.rebase $rebase
216           .buttons.update configure -text $updateButtonText
217         } else {
218           .buttons.update configure -text $initializeButtonText
219         }
220 }
221
222 proc clear_rebase {} {
223   global rebase
224   set rebase 0
225   toggle_rebase
226 }
227
228 proc set_rebase {} {
229   global rebase
230   set rebase 1
231   toggle_rebase
232 }
233
234 proc commitMessageOK {} {
235   global commit_message
236   set commit_message [.commitMessage.commit_message get 1.0 end]
237   destroy .commitMessage
238 }
239
240 proc commitMessageCancel {} {
241   global commit_message
242   global commit_canceled
243   set commit_message ""
244   set commit_canceled 1
245   destroy .commitMessage
246 }
247
248
249 # Commit message input window
250 proc get_commit_message {} {
251   global commit_message
252   toplevel .commitMessage
253   text   .commitMessage.commit_message \
254             -width 60  -height 10 -relief solid -border 2
255   frame .commitMessage.leftFrame
256   label .commitMessage.leftFrame.1 -text "Enter commit message:"
257   button .commitMessage.leftFrame.ok \
258            -text OK -default active -command commitMessageOK
259   button .commitMessage.leftFrame.cancel -text Cancel -default active \
260           -command commitMessageCancel
261   wm withdraw .commitMessage
262   wm title .commitMessage "Git Commit Message"
263
264   pack .commitMessage.leftFrame.1
265   pack .commitMessage.leftFrame.ok
266   pack .commitMessage.leftFrame.cancel
267
268   pack .commitMessage.leftFrame -side left
269   pack .commitMessage.commit_message -side left
270
271   wm transient .commitMessage .
272   wm deiconify .commitMessage
273 }
274
275
276 # GUI
277
278 wm title . $windowTitle
279
280 # Buttons
281
282 panedwindow .buttons
283 button .buttons.commit -text "2. Make local commit" -command commit
284 button .buttons.update -text $updateButtonText \
285           -command update_lilypond_with_rebase
286 toggle_rebase
287 button .buttons.patch -text "3. Make patch set" \
288           -command patch_from_origin
289 button .buttons.panic -text "Abort changes -- Reset to origin" \
290           -command abort_changes -fg Blue -bg Red
291 label   .buttons.spacer -text "                         "
292 if {![file exists $lily_dir]} {
293         .buttons.update configure \
294             -text $initializeButtonText
295         .buttons.commit configure -state disabled
296         .buttons.patch configure -state disabled
297         .buttons.panic configure -state disabled
298 }
299
300 #  Operating buttons
301
302 pack .buttons.update -side left
303 pack .buttons.commit -side left
304 pack .buttons.patch -side left
305 pack .buttons.spacer -side left
306 pack .buttons.panic -side left
307
308
309 # Output text box
310
311 panedwindow .output
312 label .output.label -text "Command output:"
313 text .output.text -width 80 -height 15 \
314         -xscrollcommand [list .output.horizontal set] \
315         -yscrollcommand [list .output.vertical set] \
316         -relief solid -border 2
317 scrollbar .output.horizontal -orient h -command [list .output.text xview]
318 scrollbar .output.vertical -orient v -command [list .output.text yview]
319 pack .output.label -side left
320 pack .output.horizontal -side bottom -fill x
321 pack .output.vertical -side right -fill y
322 pack .output.text -expand true -anchor nw -fill both
323
324 pack .buttons
325 pack .output
326
327 #grid .buttons -row 2 -column 1
328 #grid .output -row 3 -column 1 -sticky "w"