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