+//<script type="text/javascript">
+GLib= imports.gi.GLib;
+Gio = imports.gi.Gio;
+
+Roo = imports['Roo.js'].Roo;
+File = imports['File.js'].File;
+console = imports['console.js'].console;
+
+
+imports['Date.js'].load(Date);
+
+
+// these should come from args
+var SRC='/disk2/checkout/gnome2/';
+
+// perhaps we can just do a simple make for building the girs - no make install etc.?
+var UPDATE_SOURCES = false;
+
+
+
+var LOGFILE = "jhbuild-" + (new Date()).format("Y-m-d-H") + '.log';
+
+
+// change src & deleteGirs when you add / remove girs..
+/*
+
+USAGE:
+screen -d -m seed jhbuild.js
+tail /tmp/builder.log
+
+TODO:
+continue - do not trash gir's...
+use this to diff changes when we fix gobject introspection..
+git diff on directories..
+email me the results.
+run the doc tool as well.
+
+
+patching
+--- before jhbuild..
+--- git diff (current to /SRC/package-DATE.diff)
+--- see if we have a patch list
+--- if so: git reset --hard
+--- apply patch..
+--- run jhbuild.
+
+to add:
+avahi + core.
+babl
+dbus
+
+
+sqlite3
+libbonbo
+
+to fix: - see the list of modules commented out.
+
+*/
+
+
+
+var deleteGirs = [
+ 'atk/atk/Atk-1.0.gir',
+ 'clutter/clutter/json/ClutterJson-1.0.gir',
+ 'clutter/clutter/cogl/Cogl-1.0.gir',
+ 'clutter/clutter/Clutter-1.0.gir',
+ 'clutter/clutter/Cogl-1.0.gir',
+ 'clutter/clutter/ClutterJson-1.0.gir',
+ 'epiphany/src/Epiphany-2.29.gir',
+ 'libgda/libgda/Gda-4.0.gir',
+ 'libgda/libgda-ui/Gdaui-4.0.gir',
+ 'libgsf/gsf/Gsf-1.gir',
+ 'gobject-introspection/gir/libxml2-2.0.gir', // needed!
+ 'gobject-introspection/gir/Gio-2.0.gir',
+ 'gobject-introspection/gir/GModule-2.0.gir',
+ 'gobject-introspection/gir/GLib-2.0.gir',
+ 'gobject-introspection/gir/GIRepository-2.0.gir',
+ 'gobject-introspection/gir/GObject-2.0.gir',
+
+ 'gtk+/gdk-pixbuf/GdkPixbuf-2.0.gir',
+ 'gtk+/gtk/Gtk-2.0.gir',
+ 'gtk+/gdk/Gdk-2.0.gir',
+ 'clutter-gtk/clutter-gtk/GtkClutter-0.10.gir',
+ 'gconf/GConf-2.0.gir',
+ 'gtksourceview/gtksourceview/GtkSource-2.0.gir',
+ 'gstreamer/gst/Gst-0.10.gir',
+ 'gstreamer/libs/gst/check/GstCheck-0.10.gir',
+ 'gstreamer/libs/gst/net/GstNet-0.10.gir',
+ 'gstreamer/libs/gst/controller/GstController-0.10.gir',
+ 'gstreamer/libs/gst/base/GstBase-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/video/GstVideo-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/tag/GstTag-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/interfaces/GstInterfaces-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/pbutils/GstPbutils-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/netbuffer/GstNetbuffer-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/riff/GstRiff-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/audio/GstAudio-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/fft/GstFft-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/rtsp/GstRtsp-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/app/GstApp-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/sdp/GstSdp-0.10.gir',
+ 'gst-plugins-base/gst-libs/gst/rtp/GstRtp-0.10.gir',
+
+ 'gssdp/libgssdp/GSSDP-1.0.gir',
+ 'gdome2/libgdome/Gdome-2.0.gir',
+ 'gnome-menus/libmenu/GMenu-2.0.gir',
+
+
+
+ 'pango/pango/PangoFT2-1.0.gir',
+ 'pango/pango/PangoCairo-1.0.gir',
+ 'pango/pango/PangoXft-1.0.gir',
+ 'pango/pango/Pango-1.0.gir',
+ 'PolicyKit/src/polkit/Polkit-1.0.gir',
+ 'unique/unique/Unique-1.0.gir',
+ 'vte/src/Vte-0.gir',
+
+ 'WebKit/WebKit-1.0.gir',
+ //'WebKit/WebKit/gtk/JSCore-1.0.gir', -- not a generated file!
+
+
+];
+
+var all = {
+
+ // package : directory
+ 'atk' : 'atk',
+ 'clutter': 'clutter',
+ 'clutter-gtk' :'clutter-gtk',
+ 'eggdbus' : 'eggdbus',
+ 'glib' : 'glib' ,
+ 'epiphany' : 'epiphany',
+ 'gtk+' : 'gtk+',
+ 'gobject-introspection' : 'gobject-introspection',
+
+ 'gstreamer' : 'gstreamer',
+ 'gst-plugins-base' : 'gst-plugins-base',
+ 'gtksourceview' : 'gtksourceview',
+ 'gnome-menus' : 'gnome-menus',
+ 'gssdp' :'gssdp',
+ 'libgda' :'libgda',
+ 'libgsf' :'libgsf',
+ 'libunique' :'unique',
+ 'libsoup' : 'libsoup',
+ 'pango' : 'pango',
+ 'polkit' : 'PolicyKit',
+ 'vte' : 'vte',
+ 'WebKit' :'WebKit',
+ 'gconf' : 'gconf',
+ //'gupnp', -- needs patch
+ // 'gnome-keyring' -- ndeds patch
+ // gnome-vfs -- needs patch
+ // 'goocanvas' -- needs patch
+ //'libnotify' -- needs patch
+ // 'poppler' ---
+
+};
+
+// we dont use these at present..
+var patches = {
+ 'gconf' : [
+ 'http://bugzilla-attachments.gnome.org/attachment.cgi?id=156459',
+ 'http://bugzilla-attachments.gnome.org/attachment.cgi?id=156457',
+ ],
+ 'gnome-keyring' : [
+ // not valid - against release..
+ //'http://bugzilla-attachments.gnome.org/attachment.cgi?id=145422'
+ ],
+ 'gtksouceview' : [
+ 'http://bugzilla-attachments.gnome.org/attachment.cgi?id=153062',
+ ],
+ 'avahi' : [
+ 'http://www.akbkhome.com/svn/seed/gir/avahi.diff',
+ ]
+};
+/**
+ *
+ * spawnlog:
+ * spawn process, and print/monitor output.
+ *
+ * usage scenarios:
+ * - global log.. -> our global log just indicates what was done and what was the result?
+ * - build log for a specific package?
+ * - return data? -
+ *
+ * @arg string cwd working directory.
+ * @arg array args
+ * @
+ *
+ */
+var streams = { };
+
+function write(fn, str) {
+ if (!str) {
+ return;
+ }
+
+ if (!fn) {
+ return;
+ }
+ console.log(str.replace(/\n/,''));
+
+ if (typeof(streams[fn])=='undefined') {
+ GLib.unlink(fn);
+ var f = Gio.file_new_for_path(String(fn));
+ streams[fn] = new Gio.DataOutputStream({
+ base_stream: f.replace(null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, null)
+ });
+ }
+ streams[fn].put_string(str, null);
+}
+function close(fn) {
+ if (!fn || typeof(streams[fn])=='undefined') {
+ return;
+ }
+ streams[fn].close(null);
+ delete streams[fn];
+}
+
+
+function spawnlog (cwd, s, outfile, errfile) {
+ var ret = { };
+ var retval = { output: '' , error : '', cmd : s.join(' ') , done : false};
+ console.log(retval.cmd);
+ GLib.spawn_async_with_pipes(cwd, s, null,
+ GLib.SpawnFlags.DO_NOT_REAP_CHILD + GLib.SpawnFlags.SEARCH_PATH ,
+ null, null, ret);
+
+ var ctx = GLib.main_loop_new (null, false);
+ var started = false;
+
+ GLib.child_watch_add(GLib.PRIORITY_DEFAULT, ret.child_pid, function(pid, status) {
+ console.log("GOT STATUS:" + status);
+ retval.status = status;
+ retval.done = true;
+ if (started) {
+ console.log("Ending LOOP");
+ GLib.main_loop_quit(ctx);
+ }
+
+ });
+ //console.dump(ret);
+
+ var in_ch = GLib.io_channel_unix_new(ret.standard_input);
+ var out_ch = GLib.io_channel_unix_new(ret.standard_output);
+ var err_ch = GLib.io_channel_unix_new(ret.standard_error);
+
+ function readstr(ch, fn, prop) {
+
+ while (true) {
+
+ var x = new GLib.String();
+
+
+ var cstatus = GLib.io_channel_get_buffer_condition(ch);
+ cstatus = GLib.io_channel_get_flags (ch)
+
+
+ //Seed.print("WAITING INPUT?" + prop+':'+cstatus);
+ //var status = GLib.io_channel_read_line_string (ch, x, null);
+
+
+ var status = GLib.io_channel_read_line_string (ch, x);
+
+ //Seed.print(prop + ":INPUT:" + status);
+
+ switch(status) {
+ case GLib.IOStatus.NORMAL:
+ write(fn, x.str);
+ retval[prop] += x.str;
+ continue
+ case GLib.IOStatus.AGAIN:
+ break;
+ case GLib.IOStatus.ERROR:
+ case GLib.IOStatus.EOF:
+ break;
+
+ }
+ break;
+ }
+ }
+
+
+
+ GLib.io_add_watch(in_ch, GLib.PRIORITY_DEFAULT,
+ GLib.IOCondition.OUT + GLib.IOCondition.IN + GLib.IOCondition.PRI, function()
+ {
+ //Seed.print("GOT INOUT ON IN");
+ readstr(out_ch, outfile, 'output');
+
+ });
+ GLib.io_add_watch(err_ch, GLib.PRIORITY_DEFAULT,
+ GLib.IOCondition.ERR + GLib.IOCondition.IN + GLib.IOCondition.PRI + GLib.IOCondition.OUT,
+ function()
+ {
+ // Seed.print("GOT INOUT ON ERR");
+ readstr(er_ch, errfile, 'error');
+
+ });
+ // let's just write some data...
+ //var x = new GLib.String();
+ //var status = GLib.io_channel_write (out_ch, "\n", 1);
+
+ //while (!retval.done) {
+
+
+ //}
+
+ // do we need this?
+ if (!retval.done) {
+ started = true;
+ console.log("STARTING LOOP");
+ GLib.main_loop_run(ctx, false); // wait fore exit?
+ }
+ readstr(out_ch, outfile, 'output');
+ readstr(err_ch, errfile, 'error');
+
+
+
+
+ close(outfile);
+ close(errfile);
+
+ //GLib.spawn_close_pid(ret.child_pid);
+ return retval;
+
+
+}
+
+
+function log(res) {
+ if (typeof(res) == 'string') {
+ if (!res.length) { // skip blan.
+ return;
+ }
+
+
+ write(SRC + LOGFILE, '[' + (new Date()).format("Y-m-d H:i:s") + '] ' + res);
+ return;
+ }
+ log("CMD:" + res.cmd +"\n");
+ log("RETURN:" + (res.status ? res.status : "OK")+"\n");
+ log(res.output ? "---OUT---\n" + res.output + "\n" : '');
+ log(res.error ? " ---ERROR---\n" + res.error + "\n" : '');
+
+}
+function logresult(res) {
+ log("CMD: " + res.cmd +"\n");
+ log((res.status ? "RETURN: " + res.status : 'BUILD OK') +"\n");
+ if (res.status != 0 ) {
+ log(res.error ? "---ERROR---\n" + res.error + "\n" : '');
+ }
+
+}
+
+var nojhbuild = {
+ gdome : [ 'git', 'clean', 'make' , 'install' ], // fixme..
+
+
+
+}
+
+function main() {
+ // delete old..
+ deleteGirs.map( function(g) {
+ try {
+ console.log("DELETE" + SRC + g);
+ GLib.unlink(SRC+g);
+ } catch(e) {
+ console.log(e);
+ }
+
+ });
+
+
+
+
+ var pkgs = [];
+ var cline = [];
+ for(var i in all) {
+ pkgs.push(i);
+ cline.push(i);
+ }
+ cline.unshift('list');
+ cline.unshift('jhbuild');
+ var order = spawnlog('/tmp', cline).output.split("\n");
+ // push introspection first...!!!
+
+
+ var buildorder = [];
+ for (var i=0; i < order.length; i++) {
+ if (!order[i].length || pkgs.indexOf(order[i]) < 0) {
+ //console.log("SKIP (not related to gir) " + order[i] );
+ log("SKIP (not related to gir) " + order[i] +"\n");
+ continue;
+ }
+
+ // special cases:
+ // just for our reference..
+ spawnlog('/tmp', ['jhbuild','info', order[i]]);
+ // add -a -c for a clean build..
+
+ if (!UPDATE_SOURCES) {
+ // quick rebuild - probably to check introspection change results.
+ log("MAKE INSTALL: " + order[i] + "\n");
+ var res = spawnlog(
+ SRC+all[order[i]], ['bash' , '-c' ,'make install 2>&1'],
+ SRC+all[order[i]]+'/jhbuild.log',
+ SRC+all[order[i]]+'/jhbuild.err'
+ );
+ logresult(res);
+ continue;
+
+ }
+
+
+ // for git.. - do a diff before we start, and store it..
+ // just in case..
+ if (File.exists(SRC+all[order[i]]+'/.git')) {
+
+ var gitres = spawnlog( SRC + all[order[i]], [ 'git', 'diff' ]);
+
+ var fn = false;
+ if (gitres.output.length) {
+ fn = SRC+all[order[i]]+'-' + (new Date()).format('Y-m-d-H') + '.diff';
+ log("DIFF STORED: "+ fn+"\n");
+ write(fn, gitres.output);
+ close(fn);
+ }
+ log("RESET GIT / PULL\n");
+ spawnlog( SRC + all[order[i]], [ 'git', 'reset', '--hard' ]);
+ spawnlog( SRC + all[order[i]], [ 'git', 'pull' ]);
+ if (fn) {
+ log("RE-APPLING DIFF\n");
+ spawnlog( SRC + all[order[i]], [ 'patch', '-p1', '-i', fn ]);
+ }
+ // we should apply patches here..
+
+ }
+
+
+
+ while(true) {
+
+
+ log("BUILDING : " + order[i] + "\n");
+ var res = spawnlog(
+ '/tmp', ['jhbuild', '--no-interact', 'buildone',order[i]],
+ SRC+all[order[i]]+'/jhbuild.log',
+ SRC+all[order[i]]+'/jhbuild.err'
+ );
+ logresult(res);
+ if (res.status == 256 && res.error.match(/The remote end hung up unexpectedly/)) {
+ // try again - git connection failed..
+ continue;
+ }
+ break;
+ }
+
+
+
+
+ }
+ close(SRC + LOGFILE);
+
+
+}
+
+
+main();
+// specials..
+//polkit -> PolicyKit
+//WebKit -> svn
+//gdome -> manual..
+//libxml2 -> last! and must manual..
+
+// refresh build...
+// we can just trash the gir's..
+// usefull for checking changes in introspection..
+// then run make on the whole lot..
+
+
+// special treatment
+//libxml (must be after introspecton)
+
+
+
+
+
+// full build - needs jhbuild really...
+// ideally:
+// -- will not build stuff that's not changed.. (we need to store checkout id's to make this work..)
+// otherwise do a -a -c
+
+
+
+// what this has to do.. (similar to jhbuild...?? why not use it???
+
\ No newline at end of file