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