From 05d6e3244aaf885196155fca7b2c6795be874782 Mon Sep 17 00:00:00 2001 From: Alan Knowles Date: Tue, 20 Sep 2011 22:38:41 +0800 Subject: [PATCH] Move monitor implementation code out of bootstap code. --- GitMonitor.js | 379 ++++++++++++++++++++++++++++++++++++++++++++++++++ gitlive.js | 302 +++------------------------------------- 2 files changed, 395 insertions(+), 286 deletions(-) create mode 100644 GitMonitor.js diff --git a/GitMonitor.js b/GitMonitor.js new file mode 100644 index 00000000..5ab6e51e --- /dev/null +++ b/GitMonitor.js @@ -0,0 +1,379 @@ + +var Gio = imports.gi.Gio; +var Gtk = imports.gi.Gtk; +var Notify = imports.gi.Notify; +var GLib = imports.gi.GLib; + +var Spawn = imports.Spawn; +var StatusIcon = imports.StatusIcon.StatusIcon; +var Monitor = imports.Monitor.Monitor; + + + +var GitMonitor = new Monitor({ + + /** + * @property {String} the "gitlive" directory, normally ~/gitlive + * dset by OWNER... - we should do this as a CTOR. + * + */ + gitlive : false, + + + queue : [], + queueRunning : false, + + + + pause : function() { + this.paused = true; + this.queue = []; + imports.StatusIcon.StatusIcon.el.set_from_stock( Gtk.STOCK_MEDIA_PAUSE ); + }, + + resume : function() { + this.paused = false; + this.queue = []; + imports.StatusIcon.StatusIcon.el.set_from_stock( Gtk.STOCK_MEDIA_PLAY ); + + + }, + + + start: function() { + var _this = this; + this.lastAdd = new Date(); + + this.top.forEach(this.monitor, this); + + GLib.timeout_add(GLib.PRIORITY_LOW, 500, function() { + //TIMEOUT", _this.queue.length , _this.queueRunning].join(', ')); + if (!_this.queue.length || _this.queueRunning) { + return 1; + } + var last = Math.floor(((new Date()) - this.lastAdd) / 100); + if (last < 4) { // wait 1/2 a seconnd before running. + return 1; + } + _this.runQueue(); + return 1; + },null,null); + + try { + var notification = new Notify.Notification({ + summary: "Git Live", + body : this.gitlive + "\nMonitoring " + this.monitors.length + " Directories", + timeout : 5 + }); + + notification.set_timeout(5); + notification.show(); + } catch(e) { + print(e.toString()); + } + + }, + + /** + * run the queue. + * - pulls the items off the queue + * (as commands run concurrently and new items may get added while it's running) + * - runs the queue items + * - pushes upstream. + * + */ + runQueue: function() + { + + if (this.paused) { + return; + } + this.queueRunning = true; + var cmds = []; + this.queue.forEach(function (q) { + cmds.push(q); + }); + this.queue = []; // empty queue! + + var success = []; + var failure = []; + var repos = []; + var done = []; + + // first build a array of repo's to work with + var repo_list = {}; + + // pull and group. + + //print(JSON.stringify(cmds)); + + cmds.forEach(function(cmd) { + var gitpath = cmd.shift(); + if (typeof(repo_list[gitpath]) == 'undefined') { + repo_list[gitpath] = new imports.Scm.Git.Repo.Repo( { repopath : gitpath }); + repo_list[gitpath].cmds = []; + repo_list[gitpath].pull(); + } + repo_list[gitpath].cmds.push(cmd); + }); + + // build add, remove and commit message list.. + + + for (var gitpath in repo_list) { + var repo = repo_list[gitpath]; + var add_files = []; + var remove_files = []; + var messages = []; + repo.cmds.forEach(function(cmd) { + //print(JSON.stringify(cmd)); + var name = cmd.shift(); + var arg = cmd.shift(); + + switch(name) { + case 'add' : + if (add_files.indexOf(arg) > -1) break; + add_files.push(arg); + break; + + case 'rm': + remove_files.push(arg); + break; + + case 'commit' : + messages.push(arg.message); + break; + } + }); + //repo.debug = 1; + // these can fail... at present... as we wildcard stuff. + repo.add(add_files); + repo.remove(remove_files); + + try { + success.push(repo.commit({ + reason : messages.join("\n"), + files : add_files + })); + success.push(repo.push()); + + } catch(e) { + failure.push(e.message); + + } + } + + // finally merge all the commit messages. + + try { + // catch notification failures.. so we can carry on.. + if (success.length) { + print(success.join("\n")); + + var notification = new Notify.Notification({ + summary: "Git Live Commited", + body : success.join("\n"), + timeout : 5 + + }); + + notification.set_timeout(5); + notification.show(); + } + + if (failure.length) { + + var notification = new Notify.Notification({ + summary: "Git Live ERROR!!", + body : failure.join("\n"), + timeout : 5 + + }); + + notification.set_timeout(5); // show errros for longer + notification.show(); + } + } catch(e) { + print(e.toString()); + + } + this.queueRunning = false; + }, + + shouldIgnore: function(f) + { + + if (this.paused) { + return true; + } + if (f.name[0] == '.') { + // except! + if (f.name == '.htaccess') { + return false; + } + + return true; + } + if (f.name.match(/~$/)) { + return true; + } + // ignore anything in top level!!!! + if (!f.vpath.length) { + return true; + } + + return false; + }, + + /** + * parsePath: + * Fill in gitlive, vpath and repo + * + */ + parsePath: function(f) + { + + var vpath_ar = f.path.substring(this.gitlive.length +1).split('/'); + + f.gitpath = this.gitlive + '/' + vpath_ar.shift(); + f.vpath = vpath_ar.join('/'); + //f.repo = new imports.Scm.Git.Repo({ repopath: f.gitpath }) + + + }, + + just_created : {}, + + onChanged : function(src) + { + return; // always ignore this..? + //this.parsePath(src); + }, + + + + + /** + * results in git add + git commit.. + * + */ + onChangesDoneHint : function(src) + { + this.parsePath(src); + if (this.shouldIgnore(src)) { + return; + } + + + var add_it = false; + if (typeof(this.just_created[src.path]) !='undefined') { + delete this.just_created[src.path]; + this.lastAdd = new Date(); + this.queue.push( + [ src.gitpath, 'add', src.vpath ], + [ src.gitpath, 'commit', { message: src.vpath} ] + + ); + + return; + } + this.lastAdd = new Date(); + this.queue.push( + [ src.gitpath, 'add', src.vpath ], + [ src.gitpath, 'commit', { message: src.vpath} ] + + + ); + }, + onDeleted : function(src) + { + this.parsePath(src); + if (this.shouldIgnore(src)) { + return; + } + // should check if monitor needs removing.. + // it should also check if it was a directory.. - so we dont have to commit all.. + + this.lastAdd = new Date(); + this.queue.push( + [ src.gitpath, 'rm' , src.vpath ], + [ src.gitpath, 'commit', { all: true, message: src.vpath} ] + + ); + + + }, + onCreated : function(src) + { + this.parsePath(src); + if (this.shouldIgnore(src)) { + return; + } + + if (!GLib.file_test(src.path, GLib.FileTest.IS_DIR)) { + this.just_created[src.path] = true; + return; // we do not handle file create flags... - use done hint. + } + // director has bee created + this.monitor(src.path); + this.lastAdd = new Date(); + this.queue.push( + [ src.gitpath, 'add' , src.vpath, { all: true } ], + [ src.gitpath, 'commit' , { all: true, message: src.vpath} ] + + ); + + + }, + onAttributeChanged : function(src) { + this.parsePath(src); + if (this.shouldIgnore(src)) { + return; + } + this.lastAdd = new Date(); + this.queue.push( + + //[ src.gitpath, 'commit' , src.vpath, { message: src.vpath} ] + [ src.gitpath, 'add' , src.vpath ], + [ src.gitpath, 'commit' , { message: "Attribute Changed :" + src.vpath} ] + ); + + + }, + + onMoved : function(src,dest) + { + this.parsePath(src); + this.parsePath(dest); + + if (src.gitpath != dest.gitpath) { + this.onDeleted(src); + this.onCreated(dest); + this.onChangedDoneHint(dest); + return; + } + // needs to handle move to/from unsupported types.. + + if (this.shouldIgnore(src)) { + return; + } + if (this.shouldIgnore(dest)) { + return; + } + this.lastAdd = new Date(); + this.queue.push( + // [ src.gitpath, 'mv', '-k', src.vpath, dest.vpath ], + [ src.gitpath, 'add', dest.vpath ], + [ src.gitpath, 'rm', src.vpath ], + + [ src.gitpath, 'commit' , + { message: 'MOVED ' + src.vpath +' to ' + dest.vpath} + ] + ); + + } + + +}); + + \ No newline at end of file diff --git a/gitlive.js b/gitlive.js index c3bcfa6f..d426fce5 100644 --- a/gitlive.js +++ b/gitlive.js @@ -10,309 +10,40 @@ * */ - - -GI = imports.gi.GIRepository; +GIRepository = imports.gi.GIRepository GLib = imports.gi.GLib; - +//print(JSON.stringify(GI, null,4)); // we add this in, as it appears to get lost sometimes if we set it using the ENV. variable in builder.sh -GI.Repository.prepend_search_path(GLib.get_home_dir() + '/.Builder/girepository-1.2'); - +// see the install instructions on how to override the default gir's +GIRepository.Repository.prepend_search_path(GLib.get_home_dir() + '/.Builder/girepository-1.2'); var Gio = imports.gi.Gio; var Gtk = imports.gi.Gtk; var Notify = imports.gi.Notify; -var Spawn = imports.Spawn; -var Git = imports.Git; + var StatusIcon = imports.StatusIcon.StatusIcon; var Monitor = imports.Monitor.Monitor; +var GitMonitor = imports.GitMonitor.GitMonitor; -//File = imports[__script_path__+'/../introspection-doc-generator/File.js'].File Gtk.init (null, null); -var gitlive = GLib.get_home_dir() + "/gitlive"; +// sanity check... -if (!GLib.file_test(gitlive, GLib.FileTest.IS_DIR)) { +// where is everything.. +GitMonitor.gitlive = GLib.get_home_dir() + "/gitlive"; + +if (!GLib.file_test(GitMonitor.gitlive, GLib.FileTest.IS_DIR)) { var msg = new Gtk.MessageDialog({message_type: Gtk.MessageType.INFO, buttons : Gtk.ButtonsType.OK, text: "GIT Live - ~/gitlive does not exist."}); msg.run(); msg.destroy(); - Seed.quit(); } - -var monitor = new Monitor({ - - queue : [], - queueRunning : false, - - start: function() { - var _this = this; - this.lastAdd = new Date(); - - GLib.timeout_add(GLib.PRIORITY_LOW, 500, function() { - //TIMEOUT", _this.queue.length , _this.queueRunning].join(', ')); - if (!_this.queue.length || _this.queueRunning) { - return 1; - } - var last = Math.floor(((new Date()) - this.lastAdd) / 100); - if (last < 4) { // wait 1/2 a seconnd before running. - return 1; - } - _this.runQueue(); - return 1; - },null,null); - - Monitor.prototype.start.call(this); - var notification = new Notify.Notification({ - summary: "Git Live", - body : gitlive + "\nMonitoring " + this.monitors.length + " Directories" - }); - - notification.set_timeout(2000); - notification.show(); - }, - /** - * run the queue. - * - pulls the items off the queue - * (as commands run concurrently and new items may get added while it's running) - * - runs the queue items - * - pushes upstream. - * - */ - runQueue: function() - { - this.queueRunning = true; - var cmds = []; - this.queue.forEach(function (q) { - cmds.push(q); - }); - this.queue = []; // empty queue! - - var success = []; - var failure = []; - var repos = []; - var done = []; - cmds.forEach(function(cmd) { - // prevent duplicate calls.. - if (done.indexOf(cmd.join(',')) > -1) { - return; - } - done.push(cmd.join(',')); - - if (repos.indexOf(cmd[0]) < 0) { - repos.push(cmd[0]); - Git.run(cmd[0] , 'pull'); // pull before we push! - } - var sp = Git.run.apply(Git,cmd); - - switch (sp.result * 1) { - case 0: // success: - success.push(sp.args.join(' ')); - if (sp.output.length) success.push(sp.output + ''); - // if (sp.stderr.length) success.push(sp.stderr + ''); - break; - default: - failure.push(sp.args.join(' ')); - if (sp.output.length) failure.push(sp.output); - if (sp.stderr.length) failure.push(sp.stderr); - break; - } - - }); - - // push upstream. - repos.forEach(function(r) { - var sp = Git.run(r , 'push', { all: true } ); - if (sp.length) { - success.push(sp); - } - - }); - - if (success.length) { - print(success.join("\n")); - var notification = new Notify.Notification({ - summary: "Git Live Commited", - body : success.join("\n") - - }); - - notification.set_timeout(2000); - notification.show(); - } - if (failure.length) { - - var notification = new Notify.Notification({ - summary: "Git Live ERROR!!", - body : failure.join("\n") - - }); - - notification.set_timeout(5000); // show errros for longer - notification.show(); - } - this.queueRunning = false; - }, - - shouldIgnore: function(f) - { - if (f.name[0] == '.') { - // except! - if (f.name == '.htaccess') { - return false; - } - - return true; - } - if (f.name.match(/~$/)) { - return true; - } - // ignore anything in top level!!!! - if (!f.vpath.length) { - return true; - } - - return false; - - }, - - parsePath: function(f) { - - var vpath_ar = f.path.substring(gitlive.length +1).split('/'); - - f.gitpath = gitlive + '/' + vpath_ar.shift(); - f.vpath = vpath_ar.join('/'); - - - }, - - just_created : {}, - - onChanged : function(src) - { - return; // always ignore this..? - //this.parsePath(src); - }, - onChangesDoneHint : function(src) - { - this.parsePath(src); - if (this.shouldIgnore(src)) { - return; - } - - var add_it = false; - if (typeof(this.just_created[src.path]) !='undefined') { - delete this.just_created[src.path]; - this.lastAdd = new Date(); - this.queue.push( - [ src.gitpath, 'add', src.vpath ], - [ src.gitpath, 'commit', src.vpath, { message: src.vpath} ] - - ); - - return; - } - this.lastAdd = new Date(); - this.queue.push( - [ src.gitpath, 'add', src.vpath ], - [ src.gitpath, 'commit', src.vpath, { message: src.vpath} ] - - - ); - - - }, - onDeleted : function(src) - { - this.parsePath(src); - if (this.shouldIgnore(src)) { - return; - } - // should check if monitor needs removing.. - // it should also check if it was a directory.. - so we dont have to commit all.. - - this.lastAdd = new Date(); - this.queue.push( - [ src.gitpath, 'rm' , src.vpath ], - [ src.gitpath, 'commit', { all: true, message: src.vpath} ] - - ); - - - }, - onCreated : function(src) - { - this.parsePath(src); - if (this.shouldIgnore(src)) { - return; - } - - if (!GLib.file_test(src.path, GLib.FileTest.IS_DIR)) { - this.just_created[src.path] = true; - return; // we do not handle file create flags... - use done hint. - } - // director has bee created - this.monitor(src.path); - this.lastAdd = new Date(); - this.queue.push( - [ src.gitpath, 'add' , src.vpath, { all: true } ], - [ src.gitpath, 'commit' , { all: true, message: src.vpath} ] - - ); - - - }, - onAttributeChanged : function(src) { - this.parsePath(src); - if (this.shouldIgnore(src)) { - return; - } - this.lastAdd = new Date(); - this.queue.push( - [ src.gitpath, 'commit' , src.vpath, { message: src.vpath} ] - ); - - - }, - - onMoved : function(src,dest) - { - this.parsePath(src); - this.parsePath(dest); - - if (src.gitpath != dest.gitpath) { - this.onDeleted(src); - this.onCreated(dest); - this.onChangedDoneHint(dest); - return; - } - // needs to handle move to/from unsupported types.. - - if (this.shouldIgnore(src)) { - return; - } - if (this.shouldIgnore(dest)) { - return; - } - this.lastAdd = new Date(); - this.queue.push( - [ src.gitpath, 'mv', '-k', src.vpath, dest.vpath ], - [ src.gitpath, 'commit' , src.vpath, dest.vpath , - { message: 'MOVED ' + src.vpath +' to ' + dest.vpath} ] - ); - - } - - -}); - - - +// I'm lost... function errorDialog(data) { var msg = new Gtk.MessageDialog({ @@ -326,8 +57,6 @@ function errorDialog(data) { - - // // need a better icon... @@ -337,8 +66,9 @@ StatusIcon.init(); Notify.init("gitlive"); -monitor.add(GLib.get_home_dir() + "/gitlive"); -monitor.start(); +GitMonitor.add(GitMonitor.gitlive); +GitMonitor.start(); + Gtk.main(); -//icon.signal["activate"].connect(on_left_click); +vv//icon.signal["activate"].connect(on_left_click); -- 2.39.2