jhbuild.js
[gnome.introspection-doc-generator] / jhbuild.js
1 //<script type="text/javascript">
2
3
4 /** NOT CURRENTLY BEING WORKED ON !!! */
5
6
7 GLib= imports.gi.GLib;
8 Gio = imports.gi.Gio;
9
10
11 File = imports.File.File;
12 console = imports.console.console;
13
14  
15 Date = imports.Date.Date;
16
17  
18
19 // these should come from args
20 var SRC='/disk2/checkout/gnome2/';
21
22 // perhaps we can just do a simple make for building the girs - no make install etc.?
23 var UPDATE_SOURCES = false;
24
25
26
27 var LOGFILE = "jhbuild-" + (new Date()).format("Y-m-d-H") + '.log';
28
29
30 // change src & deleteGirs when you add / remove girs..
31 /*
32
33 USAGE:
34 screen -d -m seed jhbuild.js
35 tail /tmp/builder.log
36
37 TODO:
38 continue - do not trash gir's...
39 use this to diff changes when we fix gobject introspection..
40 git diff on directories..
41 email me the results.
42 run the doc tool as well.
43
44
45 patching
46 --- before jhbuild..
47 --- git diff (current to /SRC/package-DATE.diff)
48 --- see if we have a patch list
49 --- if so: git reset --hard
50 ---    apply patch..
51 --- run jhbuild.
52
53 to add:
54 avahi + core.
55 babl
56 dbus
57  
58
59 sqlite3
60 libbonbo
61
62 to fix: - see the list of modules commented out.
63
64 */
65
66
67
68 var deleteGirs = [
69         'atk/atk/Atk-1.0.gir',
70     'clutter/clutter/json/ClutterJson-1.0.gir',
71         'clutter/clutter/cogl/Cogl-1.0.gir',
72         'clutter/clutter/Clutter-1.0.gir',
73         'clutter/clutter/Cogl-1.0.gir',
74         'clutter/clutter/ClutterJson-1.0.gir',
75     'epiphany/src/Epiphany-2.29.gir',
76     'libgda/libgda/Gda-4.0.gir',
77         'libgda/libgda-ui/Gdaui-4.0.gir',
78     'libgsf/gsf/Gsf-1.gir',
79     'gobject-introspection/gir/libxml2-2.0.gir', // needed!
80         'gobject-introspection/gir/Gio-2.0.gir',
81         'gobject-introspection/gir/GModule-2.0.gir',
82         'gobject-introspection/gir/GLib-2.0.gir',
83         'gobject-introspection/gir/GIRepository-2.0.gir',
84         'gobject-introspection/gir/GObject-2.0.gir',
85         
86         'gtk+/gdk-pixbuf/GdkPixbuf-2.0.gir',
87         'gtk+/gtk/Gtk-2.0.gir',
88         'gtk+/gdk/Gdk-2.0.gir',
89     'clutter-gtk/clutter-gtk/GtkClutter-0.10.gir',
90     'gconf/GConf-2.0.gir',
91     'gtksourceview/gtksourceview/GtkSource-2.0.gir',
92         'gstreamer/gst/Gst-0.10.gir',
93         'gstreamer/libs/gst/check/GstCheck-0.10.gir',
94         'gstreamer/libs/gst/net/GstNet-0.10.gir',
95         'gstreamer/libs/gst/controller/GstController-0.10.gir',
96         'gstreamer/libs/gst/base/GstBase-0.10.gir',
97     'gst-plugins-base/gst-libs/gst/video/GstVideo-0.10.gir',
98         'gst-plugins-base/gst-libs/gst/tag/GstTag-0.10.gir',
99         'gst-plugins-base/gst-libs/gst/interfaces/GstInterfaces-0.10.gir',
100         'gst-plugins-base/gst-libs/gst/pbutils/GstPbutils-0.10.gir',
101         'gst-plugins-base/gst-libs/gst/netbuffer/GstNetbuffer-0.10.gir',
102         'gst-plugins-base/gst-libs/gst/riff/GstRiff-0.10.gir',
103         'gst-plugins-base/gst-libs/gst/audio/GstAudio-0.10.gir',
104         'gst-plugins-base/gst-libs/gst/fft/GstFft-0.10.gir',
105         'gst-plugins-base/gst-libs/gst/rtsp/GstRtsp-0.10.gir',
106         'gst-plugins-base/gst-libs/gst/app/GstApp-0.10.gir',
107         'gst-plugins-base/gst-libs/gst/sdp/GstSdp-0.10.gir',
108         'gst-plugins-base/gst-libs/gst/rtp/GstRtp-0.10.gir',
109
110     'gssdp/libgssdp/GSSDP-1.0.gir',
111         'gdome2/libgdome/Gdome-2.0.gir',
112     'gnome-menus/libmenu/GMenu-2.0.gir',
113         
114         
115     
116         'pango/pango/PangoFT2-1.0.gir',
117         'pango/pango/PangoCairo-1.0.gir',
118         'pango/pango/PangoXft-1.0.gir',
119         'pango/pango/Pango-1.0.gir',
120         'PolicyKit/src/polkit/Polkit-1.0.gir',    
121         'unique/unique/Unique-1.0.gir',
122     'vte/src/Vte-0.gir',
123         
124         'WebKit/WebKit-1.0.gir',
125         //'WebKit/WebKit/gtk/JSCore-1.0.gir', -- not a generated file!
126         
127
128 ];
129
130 var all = {
131     
132     // package : directory
133     'atk' : 'atk',
134     'clutter': 'clutter', 
135         'clutter-gtk' :'clutter-gtk', 
136     'eggdbus' : 'eggdbus',
137         'glib' : 'glib' ,   
138         'epiphany' : 'epiphany',
139         'gtk+' : 'gtk+',
140         'gobject-introspection' : 'gobject-introspection',
141          
142         'gstreamer' : 'gstreamer',
143         'gst-plugins-base' : 'gst-plugins-base',
144         'gtksourceview' : 'gtksourceview',
145     'gnome-menus' :     'gnome-menus',
146     'gssdp' :'gssdp',
147         'libgda'  :'libgda',
148         'libgsf' :'libgsf',
149         'libunique' :'unique', 
150     'libsoup' : 'libsoup',
151         'pango' : 'pango',
152     'polkit' : 'PolicyKit', 
153         'vte' : 'vte',
154         'WebKit' :'WebKit',
155     'gconf' : 'gconf',
156     //'gupnp', -- needs patch
157         // 'gnome-keyring' -- ndeds patch
158     // gnome-vfs -- needs patch
159     // 'goocanvas' -- needs patch
160     //'libnotify' -- needs patch
161     // 'poppler' --- 
162     
163 };
164
165 // we dont use these at present..
166 var patches = {
167     'gconf' : [
168        'http://bugzilla-attachments.gnome.org/attachment.cgi?id=156459',
169        'http://bugzilla-attachments.gnome.org/attachment.cgi?id=156457',
170     ],
171     'gnome-keyring' : [
172         // not valid - against release..
173         //'http://bugzilla-attachments.gnome.org/attachment.cgi?id=145422'
174     ],
175     'gtksouceview' : [
176         'http://bugzilla-attachments.gnome.org/attachment.cgi?id=153062',
177     ],
178     'avahi' : [
179        'http://www.akbkhome.com/svn/seed/gir/avahi.diff',
180     ]
181 };
182 /**
183  * 
184  * spawnlog:
185  * spawn process, and print/monitor output.
186  * 
187  * usage scenarios:
188  *  - global log.. -> our global log just indicates what was done and what was the result?
189  *  - build log for a specific package?
190  *  - return data? - 
191  * 
192  * @arg string cwd working directory.
193  * @arg array  args 
194  * @
195  * 
196  */
197 var streams  = { };
198   
199 function  write(fn, str) {
200     if (!str) {
201         return;
202     }
203     
204     if (!fn) {
205         return;
206     }
207     console.log(str.replace(/\n/,''));
208     
209     if (typeof(streams[fn])=='undefined') {
210         GLib.unlink(fn);
211         var f = Gio.file_new_for_path(String(fn));
212         streams[fn] = new Gio.DataOutputStream({
213                 base_stream: f.replace(null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, null)
214             });
215     }
216     streams[fn].put_string(str, null);
217 }
218 function  close(fn) {
219     if (!fn || typeof(streams[fn])=='undefined') {
220         return;
221     }
222     streams[fn].close(null);
223     delete streams[fn];
224 }
225
226
227 function spawnlog (cwd, s, outfile, errfile) {
228     var ret = { };
229     var retval =  { output: '' , error : '', cmd : s.join(' ') , done : false};
230     console.log(retval.cmd);
231     GLib.spawn_async_with_pipes(cwd, s, null, 
232         GLib.SpawnFlags.DO_NOT_REAP_CHILD + GLib.SpawnFlags.SEARCH_PATH , 
233         null, null, ret);
234         
235     var ctx = GLib.main_loop_new (null, false);
236     var started = false;
237     
238     GLib.child_watch_add(GLib.PRIORITY_DEFAULT, ret.child_pid, function(pid, status) {
239         console.log("GOT STATUS:" + status);
240         retval.status = status;
241         retval.done = true;
242         if (started) {
243             console.log("Ending LOOP");
244             GLib.main_loop_quit(ctx);
245         }
246         
247     });
248    //console.dump(ret);
249
250     var in_ch = GLib.io_channel_unix_new(ret.standard_input);
251     var out_ch = GLib.io_channel_unix_new(ret.standard_output);
252     var err_ch = GLib.io_channel_unix_new(ret.standard_error);
253     
254     function readstr(ch, fn, prop) {
255         
256         while (true) {
257             
258             var x = new GLib.String();
259             
260             
261             var cstatus = GLib.io_channel_get_buffer_condition(ch);
262             cstatus = GLib.io_channel_get_flags (ch)
263             
264
265             //Seed.print("WAITING INPUT?" + prop+':'+cstatus);
266             //var status = GLib.io_channel_read_line_string (ch, x, null);
267             
268                
269             var status = GLib.io_channel_read_line_string (ch, x);
270             
271             //Seed.print(prop + ":INPUT:" + status);
272         
273             switch(status) {
274                 case GLib.IOStatus.NORMAL:
275                     write(fn, x.str);
276                     retval[prop] += x.str;
277                    continue
278                 case GLib.IOStatus.AGAIN:   
279                     break;
280                 case GLib.IOStatus.ERROR:    
281                 case GLib.IOStatus.EOF:   
282                    break;
283                 
284             }
285             break;
286         }
287     }
288     
289     
290     
291     GLib.io_add_watch(in_ch, GLib.PRIORITY_DEFAULT, 
292         GLib.IOCondition.OUT + GLib.IOCondition.IN  + GLib.IOCondition.PRI, function()
293     {
294         //Seed.print("GOT INOUT ON IN");
295         readstr(out_ch, outfile, 'output');
296         
297     });
298     GLib.io_add_watch(err_ch, GLib.PRIORITY_DEFAULT, 
299         GLib.IOCondition.ERR + GLib.IOCondition.IN + GLib.IOCondition.PRI + GLib.IOCondition.OUT, 
300         function()
301     {
302         // Seed.print("GOT INOUT ON ERR");
303          readstr(er_ch, errfile, 'error');
304          
305     });
306     // let's just write some data... 
307     //var x = new GLib.String();
308     //var status = GLib.io_channel_write (out_ch, "\n", 1);
309     
310     //while (!retval.done) {
311             
312      
313     //}
314  
315     // do we need this?
316     if (!retval.done) {
317         started = true;
318         console.log("STARTING LOOP");
319         GLib.main_loop_run(ctx, false); // wait fore exit?
320     }
321     readstr(out_ch, outfile, 'output');
322     readstr(err_ch, errfile, 'error');
323      
324     
325     
326     
327     close(outfile);
328     close(errfile);
329     
330     //GLib.spawn_close_pid(ret.child_pid);
331     return retval;
332     
333
334 }
335   
336
337 function log(res) {
338     if (typeof(res) == 'string') {
339         if (!res.length) { // skip blan.
340             return;
341         }
342         
343         
344         write(SRC + LOGFILE, '[' + (new Date()).format("Y-m-d H:i:s") + '] ' + res);
345         return;
346     }
347     log("CMD:" + res.cmd +"\n");
348     log("RETURN:" + (res.status ? res.status : "OK")+"\n");
349     log(res.output ? "---OUT---\n" + res.output + "\n" : '');
350     log(res.error ? " ---ERROR---\n" + res.error + "\n" : '');
351    
352 }
353 function logresult(res) {
354    log("CMD: " + res.cmd +"\n");
355    log((res.status ? "RETURN: " + res.status : 'BUILD OK') +"\n");
356     if (res.status != 0 ) {
357        log(res.error ? "---ERROR---\n" + res.error + "\n" : '');
358     }
359      
360 }
361
362 var nojhbuild = {
363         gdome  : [ 'git', 'clean', 'make' , 'install' ], // fixme..
364          
365     
366     
367 }
368
369 function main() {
370         // delete old..
371     deleteGirs.map( function(g) {
372         try {
373             console.log("DELETE" + SRC + g);
374             GLib.unlink(SRC+g);
375         } catch(e) {
376             console.log(e);
377         }
378         
379     });
380
381     
382     
383     
384     var pkgs = [];
385     var cline = [];
386     for(var i in all) {
387         pkgs.push(i);
388         cline.push(i);
389     }
390     cline.unshift('list');
391     cline.unshift('jhbuild');
392     var order = spawnlog('/tmp', cline).output.split("\n");
393     // push introspection first...!!!
394     
395  
396     var buildorder = [];
397     for (var i=0; i < order.length; i++) {
398         if (!order[i].length || pkgs.indexOf(order[i]) < 0) {
399             //console.log("SKIP (not related to gir) " + order[i] );
400             log("SKIP (not related to gir) " + order[i] +"\n");
401             continue;    
402         }
403         
404         // special cases:
405         // just for our reference..
406         spawnlog('/tmp', ['jhbuild','info', order[i]]);
407         // add -a -c for a clean build..
408         
409         if (!UPDATE_SOURCES) {
410             // quick rebuild - probably to check introspection change results.
411             log("MAKE INSTALL: " + order[i] + "\n");
412             var res = spawnlog(
413                     SRC+all[order[i]], ['bash' , '-c' ,'make install 2>&1'],
414                     SRC+all[order[i]]+'/jhbuild.log', 
415                     SRC+all[order[i]]+'/jhbuild.err'
416             );
417             logresult(res); 
418             continue;
419             
420         }
421         
422         
423         // for git.. - do a diff before we start, and store it..
424         // just in case..
425         if (File.exists(SRC+all[order[i]]+'/.git')) {
426              
427             var gitres = spawnlog( SRC + all[order[i]], [ 'git', 'diff' ]);
428             
429             var fn = false;
430             if (gitres.output.length) {
431                 fn = SRC+all[order[i]]+'-' + (new Date()).format('Y-m-d-H') + '.diff';
432                 log("DIFF STORED: "+ fn+"\n");
433                 write(fn, gitres.output);
434                 close(fn);
435             }
436             log("RESET GIT / PULL\n");
437             spawnlog( SRC + all[order[i]], [ 'git', 'reset', '--hard' ]);
438             spawnlog( SRC + all[order[i]], [ 'git', 'pull' ]);
439             if (fn) {
440                 log("RE-APPLING DIFF\n");
441                 spawnlog( SRC + all[order[i]], [ 'patch', '-p1', '-i',  fn ]);
442             }
443             // we should apply patches here..
444             
445         }
446         
447         
448         
449         while(true) {
450             
451                
452             log("BUILDING : " + order[i] + "\n");
453             var res = spawnlog(
454                     '/tmp', ['jhbuild', '--no-interact', 'buildone',order[i]],
455                     SRC+all[order[i]]+'/jhbuild.log', 
456                     SRC+all[order[i]]+'/jhbuild.err'
457             );
458             logresult(res);
459             if (res.status == 256 && res.error.match(/The remote end hung up unexpectedly/)) {
460                 // try again - git connection failed..
461                 continue;
462             }
463             break;
464         }
465        
466    
467         
468         
469     }
470     close(SRC + LOGFILE);
471         
472         
473 }
474
475  
476 main();
477 // specials..
478 //polkit  -> PolicyKit
479 //WebKit -> svn 
480 //gdome -> manual..
481 //libxml2 -> last! and must manual..
482
483 // refresh build...
484 // we can just trash the gir's..
485 // usefull for checking changes in introspection..
486 // then run make on the whole lot..
487
488
489 // special treatment
490 //libxml (must be after introspecton)
491
492
493
494
495
496 // full build - needs jhbuild really...
497 // ideally:
498 // -- will not build stuff that's not changed.. (we need to store checkout id's to make this work..)
499 // otherwise do a -a -c 
500
501
502
503 // what this has to do.. (similar to jhbuild...?? why not use it???
504