[gnome-ostree/wip/dyntask-2: 2/2] wip



commit a7220281bad10f93944beb60eb256de196b58755
Author: Colin Walters <walters verbum org>
Date:   Thu Jan 24 09:13:51 2013 -0500

    wip

 Makefile-ostbuild.am                   |    2 +
 src/libgsystem                         |    2 +-
 src/ostbuild/js/buildutil.js           |   27 +++
 src/ostbuild/js/builtins/run_task.js   |   66 +++++++
 src/ostbuild/js/dyntask.js             |  305 +++++++++++++++++++++++++-------
 src/ostbuild/js/jsonutil.js            |   38 ++++
 src/ostbuild/js/main.js                |    2 +
 src/ostbuild/js/subtask.js             |   17 --
 src/ostbuild/js/tasks/task-checksum.js |  100 +----------
 src/ostbuild/ostbuild.in               |    2 +-
 10 files changed, 383 insertions(+), 178 deletions(-)
---
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index ef0ef1f..725ebfe 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -64,11 +64,13 @@ jsostbuiltins_DATA= \
 	src/ostbuild/js/builtins/build_disks.js \
 	src/ostbuild/js/builtins/checkout.js \
 	src/ostbuild/js/builtins/git_mirror.js \
+	src/ostbuild/js/builtins/make.js \
 	src/ostbuild/js/builtins/qa_make_disk.js \
 	src/ostbuild/js/builtins/qa_pull_deploy.js \
 	src/ostbuild/js/builtins/qa_smoketest.js \
 	src/ostbuild/js/builtins/prefix.js \
 	src/ostbuild/js/builtins/resolve.js \
+	src/ostbuild/js/builtins/run_task.js \
 	src/ostbuild/js/builtins/shell.js \
 	$(NULL)
 
diff --git a/src/libgsystem b/src/libgsystem
index 7caa16d..0258d06 160000
--- a/src/libgsystem
+++ b/src/libgsystem
@@ -1 +1 @@
-Subproject commit 7caa16d62721edb3800481b874613c4f989058f3
+Subproject commit 0258d06e5342bc4617f88594324eed43269e133e
diff --git a/src/ostbuild/js/buildutil.js b/src/ostbuild/js/buildutil.js
index 0f3d1c7..7246e5c 100644
--- a/src/ostbuild/js/buildutil.js
+++ b/src/ostbuild/js/buildutil.js
@@ -127,3 +127,30 @@ function getBaseUserChrootArgs() {
     let path = findUserChrootPath();
     return [path.get_path(), '--unshare-pid', '--unshare-ipc', '--unshare-net'];
 }
+
+function compareVersions(a, b) {
+    let adot = a.indexOf('.');
+    while (adot != -1) {
+	let bdot = b.indexOf('.');
+	if (bdot == -1)
+	    return 1;
+	let aSub = parseInt(a.substr(0, adot));
+	let bSub = parseInt(b.substr(0, bdot));
+	if (aSub > bSub)
+	    return 1;
+	else if (aSub < bSub)
+	    return -1;
+	a = a.substr(adot + 1);
+	b = b.substr(bdot + 1);
+	adot = a.indexOf('.');
+    }
+    if (b.indexOf('.') != -1)
+	return -1;
+    let aSub = parseInt(a);
+    let bSub = parseInt(b);
+    if (aSub > bSub)
+	return 1;
+    else if (aSub < bSub)
+	return -1;
+    return 0;
+}
diff --git a/src/ostbuild/js/builtins/run_task.js b/src/ostbuild/js/builtins/run_task.js
new file mode 100644
index 0000000..696b664
--- /dev/null
+++ b/src/ostbuild/js/builtins/run_task.js
@@ -0,0 +1,66 @@
+// Copyright (C) 2012,2013 Colin Walters <walters verbum org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
+const Lang = imports.lang;
+const Format = imports.format;
+
+const GSystem = imports.gi.GSystem;
+
+const Builtin = imports.builtin;
+const DynTask = imports.dyntask;
+const JsonDB = imports.jsondb;
+const ProcUtil = imports.procutil;
+const JsonUtil = imports.jsonutil;
+const Snapshot = imports.snapshot;
+const Config = imports.config;
+const BuildUtil = imports.buildutil;
+const Vcs = imports.vcs;
+const ArgParse = imports.argparse;
+
+const RunTask = new Lang.Class({
+    Name: 'RunTask',
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Internal helper to execute a task",
+
+    _init: function() {
+	this.parent();
+	this.parser.addArgument('taskName');
+	this.parser.addArgument('outfd');
+    },
+
+    execute: function(args, loop, cancellable) {
+	let outstream = Gio.UnixOutputStream.new(parseInt(args.outfd), true);
+	let taskset = DynTask.TaskSet.prototype.getInstance();
+	let [taskDef, inputs] = taskset.getTask(args.taskName);
+	let instance = new taskDef(null, args.taskName, inputs);
+	let result = null;
+	let err = null;
+	try {
+	    result = taskDef.executeSync(cancellable);
+	} catch (e) {
+	    err = e;
+	}
+	let data = { result: result,
+		     error: err };
+	JsonUtil.writeJsonToStream(outstream, data, cancellable);
+	outstream.close(cancellable);
+	print("done with task " + args.taskName);
+    }
+});
diff --git a/src/ostbuild/js/dyntask.js b/src/ostbuild/js/dyntask.js
index a99cab3..b227298 100644
--- a/src/ostbuild/js/dyntask.js
+++ b/src/ostbuild/js/dyntask.js
@@ -22,28 +22,18 @@ const Lang = imports.lang;
 
 const GSystem = imports.gi.GSystem;
 const Params = imports.params;
+const JsonUtil = imports.jsonutil;
+const ProcUtil = imports.procutil;
+const BuildUtil = imports.buildutil;
 
 const VERSION_RE = /(\d+)\.(\d+)/;
 
-const TaskMaster = new Lang.Class({
-    Name: 'TaskMaster',
-
-    _init: function(path, params) {
-	params = Params.parse(params, {maxConcurrent: 4,
-				       onEmpty: null});
-	this.path = path;
-	this.maxConcurrent = params.maxConcurrent;
-	this._onEmpty = params.onEmpty;
-	this.cancellable = null;
-	this._idleRecalculateId = 0;
-	this._taskSerial = 1;
+var _tasksetInstance = null;
+const TaskSet = new Lang.Class({
+    Name: 'TaskSet',
+    
+    _init: function() {
 	this._tasks = [];
-	this._executing = [];
-	this._pendingTasksList = [];
-	this._seenTasks = {};
-	this._completeTasks = {};
-	this._taskErrors = {};
-
 	let taskdir = Gio.File.new_for_path(GLib.getenv('OSTBUILD_DATADIR')).resolve_relative_path('js/tasks');
 	let denum = taskdir.enumerate_children('standard::*', 0, null);
 	let finfo;
@@ -54,62 +44,95 @@ const TaskMaster = new Lang.Class({
 		if (defname.indexOf('Task') !== 0)
 		    continue;
 		let cls = taskMod[defname];
-		let instance = new cls;
-		this.register(instance);
+		this.register(cls);
 	    }
 	}
     },
 
     register: function(taskdef) {
 	this._tasks.push(taskdef);
+	print("Registered task " + taskdef);
     },
 
-    _pushRecurse: function(taskName, seen) {
-	if (seen[taskName])
-	    return null;
-	let result = null;
+    getAllTasks: function() {
+	return this._tasks;
+    },
+
+    getTask: function(taskName, params) {
+	params = Params.parse(params, { allowNone: false })
 	for (let i = 0; i < this._tasks.length; i++) {
 	    let taskDef = this._tasks[i];
-	    let pattern = taskDef.getPattern();
+	    let pattern = taskDef.prototype.TaskPattern;
 	    let re = pattern[0];
 	    let match = re.exec(taskName);
 	    if (!match)
 		continue;
-
-	    let serial = this._taskSerial;
-	    this._taskSerial++;
 	    let vars = {};
 	    for (let i = 1; i < pattern.length; i++) {
 		vars[pattern[i]] = match[i];
 	    }
-	    let specifiedDependencies = taskDef.getDepends(vars);;
-	    let waitingDependencies = {};
-	    for (let j = 0; j < specifiedDependencies.length; j++) {
-		let depName = specifiedDependencies[j];
-		if (!this._completeTasks[depName]) {
-		    let depTask = this._pushRecurse(depName, seen);
-		    waitingDependencies[depName] = depTask;
-		}
-	    }
-	    result = {name: taskName,
-		      def: taskDef,
-		      vars: vars,
-		      dependencies: specifiedDependencies,
-		      waitingDependencies: waitingDependencies,
-		      serial: serial,
-		      result: null };
-	    this._pendingTasksList.push(result);
-	    seen[taskName] = true;
-	    break;
+	    return [taskDef, vars];
 	}
-	if (!result)
+	if (!params.allowNone)
 	    throw new Error("No task definition matches " + taskName);
+	return null;
+    },
+
+    getInstance: function() {
+	if (!_tasksetInstance)
+	    _tasksetInstance = new TaskSet();
+	return _tasksetInstance;
+    }
+});
+    
+const TaskMaster = new Lang.Class({
+    Name: 'TaskMaster',
+
+    _init: function(path, params) {
+	params = Params.parse(params, {maxConcurrent: 4,
+				       onEmpty: null});
+	this.path = path;
+	this.maxConcurrent = params.maxConcurrent;
+	this._onEmpty = params.onEmpty;
+	this.cancellable = null;
+	this._idleRecalculateId = 0;
+	this._executing = [];
+	this._pendingTasksList = [];
+	this._seenTasks = {};
+	this._completeTasks = {};
+	this._taskErrors = {};
+	this._caughtError = false;
+
+	this._taskset = TaskSet.prototype.getInstance();
+    },
+
+    _pushRecurse: function(taskName, seen) {
+	if (seen[taskName])
+	    return null;
+	let [taskDef, inputs] = this._taskset.getTask(taskName);
+	let specifiedDependencies = taskDef.prototype.getDepends(inputs);
+	let waitingDependencies = {};
+	for (let j = 0; j < specifiedDependencies.length; j++) {
+	    let depName = specifiedDependencies[j];
+	    if (!this._completeTasks[depName]) {
+		let depTask = this._pushRecurse(depName, seen);
+		waitingDependencies[depName] = depTask;
+	    }
+	}
+	let instance = new taskDef(this, taskName, inputs);
+	instance.onComplete = Lang.bind(this, this._onComplete, instance);
+	instance.dependencies = specifiedDependencies;
+	instance.waitingDependencies = waitingDependencies;
+	this._pendingTasksList.push(instance);
+	seen[taskName] = true;
 	this._queueRecalculate();
-	return result;
+	return instance;
     },
 
-    push: function(taskName) {
-	return this._pushRecurse(taskName, {});
+    pushTasks: function(taskNames) {
+	let seen = {};
+	for (let i = 0; i < taskNames.length; i++)
+	    this._pushRecurse(taskNames[i], seen);
     },
 
     _queueRecalculate: function() {
@@ -137,7 +160,7 @@ const TaskMaster = new Lang.Class({
 
 	if (this._executing.length == 0 &&
 	    this._pendingTasksList.length == 0) {
-	    this._onEmpty();
+	    this._onEmpty(true, null);
 	    return;
 	} else if (this._pendingTasksList.length == 0) {
 	    return;
@@ -156,20 +179,24 @@ const TaskMaster = new Lang.Class({
     _onComplete: function(result, error, task) {
 	if (error) {
 	    print("TaskMaster: While executing " + task.name + ": " + error);
-	    this._taskErrors[task.name] = error;
+	    if (!this._caughtError) {
+		this._caughtError = true;
+		this._onEmpty(false, error);
+	    }
+	    return;
 	} else {
 	    print("TaskMaster: Completed: " + task.name + " : " + JSON.stringify(result));
 	}
 	let idx = -1;
 	for (let i = 0; i < this._executing.length; i++) {
 	    let executingTask = this._executing[i];
-	    if (executingTask.serial != task.serial)
+	    if (executingTask !== task)
 		continue;
 	    idx = i;
 	    break;
 	}
 	if (idx == -1)
-	    throw new Error("TaskMaster: Internal error - Failed to find completed task serial:" + task.serial);
+	    throw new Error("TaskMaster: Internal error - Failed to find completed task:" + task.name);
 	task.result = result;
 	this._completeTasks[task.name] = task;
 	this._executing.splice(idx, 1);
@@ -197,12 +224,8 @@ const TaskMaster = new Lang.Class({
 	       !this._hasDeps(this._pendingTasksList[0])) {
 	    let task = this._pendingTasksList.shift();
 	    print("TaskMaster: running: " + task.name);
-	    let depResults = [];
-	    for (let i = 0; i < task.dependencies.length; i++) {
-		let depName = task.dependencies[i];
-		depResults.push(this._completeTasks[depName].result);
-	    }
-	    task.def.execute(task.vars, depResults, this.cancellable, Lang.bind(this, this._onComplete, task));
+	    let cls = task.def;
+	    task.execute(this.cancellable);
 	    this._executing.push(task);
 	}
     }
@@ -211,22 +234,172 @@ const TaskMaster = new Lang.Class({
 const TaskDef = new Lang.Class({
     Name: 'TaskDef',
 
-    _init: function() {
-    },
+    TaskPattern: null,
 
-    getPattern: function() {
-	throw new Error("Not implemented");
+    _init: function(taskmaster, name, inputs) {
+	this.taskmaster = taskmaster;
+	this.name = name;
+	this.inputs = inputs;
     },
 
     getDepends: function(inputs) {
 	return [];
     },
 
-    execute: function(inputs, dependResults, cancellable, onComplete) {
+    execute: function(cancellable) {
 	throw new Error("Not implemented");
     }
 });
 
+const SubTaskDef = new Lang.Class({
+    Name: 'SubTaskDef',
+    Extends: TaskDef,
+
+    PreserveStdout: true,
+    RetainFailed: 1,
+    RetainSuccess: 5,
+
+    _VERSION_RE: /(\d+\d\d\d\d)\.(\d+)/,
+
+    _loadVersionsFrom: function(dir, cancellable) {
+	let e = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, cancellable);
+	let info;
+	let results = [];
+	while ((info = e.next_file(cancellable)) != null) {
+	    let name = info.get_name();
+	    let match = this._VERSION_RE.exec(name);
+	    if (!match)
+		continue;
+	    results.push(name);
+	}
+	results.sort();
+	return results;
+    },
+
+    _cleanOldVersions: function(dir, retain, cancellable) {
+	let versions = this._loadVersionsFrom(dir, cancellable);
+	while (versions.length > retain) {
+	    let child = dir.get_child(versions.shift());
+	    GSystem.shutil_rm_rf(child, cancellable);
+	}
+    },
+
+    executeSync: function(cancellable) {
+	throw new Error("Not implemented");
+    },
+
+    execute: function(cancellable) {
+	this._asyncOutstanding = 0;
+	this._cancellable = cancellable;
+
+	this._subtaskdir = this.taskmaster.path.resolve_relative_path(this.name.substr(1));
+	GSystem.file_ensure_directory(this._subtaskdir, true, cancellable);
+	
+	let allVersions = [];
+
+	this._successDir = this._subtaskdir.get_child('successful');
+	GSystem.file_ensure_directory(this._successDir, true, cancellable);
+	let successVersions = this._loadVersionsFrom(this._successDir, cancellable);
+	for (let i = 0; i < successVersions.length; i++) {
+	    allVersions.push([true, successVersions[i]]);
+	}
+
+	this._failedDir = this._subtaskdir.get_child('failed');
+	GSystem.file_ensure_directory(this._failedDir, true, cancellable);
+	let failedVersions = this._loadVersionsFrom(this._failedDir, cancellable);
+	for (let i = 0; i < failedVersions.length; i++) {
+	    allVersions.push([false, failedVersions[i]]);
+	}
+
+	allVersions.sort(function (a, b) {
+	    let [successA, versionA] = a;
+	    let [successB, versionB] = b;
+	    return BuildUtil.compareVersions(versionA, versionB);
+	});
+
+	let currentTime = GLib.DateTime.new_now_utc();
+
+	let currentYmd = Format.vprintf('%d%02d%02d', [currentTime.get_year(),
+						       currentTime.get_month(),
+						       currentTime.get_day_of_month()]);
+	let version = null;
+	if (allVersions.length > 0) {
+	    let [lastSuccess, lastVersion] = allVersions[allVersions.length-1];
+	    let match = this._VERSION_RE.exec(lastVersion);
+	    if (!match) throw new Error();
+	    let lastYmd = match[1];
+	    let lastSerial = match[2];
+	    if (lastYmd == currentYmd) {
+		version = currentYmd + '.' + (parseInt(lastSerial) + 1);
+	    }
+	}
+	if (version === null) {
+	    version = currentYmd + '.0';
+	}
+
+	this._workdir = this._subtaskdir.get_child(version);
+	GSystem.shutil_rm_rf(this._workdir, cancellable);
+	GSystem.file_ensure_directory(this._workdir, true, cancellable);
+
+	let baseArgv = ['ostbuild', 'run-task', this.name];
+	let context = new GSystem.SubprocessContext({ argv: baseArgv });
+	context.set_cwd(this._workdir.get_path());
+	context.set_stdin_disposition(GSystem.SubprocessStreamDisposition.PIPE);
+	if (this.PreserveStdout) {
+	    let outPath = this._workdir.get_child('output.txt');
+	    context.set_stdout_file_path(outPath.get_path());
+	    context.set_stderr_disposition(GSystem.SubprocessStreamDisposition.STDERR_MERGE);
+	} else {
+	    context.set_stdout_disposition(GSystem.SubprocessStreamDisposition.NULL);
+	    let errPath = this._workdir.get_child('errors.txt');
+	    context.set_stderr_file_path(errPath.get_path());
+	}
+	let [success, resultpipe, fdno] = context.open_pipe_read(cancellable);
+	context.argv_append(''+fdno);
+	this._proc = new GSystem.Subprocess({ context: context });
+	this._proc.init(cancellable);
+
+	this._proc.wait(cancellable, Lang.bind(this, this._onChildExited));
+	this._asyncOutstanding += 1;
+	
+	this._result = null;
+	JsonUtil.loadJsonFromStreamAsync(resultpipe, cancellable, Lang.bind(this, this._onResultRead));
+	this._asyncOutstanding += 1;
+    },
+    
+    _onAsyncOpComplete: function(error) {
+	this._asyncOutstanding--;
+	if (this._asyncOutstanding != 0)
+	    return;
+	if (error) {
+	    this.onComplete(null, error);
+	} else {
+	    this.onComplete(this._result, null);
+	}
+    },
+
+    _onChildExited: function(proc, result) {
+	let [success, errmsg] = ProcUtil.asyncWaitCheckFinish(proc, result);
+	if (!success) {
+	    GSystem.file_rename(this._workdir, this._failedDir.get_child(this._workdir.get_basename()), null);
+	    this._cleanOldVersions(this._failedDir, this.RetainFailed, null);
+	    this._onAsyncOpComplete(new Error(errmsg));
+	} else {
+	    GSystem.file_rename(this._workdir, this._successDir.get_child(this._workdir.get_basename()), null);
+	    this._cleanOldVersions(this._successDir, this.RetainSuccess, null);
+	    this._onAsyncOpComplete(null);
+	}
+    },
+
+    _onResultRead: function(result, error) {
+	let childResult = result['result'];
+	let childError = result['error'];
+	if (childResult)
+	    this._result = childResult;
+	this._onAsyncOpComplete(childError);
+    }
+});
+
 function demo(argv) {
     var loop = GLib.MainLoop.new(null, true);
     let ecode = 1;
diff --git a/src/ostbuild/js/jsonutil.js b/src/ostbuild/js/jsonutil.js
index 04a82ca..24deb88 100644
--- a/src/ostbuild/js/jsonutil.js
+++ b/src/ostbuild/js/jsonutil.js
@@ -27,6 +27,44 @@ function writeJsonToStream(stream, data, cancellable) {
     stream.write_bytes(new GLib.Bytes(buf), cancellable);
 }
 
+function writeJsonToStreamAsync(stream, data, cancellable, onComplete) {
+    let buf = JSON.stringify(data, null, "  ");
+    stream.write_bytes_async(new GLib.Bytes(buf), GLib.PRIORITY_DEFAULT,
+			     cancellable, function(stream, result) {
+				 let err = null;
+				 try {
+				     stream.write_bytes_finish(result);
+				 } catch (e) {
+				     err = e;
+				 } 
+				 onComplete(err != null, err);
+			     });
+}
+
+function loadJsonFromStream(stream, cancellable) {
+    let membuf = Gio.MemoryOutputStream.new_resizable();
+    membuf.splice(stream, Gio.OutputStreamSpliceFlags.CLOSE_TARGET, cancellable);
+    let bytes = membuf.steal_as_bytes();
+    return JSON.parse(bytes.toArray().toString());
+}
+
+function loadJsonFromStreamAsync(stream, cancellable, onComplete) {
+    let membuf = Gio.MemoryOutputStream.new_resizable();
+    membuf.splice_async(stream, Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_DEFAULT,
+			cancellable, function(stream, result) {
+			    let err = null;
+			    let res = null;
+			    try {
+				stream.splice_finish(result);
+				let bytes = membuf.steal_as_bytes();
+				res = JSON.parse(bytes.toArray().toString());
+			    } catch (e) {
+				err = e;
+			    }
+			    onComplete(res, err);
+			});
+}
+
 function writeJsonFileAtomic(path, data, cancellable) {
     let s = path.replace(null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, cancellable);
     writeJsonToStream(s, data, cancellable);
diff --git a/src/ostbuild/js/main.js b/src/ostbuild/js/main.js
index ae92800..0f1e2e2 100755
--- a/src/ostbuild/js/main.js
+++ b/src/ostbuild/js/main.js
@@ -26,7 +26,9 @@ const BUILTINS = ['autobuilder',
                   'resolve',
                   'build',
                   'build-disks',
+                  'make',
                   'shell',
+                  'run-task',
                   'qa-make-disk',
 		  'qa-pull-deploy',
 		  'qa-smoketest'];
diff --git a/src/ostbuild/js/subtask.js b/src/ostbuild/js/subtask.js
index ddab482..a6333c6 100644
--- a/src/ostbuild/js/subtask.js
+++ b/src/ostbuild/js/subtask.js
@@ -99,23 +99,6 @@ const TaskSet = new Lang.Class({
 	}
     },
 
-    _load: function() {
-	var e = this.path.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
-	let info;
-	let history = [];
-	while ((info = e.next_file(null)) != null) {
-	    let name = info.get_name();
-	    let childPath = this.path.get_child(name);
-	    let match = VERSION_RE.exec(name);
-	    if (!match)
-		continue;
-	    history.push(new TaskHistoryEntry(childPath))
-	}
-	history.sort(TaskHistoryEntry.prototype.compareTo);
-	this._history = history;
-	this._cleanOldEntries();
-    },
-
     _onProcessComplete: function(proc, result) {
 	if (!this._running) throw new Error();
 
diff --git a/src/ostbuild/js/tasks/task-checksum.js b/src/ostbuild/js/tasks/task-checksum.js
index a91dabf..e21bf3f 100644
--- a/src/ostbuild/js/tasks/task-checksum.js
+++ b/src/ostbuild/js/tasks/task-checksum.js
@@ -24,100 +24,14 @@ const GSystem = imports.gi.GSystem;
 const Params = imports.params;
 const DynTask = imports.dyntask;
 
-const TaskChecksumSha256 = new Lang.Class({
-    Name: 'TaskChecksumSha256',
-    Extends: DynTask.TaskDef,
+const TaskCat = new Lang.Class({
+    Name: 'TaskCat',
+    Extends: DynTask.SubTaskDef,
 
-    getPattern: function() {
-	return [/\/ChecksumSha256\/(.*)$/, 'PATH'];
-    },
+    TaskPattern: [/\/cat\/(.*)$/, 'PATH'], 
 
-    _onAsyncOpComplete: function(error) {
-	let state = this;
-	state.asyncOutstanding--;
-	if (state.asyncOutstanding != 0)
-	    return;
-	if (error) {
-	    state.onComplete(null, error);
-	} else {
-	    let csumStr = state.buf.steal_as_bytes().toArray().toString();
-	    state.onComplete(csumStr.substr(0, csumStr.indexOf(' ')), null);
-	}
-    },
-
-    _onSpliceComplete: function(stream, result) {
-	let state = this;
-
-	let error = null;
-	try {
-	    stream.splice_finish(result);
-	} catch (e) {
-	    if (e.domain != undefined)
-		error = e;
-	    else
-		throw e;
-	}
-	Lang.bind(state, state.me._onAsyncOpComplete)(error);
-    },
-
-    _onProcWait: function(proc, result) {
-	let state = this;
-
-	let error = null;
-	try {
-	    let [success,ecode] = proc.wait_finish(result);
-	    GLib.spawn_check_exit_status(ecode);
-	} catch (e) {
-	    if (e.domain != undefined)
-		error = e;
-	    else
-		throw e;
-	}
-	Lang.bind(state, state.me._onAsyncOpComplete)(error);
-    },
-
-    execute: function(inputs, dependResults, cancellable, onComplete) {
-	let state = {me: this,
-		     onComplete: onComplete,
-		     buf: null,
-		     asyncOutstanding: 2};
-	let path = inputs.PATH;
-	let context = new GSystem.SubprocessContext({argv: ['sha256sum', path]});
-	context.set_stdout_disposition(GSystem.SubprocessStreamDisposition.PIPE);
-	let proc = new GSystem.Subprocess({context: context});
-	proc.init(cancellable);
-	let stdout = proc.get_stdout_pipe();
-	state.buf = Gio.MemoryOutputStream.new_resizable();
-	state.buf.splice_async(stdout, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE |
-			       Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_DEFAULT,
-			       cancellable, Lang.bind(state, this._onSpliceComplete));
-	proc.wait(cancellable, Lang.bind(state, this._onProcWait));
-    }
-});
-
-const TaskChecksumMany = new Lang.Class({
-    Name: 'TaskChecksumMany',
-    Extends: DynTask.TaskDef,
-
-    getPattern: function() {
-	return [/\/ChecksumMany\/(.*)$/, 'FILENAMES'];
-    },
-
-    getDepends: function(inputs) {
-	let filenamesStr = inputs.FILENAMES;
-	let filenames = filenamesStr.split(',');
-	let r = [];
-	for (let i = 0; i < filenames.length; i++)
-	    r.push('/ChecksumSha256/' + filenames[i]);
-	return r;
-    },
-
-    execute: function(inputs, dependResults, cancellable, onComplete) {
-	let r = '';
-	for (let i = 0; i < dependResults.length; i++)
-	    r += dependResults[i] + '\n';
-	GLib.idle_add(GLib.PRIORITY_DEFAULT, function() {
-	    onComplete(r, null);
-	});
+    executeSync: function(cancellable) {
+	print("hello world");
+	throw new Error("oops");
     }
 });
diff --git a/src/ostbuild/ostbuild.in b/src/ostbuild/ostbuild.in
index 01d75bc..258d9d0 100755
--- a/src/ostbuild/ostbuild.in
+++ b/src/ostbuild/ostbuild.in
@@ -25,4 +25,4 @@ export GIO_USE_VFS=local
 export OSTBUILD_DATADIR= pkgdatadir@
 export OSTBUILD_LIBDIR= pkglibdir@
 
-exec gjs -I "${jsdir}" "${jsdir}/main.js" "$@"
+exec $OSTBUILD_GDB gjs -I "${jsdir}" "${jsdir}/main.js" "$@"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]