[gnome-ostree] build: Create Builtin class, have builtins inherit from it



commit 27244ae27b099c9615ec6b52bbcd86e84f116692
Author: Colin Walters <walters verbum org>
Date:   Wed Jan 23 14:43:50 2013 -0500

    build: Create Builtin class, have builtins inherit from it
    
    This is a lot of net code reduction and cleanup.

 Makefile-ostbuild.am                       |    1 +
 src/ostbuild/js/builtin.js                 |   77 ++++++++++++++++++++++++++
 src/ostbuild/js/builtins/autobuilder.js    |   45 ++++++++--------
 src/ostbuild/js/builtins/build.js          |   49 +++++------------
 src/ostbuild/js/builtins/checkout.js       |   50 ++++++------------
 src/ostbuild/js/builtins/git_mirror.js     |   49 ++++++-----------
 src/ostbuild/js/builtins/prefix.js         |   25 +++------
 src/ostbuild/js/builtins/qa_build_disks.js |   22 ++------
 src/ostbuild/js/builtins/qa_make_disk.js   |   26 +++------
 src/ostbuild/js/builtins/qa_pull_deploy.js |   32 ++++-------
 src/ostbuild/js/builtins/qa_smoketest.js   |   32 ++++-------
 src/ostbuild/js/builtins/resolve.js        |   35 ++++--------
 src/ostbuild/js/builtins/shell.js          |   20 ++-----
 src/ostbuild/js/jsondb.js                  |   14 ++----
 src/ostbuild/js/main.js                    |   82 +++++++++++++++++++++-------
 src/ostbuild/js/snapshot.js                |   14 -----
 16 files changed, 278 insertions(+), 295 deletions(-)
---
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index 5d5c2bf..dcf16e1 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -41,6 +41,7 @@ jsostbuilddir=$(pkgdatadir)/js
 jsostbuild_DATA= \
 	src/ostbuild/js/argparse.js \
 	src/ostbuild/js/buildutil.js \
+	src/ostbuild/js/builtin.js \
 	src/ostbuild/js/config.js \
 	src/ostbuild/js/dyntask.js \
 	src/ostbuild/js/jsondb.js \
diff --git a/src/ostbuild/js/builtin.js b/src/ostbuild/js/builtin.js
new file mode 100644
index 0000000..e3d01f0
--- /dev/null
+++ b/src/ostbuild/js/builtin.js
@@ -0,0 +1,77 @@
+// 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 Config = imports.config;
+const Params = imports.params;
+const JsonUtil = imports.jsonutil;
+const ArgParse = imports.argparse;
+const JsonDB = imports.jsondb;
+const Snapshot = imports.snapshot;
+
+const Builtin = new Lang.Class({
+    Name: 'Builtin',
+
+    DESCRIPTION: null,
+
+    _init: function() {
+	this.parser = new ArgParse.ArgumentParser(this.DESCRIPTION);
+        
+	this.config = Config.get();
+	this.workdir = Gio.File.new_for_path(this.config.getGlobal('workdir'));
+	this.mirrordir = Gio.File.new_for_path(this.config.getGlobal('mirrordir'));
+	this.patchdir = this.workdir.get_child('patches');
+	this.libdir = Gio.File.new_for_path(GLib.getenv('OSTBUILD_LIBDIR'));
+	this.repo = this.workdir.get_child('repo');
+    },
+
+    _initPrefix: function(prefix) {
+	if (!prefix)
+	    this.prefix = Config.get().getPrefix();
+	else
+	    this.prefix = prefix;
+    },
+
+    _initSnapshot: function(prefix, snapshotPath, cancellable) {
+	let snapshotDir = this.workdir.get_child('snapshots');
+	let path, data;
+	if (!prefix && !snapshotPath)
+	    prefix = Config.get().getPrefix();
+	if (prefix) {
+	    this.prefix = prefix;
+	    let db = new JsonDB.JsonDB(snapshotDir.get_child(prefix));
+	    path = db.getLatestPath();
+	    data = db.loadFromPath(path, cancellable);
+	} else {
+	    path = Gio.File.new_for_path(snapshotPath);
+	    data = JsonUtil.loadJson(path, cancellable);
+	    this.prefix = data['prefix'];
+	}
+	this._snapshot = new Snapshot.Snapshot(data, path);
+    },
+
+    main: function(argv, loop, cancellable) {
+	let args = this.parser.parse(argv);
+	this.execute(args, loop, cancellable);
+    }
+});
diff --git a/src/ostbuild/js/builtins/autobuilder.js b/src/ostbuild/js/builtins/autobuilder.js
index 97beb83..73ddcec 100644
--- a/src/ostbuild/js/builtins/autobuilder.js
+++ b/src/ostbuild/js/builtins/autobuilder.js
@@ -22,6 +22,7 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const SubTask = imports.subtask;
 const JsonDB = imports.jsondb;
 const ProcUtil = imports.procutil;
@@ -38,18 +39,14 @@ var AutoBuilderIface = <interface name="org.gnome.OSTreeBuild.AutoBuilder">
 <property name="Status" type="s" access="read" />
 </interface>;
 
-const AutoBuilder = new Lang.Class({
-    Name: 'AutoBuilder',
+const Autobuilder = new Lang.Class({
+    Name: 'Autobuilder',
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Automatically fetch git repositories and build",
     
     _init: function() {
-	this.config = Config.get();
-	this.workdir = Gio.File.new_for_path(this.config.getGlobal('workdir'));
-	this.prefix = this.config.getPrefix();
-	this._snapshot_dir = this.workdir.get_child('snapshots');
-	this._status_path = this.workdir.get_child('autobuilder-' + this.prefix + '.json');
-
-	this._manifestPath = Gio.File.new_for_path('manifest.json');
-
+	this.parent();
 	this._build_needed = true;
 	this._full_resolve_needed = true;
 	this._queued_force_resolve = [];
@@ -57,13 +54,22 @@ const AutoBuilder = new Lang.Class({
 	this._resolve_timeout = 0;
 	this._source_snapshot_path = null;
 	this._prev_source_snapshot_path = null;
-	
+    },
+
+    execute: function(args, loop, cancellable) {
+	this._initSnapshot(null, null, cancellable);
+	this._status_path = this.workdir.get_child('autobuilder-' + this.prefix + '.json');
+	this._manifestPath = Gio.File.new_for_path('manifest.json');
+
+	this._ownId = Gio.DBus.session.own_name('org.gnome.OSTreeBuild', Gio.BusNameOwnerFlags.NONE,
+						function(name) {},
+						function(name) { loop.quit(); });
+
 	this._impl = Gio.DBusExportedObject.wrapJSObject(AutoBuilderIface, this);
 	this._impl.export(Gio.DBus.session, '/org/gnome/OSTreeBuild/AutoBuilder');
 
-	let snapshotdir = this.workdir.get_child('snapshots');
-	GSystem.file_ensure_directory(snapshotdir, true, null);
-	this._src_db = new JsonDB.JsonDB(snapshotdir, this.prefix + '-src-snapshot');
+	this._snapshot_dir = this.workdir.get_child('snapshots').get_child(this.prefix);
+	this._src_db = new JsonDB.JsonDB(this._snapshot_dir);
 
 	let taskdir = this.workdir.get_child('tasks');
 	this._resolve_taskset = new SubTask.TaskSet(taskdir.get_child(this.prefix + '-resolve'));
@@ -80,6 +86,8 @@ const AutoBuilder = new Lang.Class({
 	    this._run_build();
 
 	this._updateStatus();
+
+	loop.run();
     },
 
     _updateStatus: function() {
@@ -281,12 +289,3 @@ const AutoBuilder = new Lang.Class({
 	JsonUtil.writeJsonFileAtomic(this._status_path, status, cancellable);
     }
 });
-
-function main(argv) {
-    var ownId = Gio.DBus.session.own_name('org.gnome.OSTreeBuild', Gio.BusNameOwnerFlags.NONE,
-					  function(name) {},
-					  function(name) { loop.quit(); });
-    
-    var builder = new AutoBuilder();
-    loop.run();
-}
diff --git a/src/ostbuild/js/builtins/build.js b/src/ostbuild/js/builtins/build.js
index a43eba9..98faf1a 100644
--- a/src/ostbuild/js/builtins/build.js
+++ b/src/ostbuild/js/builtins/build.js
@@ -22,6 +22,7 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const SubTask = imports.subtask;
 const JsonDB = imports.jsondb;
 const ProcUtil = imports.procutil;
@@ -40,6 +41,9 @@ var loop = GLib.MainLoop.new(null, true);
 
 const Build = new Lang.Class({
     Name: "Build",
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Build multiple components and generate trees",
 
     _resolveRefs: function(refs) {
         if (refs.length == 0)
@@ -637,32 +641,20 @@ const Build = new Lang.Class({
 
 	builtRevisionPath.replace_contents(basemeta['revision'], null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, cancellable);
     },
-        
-    execute: function(argv) {
-	let cancellable = null;
 
-        let parser = new ArgParse.ArgumentParser("Build multiple components and generate trees");
-        parser.addArgument('--prefix');
-        parser.addArgument('--snapshot');
-        parser.addArgument('--patches-path');
-        
-        let args = parser.parse(argv);
-	this.args = args;
+    _init: function() {
+	this.parent();
+        this.parser.addArgument('--prefix');
+        this.parser.addArgument('--snapshot');
+        this.parser.addArgument('--patches-path');
 
-	this.config = Config.get();
-	this.workdir = Gio.File.new_for_path(this.config.getGlobal('workdir'));
-	this.mirrordir = Gio.File.new_for_path(this.config.getGlobal('mirrordir'));
-	this.patchdir = this.workdir.get_child('patches');
-	this.prefix = args.prefix || this.config.getPrefix();
-	this._snapshotDir = this.workdir.get_child('snapshots');
-	this.libdir = Gio.File.new_for_path(GLib.getenv('OSTBUILD_LIBDIR'));
-
-	this._srcDb = new JsonDB.JsonDB(this._snapshotDir, this.prefix + '-src-snapshot');
-	this._snapshot = Snapshot.Snapshot.prototype.loadFromDb(this._srcDb, this.prefix, args.snapshot, cancellable);
-	let snapshotName = this._snapshot.path.get_basename();
-	
         this.forceBuildComponents = {};
         this.cachedPatchdirRevision = null;
+    },
+        
+    execute: function(args, loop, cancellable) {
+	this._initSnapshot(args.prefix, args.snapshot, cancellable);
+	this.args = args;
 
 	this.repo = this.workdir.get_child('repo');
 
@@ -805,7 +797,7 @@ const Build = new Lang.Class({
 
 	let buildDataPath = this.workdir.get_child(this.prefix + '-buildresult.json');
 	let targetRevisions = {};
-	let buildData = { snapshotName: snapshotName,
+	let buildData = { snapshotName: this._snapshot.path.get_basename(),
 			  snapshot: this._snapshot.data,
 			  targets: targetRevisions };
         for (let i = 0; i < targetsList.length; i++) {
@@ -817,14 +809,3 @@ const Build = new Lang.Class({
 	JsonUtil.writeJsonFileAtomic(buildDataPath, buildData, cancellable);
     }
 });
-
-
-function main(argv) {
-    let ecode = 1;
-    var app = new Build();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-		  function() { try { app.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
-
diff --git a/src/ostbuild/js/builtins/checkout.js b/src/ostbuild/js/builtins/checkout.js
index a6711ef..0b3aaf4 100644
--- a/src/ostbuild/js/builtins/checkout.js
+++ b/src/ostbuild/js/builtins/checkout.js
@@ -22,6 +22,7 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const JsonDB = imports.jsondb;
 const ProcUtil = imports.procutil;
 const JsonUtil = imports.jsonutil;
@@ -32,8 +33,6 @@ const BuildUtil = imports.buildutil;
 const Vcs = imports.vcs;
 const ArgParse = imports.argparse;
 
-var loop = GLib.MainLoop.new(null, true);
-
 function _checkoutOneComponent(mirrordir, patchdir, component, cancellable, params) {
     params = Params.parse(params, { checkoutdir: null,
 				    clean: false,
@@ -101,35 +100,27 @@ function _checkoutOneComponent(mirrordir, patchdir, component, cancellable, para
 
 const Checkout = new Lang.Class({
     Name: 'Checkout',
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Check out git repository",
 
     _init: function() {
+	this.parent();
+	this.parser.addArgument('--overwrite', {action:'storeTrue'});
+	this.parser.addArgument('--prefix');
+	this.parser.addArgument('--patches-path');
+	this.parser.addArgument('--metadata-path');
+	this.parser.addArgument('--snapshot');
+	this.parser.addArgument('--checkoutdir');
+	this.parser.addArgument('--clean', {action: 'storeTrue'});
+	this.parser.addArgument('component');
     },
 
-    execute: function(argv) {
-	let cancellable = null;
-	let parser = new ArgParse.ArgumentParser('Check out specified modules');
-	parser.addArgument('--overwrite', {action:'storeTrue'});
-	parser.addArgument('--prefix');
-	parser.addArgument('--patches-path');
-	parser.addArgument('--metadata-path');
-	parser.addArgument('--snapshot');
-	parser.addArgument('--checkoutdir');
-	parser.addArgument('--clean', {action: 'storeTrue'});
-	parser.addArgument('component');
-
-	let args = parser.parse(argv);
-        
-	this.config = Config.get();
-	this.workdir = Gio.File.new_for_path(this.config.getGlobal('workdir'));
-	this.mirrordir = Gio.File.new_for_path(this.config.getGlobal('mirrordir'));
-	this.patchdir = this.workdir.get_child('patches');
+    execute: function(args, loop, cancellable) {
+	this._initSnapshot(args.prefix, args.snapshot, cancellable);
+
 	if (!this.mirrordir.query_exists(cancellable))
 	    throw new Error("Need mirrordir: "+ this.mirrordir.get_path());
-	this.prefix = args.prefix || this.config.getPrefix();
-	this._snapshotDir = this.workdir.get_child('snapshots');
-
-	this._srcDb = new JsonDB.JsonDB(this._snapshotDir, this.prefix + '-src-snapshot');
-	this._snapshot = Snapshot.Snapshot.prototype.loadFromDb(this._srcDb, this.prefix, args.snapshot, cancellable);
 
         let componentName = args.component;
 
@@ -159,12 +150,3 @@ const Checkout = new Lang.Class({
 	}
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var checkout = new Checkout();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-		  function() { try { checkout.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/git_mirror.js b/src/ostbuild/js/builtins/git_mirror.js
index dfbbcc6..309a3be 100644
--- a/src/ostbuild/js/builtins/git_mirror.js
+++ b/src/ostbuild/js/builtins/git_mirror.js
@@ -20,6 +20,7 @@ const Gio = imports.gi.Gio;
 const Lang = imports.lang;
 const Format = imports.format;
 
+const Builtin = imports.builtin;
 const ProcUtil = imports.procutil;
 const Config = imports.config;
 const Snapshot = imports.snapshot;
@@ -33,31 +34,24 @@ var loop = GLib.MainLoop.new(null, true);
 
 const GitMirror = new Lang.Class({
     Name: 'GitMirror',
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Update internal git mirror for one or more components",
     
     _init: function() {
-
-    },
-
-    execute: function(argv) {
-	let cancellable = null;
-        let parser = new ArgParse.ArgumentParser("Update internal git mirror for one or more components");
-        parser.addArgument('--prefix');
-        parser.addArgument('--manifest');
-        parser.addArgument('--snapshot');
-        parser.addArgument('--fetch', {action:'storeTrue',
+	this.parent();
+        this.parser.addArgument('--prefix');
+        this.parser.addArgument('--manifest');
+        this.parser.addArgument('--snapshot');
+        this.parser.addArgument('--fetch', {action:'storeTrue',
 				       help:"Also do a git fetch for components"});
-        parser.addArgument(['-k', '--keep-going'], {action:'storeTrue',
+        this.parser.addArgument(['-k', '--keep-going'], {action:'storeTrue',
 						    help: "Don't exit on fetch failures"});
-        parser.addArgument('components', {nargs:'*'});
-
-        let args = parser.parse(argv);
+        this.parser.addArgument('components', {nargs:'*'});
+    },
 
-	this.config = Config.get();
-	this.workdir = Gio.File.new_for_path(this.config.getGlobal('workdir'));
-	this._mirrordir = Gio.File.new_for_path(this.config.getGlobal('mirrordir'));
-	this.prefix = args.prefix || this.config.getPrefix();
-	this._snapshotDir = this.workdir.get_child('snapshots');
-	this._srcDb = new JsonDB.JsonDB(this._snapshotDir, this.prefix + '-src-snapshot');
+    execute: function(args, loop, cancellable) {
+        let parser = new ArgParse.ArgumentParser();
 
         if (args.manifest != null) {
             let snapshotData = JsonUtil.loadJson(Gio.File.new_for_path(args.manifest), cancellable);
@@ -71,7 +65,7 @@ const GitMirror = new Lang.Class({
             snapshotData['base'] = BuildUtil.resolveComponent(snapshotData, snapshotData['base']);
 	    this._snapshot = new Snapshot.Snapshot(snapshotData, null);
         } else {
-	    this._snapshot = Snapshot.Snapshot.prototype.loadFromDb(this._srcDb, this.prefix, args.snapshot, cancellable);
+	    this._initSnapshot(args.prefix, args.snapshot, cancellable);
 	}
 
 	let componentNames;
@@ -90,20 +84,11 @@ const GitMirror = new Lang.Class({
             let branchOrTag = branch || tag;
 
             if (!args.fetch) {
-                Vcs.ensureVcsMirror(this._mirrordir, keytype, uri, branchOrTag, cancellable);
+                Vcs.ensureVcsMirror(this.mirrordir, keytype, uri, branchOrTag, cancellable);
 	    } else {
 		print("Running git fetch for " + name);
-		Vcs.fetch(this._mirrordir, keytype, uri, branchOrTag, cancellable, {keepGoing:args.keep_going});
+		Vcs.fetch(this.mirrordir, keytype, uri, branchOrTag, cancellable, {keepGoing:args.keep_going});
 	    }
 	}));
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var gitMirror = new GitMirror();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-		  function() { try { gitMirror.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/prefix.js b/src/ostbuild/js/builtins/prefix.js
index f39358f..b791d54 100644
--- a/src/ostbuild/js/builtins/prefix.js
+++ b/src/ostbuild/js/builtins/prefix.js
@@ -20,6 +20,7 @@ const Gio = imports.gi.Gio;
 const Lang = imports.lang;
 const Format = imports.format;
 
+const Builtin = imports.builtin;
 const Config = imports.config;
 const ArgParse = imports.argparse;
 
@@ -27,18 +28,17 @@ var loop = GLib.MainLoop.new(null, true);
 
 const Prefix = new Lang.Class({
     Name: 'Prefix',
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Display or modify \"prefix\" (build target)",
 
     _init: function() {
+	this.parent();
+        this.parser.addArgument(['-a', '--active'], {action: 'storeTrue'});
+        this.parser.addArgument('prefix');
     },
 
-    execute: function(argv) {
-	let cancellable = null;
-        let parser = new ArgParse.ArgumentParser("Display or modify \"prefix\" (build target)");
-        parser.addArgument(['-a', '--active'], {action: 'storeTrue'});
-        parser.addArgument('prefix');
-
-        let args = parser.parse(argv);
-
+    execute: function(args, loop, cancellable) {
 	let filepath = GLib.build_filenamev([GLib.get_user_config_dir(), "ostbuild-prefix"]);
         this.path = Gio.File.new_for_path(filepath);
         this._setPrefix(args.prefix, cancellable);
@@ -49,12 +49,3 @@ const Prefix = new Lang.Class({
         print("Prefix is now " + prefix);
     },
 });
-
-function main(argv) {
-    let ecode = 1;
-    var app = new Prefix();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-		  function() { try { app.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/qa_build_disks.js b/src/ostbuild/js/builtins/qa_build_disks.js
index ab9e08a..41be72c 100644
--- a/src/ostbuild/js/builtins/qa_build_disks.js
+++ b/src/ostbuild/js/builtins/qa_build_disks.js
@@ -23,6 +23,7 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const ArgParse = imports.argparse;
 const ProcUtil = imports.procutil;
 const LibQA = imports.libqa;
@@ -34,14 +35,12 @@ const loop = GLib.MainLoop.new(null, true);
 
 const QaBuildDisks = new Lang.Class({
     Name: 'QaBuildDisks',
+    Extends: Builtin.Builtin,
 
-    execute: function(argv) {
-	      let cancellable = null;
-	      this.config = Config.get();
-	      this.workdir = Gio.File.new_for_path(this.config.getGlobal('workdir'));
-	      this.prefix = this.config.getPrefix();
-	      this.repo = this.workdir.get_child('repo');
-	      this._snapshot_dir = this.workdir.get_child('snapshots');
+    DESCRIPTION: "Generate disk images",
+
+    execute: function(args, loop, cancellable) {
+        this._initPrefix(null);
 	      this._buildDataPath = this.workdir.get_child(this.prefix + '-buildresult.json');
 	      this._buildData = JsonUtil.loadJson(this._buildDataPath, cancellable);
 
@@ -88,12 +87,3 @@ const QaBuildDisks = new Lang.Class({
 	      return this.workdir.get_child(this.prefix + '-' + squashedName + suffix);
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var app = new QaBuildDisks();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-                  function() { try { app.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/qa_make_disk.js b/src/ostbuild/js/builtins/qa_make_disk.js
index 163fa5f..a68fec8 100644
--- a/src/ostbuild/js/builtins/qa_make_disk.js
+++ b/src/ostbuild/js/builtins/qa_make_disk.js
@@ -23,22 +23,23 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const ArgParse = imports.argparse;
 const ProcUtil = imports.procutil;
 const GuestFish = imports.guestfish;
 
-const loop = GLib.MainLoop.new(null, true);
-
 const QaMakeDisk = new Lang.Class({
     Name: 'QaMakeDisk',
+    Extends: Builtin.Builtin,
 
-    execute: function(argv) {
-        let cancellable = null;
-        let parser = new ArgParse.ArgumentParser("Generate a disk image");
-        parser.addArgument('diskpath');
-        
-        let args = parser.parse(argv);
+    DESCRIPTION: "Generate a disk image",
 
+    _init: function() {
+        this.parent();
+        this.parser.addArgument('diskpath');
+    },
+
+    execute: function(args, loop, cancellable) {
         let path = Gio.File.new_for_path(args.diskpath);
         if (path.query_exists(null))
             throw new Error("" + path.get_path() + " exists");
@@ -91,12 +92,3 @@ mkdir /boot\n\
         print("Created: " + path.get_path());
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var app = new QaMakeDisk();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-                  function() { try { app.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/qa_pull_deploy.js b/src/ostbuild/js/builtins/qa_pull_deploy.js
index b87a016..837ff48 100644
--- a/src/ostbuild/js/builtins/qa_pull_deploy.js
+++ b/src/ostbuild/js/builtins/qa_pull_deploy.js
@@ -23,26 +23,27 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const ArgParse = imports.argparse;
 const ProcUtil = imports.procutil;
 const LibQA = imports.libqa;
 const GuestFish = imports.guestfish;
 
-const loop = GLib.MainLoop.new(null, true);
-
 const QaPullDeploy = new Lang.Class({
     Name: 'QaPullDeploy',
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Copy from repository into disk image and deploy it",
 
-    execute: function(argv) {
-        let cancellable = null;
-        let parser = new ArgParse.ArgumentParser("Generate a disk image");
-        parser.addArgument('diskpath');
-        parser.addArgument('srcrepo');
-        parser.addArgument('osname');
-        parser.addArgument('target');
-        
-        let args = parser.parse(argv);
+    _init: function() {
+        this.parent();
+        this.parser.addArgument('diskpath');
+        this.parser.addArgument('srcrepo');
+        this.parser.addArgument('osname');
+        this.parser.addArgument('target');
+    },
 
+    execute: function(args, loop, cancellable) {
         let diskpath = Gio.File.new_for_path(args.diskpath);
 
         this._workdir = Gio.File.new_for_path('.');
@@ -63,12 +64,3 @@ const QaPullDeploy = new Lang.Class({
         print("Complete!");
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var app = new QaPullDeploy();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-                  function() { try { app.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/qa_smoketest.js b/src/ostbuild/js/builtins/qa_smoketest.js
index 046c0dc..6a1eeef 100644
--- a/src/ostbuild/js/builtins/qa_smoketest.js
+++ b/src/ostbuild/js/builtins/qa_smoketest.js
@@ -23,16 +23,18 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const ArgParse = imports.argparse;
 const ProcUtil = imports.procutil;
 const LibQA = imports.libqa;
 
-const loop = GLib.MainLoop.new(null, true);
-
 const TIMEOUT_SECONDS = 2 * 60;
 
-const QaSmokeTest = new Lang.Class({
-    Name: 'QaSmokeTest',
+const QaSmoketest = new Lang.Class({
+    Name: 'QaSmoketest',
+    Extends: Builtin.Builtin,
+
+    DESCRIPTION: "Test booting and logging in",
 
     RequiredMessageIDs: ["39f53479d3a045ac8e11786248231fbf", // graphical.target 
                          "f77379a8490b408bbe5f6940505a777b",  // systemd-journald
@@ -132,14 +134,13 @@ const QaSmokeTest = new Lang.Class({
         }
     },
 
-    execute: function(argv) {
-        let cancellable = null;
-        let parser = new ArgParse.ArgumentParser("Basic smoke testing via parsing serial console");
-        parser.addArgument('--monitor', { action: 'storeTrue' });
-        parser.addArgument('diskpath');
-        
-        let args = parser.parse(argv);
+    _init: function() {
+        this.parent();
+        this.parser.addArgument('--monitor', { action: 'storeTrue' });
+        this.parser.addArgument('diskpath');
+    },
 
+    execute: function(args, loop, cancellable) {
         this._failed = false;
         this._journalStream = null;
         this._journalDataStream = null;
@@ -221,12 +222,3 @@ const QaSmokeTest = new Lang.Class({
         return 0;
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var app = new QaSmokeTest();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-                  function() { try { ecode = app.execute(argv); } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/resolve.js b/src/ostbuild/js/builtins/resolve.js
index 67cae34..70751cc 100644
--- a/src/ostbuild/js/builtins/resolve.js
+++ b/src/ostbuild/js/builtins/resolve.js
@@ -23,6 +23,7 @@ const Format = imports.format;
 const GSystem = imports.gi.GSystem;
 
 const JsonDB = imports.jsondb;
+const Builtin = imports.builtin;
 const ProcUtil = imports.procutil;
 const JsonUtil = imports.jsonutil;
 const Snapshot = imports.snapshot;
@@ -31,27 +32,24 @@ const BuildUtil = imports.buildutil;
 const Vcs = imports.vcs;
 const ArgParse = imports.argparse;
 
-var loop = GLib.MainLoop.new(null, true);
-
 const Resolve = new Lang.Class({
     Name: "Resolve",
+    Extends: Builtin.Builtin,
+    
+    DESCRIPTION: "Expand git revisions in source to exact targets",
 
     _init: function() {
-    },
-
-    execute: function(argv) {
-	let cancellable = null;
-        let parser = new ArgParse.ArgumentParser("Expand git revisions in source to exact targets");
-        parser.addArgument('--manifest', {help:"Path to manifest file"});
-        parser.addArgument('--fetch', {action:'storeTrue',
+	this.parent();
+        this.parser.addArgument('--manifest', {help:"Path to manifest file"});
+        this.parser.addArgument('--fetch', {action:'storeTrue',
 					help:"Also perform a git fetch"});
-        parser.addArgument('--fetch-keep-going', {action:'storeTrue',
+        this.parser.addArgument('--fetch-keep-going', {action:'storeTrue',
 						  help:"Don't exit on fetch failures"});
-        parser.addArgument('components', {nargs:'*',
+        this.parser.addArgument('components', {nargs:'*',
 					  help:"List of component names to git fetch"});
+    },
 
-        let args = parser.parse(argv);
-
+    execute: function(args, loop, cancellable) {
 	let componentsToFetch = {};
 	args.components.forEach(function (name) {
 	    componentsToFetch[name] = true;
@@ -131,7 +129,7 @@ const Resolve = new Lang.Class({
 	}
 
 	let snapshotdir = this.workdir.get_child('snapshots');
-	this._src_db = new JsonDB.JsonDB(snapshotdir, this.prefix + '-src-snapshot');
+	this._src_db = new JsonDB.JsonDB(snapshotdir.get_child(this.prefix));
         let [path, modified] = this._src_db.store(this._snapshot, cancellable);
         if (modified) {
             print("New source snapshot: " + path.get_path());
@@ -140,12 +138,3 @@ const Resolve = new Lang.Class({
 	}
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var resolve = new Resolve();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-		  function() { try { resolve.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/builtins/shell.js b/src/ostbuild/js/builtins/shell.js
index 8c02273..00250dc 100644
--- a/src/ostbuild/js/builtins/shell.js
+++ b/src/ostbuild/js/builtins/shell.js
@@ -22,6 +22,7 @@ const Format = imports.format;
 
 const GSystem = imports.gi.GSystem;
 
+const Builtin = imports.builtin;
 const JsonDB = imports.jsondb;
 const ProcUtil = imports.procutil;
 const JsonUtil = imports.jsonutil;
@@ -31,24 +32,13 @@ const BuildUtil = imports.buildutil;
 const Vcs = imports.vcs;
 const ArgParse = imports.argparse;
 
-var loop = GLib.MainLoop.new(null, true);
-
 const Shell = new Lang.Class({
     Name: 'Shell',
+    Extends: Builtin.Builtin,
 
-    _init: function() {
-    },
+    DESCRIPTION: "Interactive shell",
 
-    execute: function(argv) {
-	    imports.console.interact();
+    execute: function(args, loop, cancellable) {
+	imports.console.interact();
     }
 });
-
-function main(argv) {
-    let ecode = 1;
-    var app = new Shell();
-    GLib.idle_add(GLib.PRIORITY_DEFAULT,
-		  function() { try { app.execute(argv); ecode = 0; } finally { loop.quit(); }; return false; });
-    loop.run();
-    return ecode;
-}
diff --git a/src/ostbuild/js/jsondb.js b/src/ostbuild/js/jsondb.js
index e494903..c61b311 100644
--- a/src/ostbuild/js/jsondb.js
+++ b/src/ostbuild/js/jsondb.js
@@ -26,11 +26,10 @@ const GSystem = imports.gi.GSystem;
 const JsonDB = new Lang.Class({
     Name: 'JsonDB',
 
-    _init: function(path, prefix) {
+    _init: function(path) {
 	this._path = path;
 	GSystem.file_ensure_directory(this._path, true, null);
-	this._prefix = prefix;
-	this._re = /-(\d+)\.(\d+)-([0-9a-f]+).json$/;
+	this._re = /^(\d+)\.(\d+)-([0-9a-f]+).json$/;
 	this._maxVersions = 5;
     },
 
@@ -52,13 +51,9 @@ const JsonDB = new Lang.Class({
 	let info;
 	while ((info = e.next_file(null)) != null) {
 	    let name = info.get_name();
-	    if (name.indexOf(this._prefix) != 0)
-		continue;
-	    if (name.length < 6 || name.lastIndexOf('.json') != name.length-5)
-		continue;
 	    let match = this._re.exec(name);
 	    if (!match)
-		throw new Error("Invalid JSONDB file " + name);
+		continue;
 	    result.push([parseInt(match[1]), parseInt(match[2]),
 			 match[3], name]);
 	}
@@ -126,8 +121,7 @@ const JsonDB = new Lang.Class({
             latestVersion = [currentTime.get_year(), 0];
 	}
 
-        let targetName = Format.vprintf('%s-%d.%d-%s.json', [this._prefix, currentTime.get_year(),
-							     latestVersion[1] + 1, csum]);
+        let targetName = Format.vprintf('%d.%d-%s.json', [currentTime.get_year(), latestVersion[1] + 1, csum]);
         let targetPath = this._path.get_child(targetName);
 	targetPath.replace_contents(buf, null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, cancellable);
 
diff --git a/src/ostbuild/js/main.js b/src/ostbuild/js/main.js
index 226a60a..2efc192 100755
--- a/src/ostbuild/js/main.js
+++ b/src/ostbuild/js/main.js
@@ -15,41 +15,83 @@
 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 // Boston, MA 02111-1307, USA.
 
+const GLib = imports.gi.GLib;
+
 const Format = imports.format;
 
-const BUILTINS = {'autobuilder': "Run resolve and build",
-                  'checkout': "Check out source tree",
-                  'prefix': "Display or modify \"prefix\" (build target)",
-                  'git-mirror': "Update internal git mirror for one or more components",
-                  'resolve': "Expand git revisions in source to exact targets",
-                  'build': "Build multiple components and generate trees",
-                  'shell': "Interactive JavaScript shell",
-                  'qa-make-disk': "Generate a bare disk image",
-                  'qa-build-disks': "Build disks",
-		  'qa-pull-deploy': "Copy OSTree repo into virtual disk and deploy it",
-		  'qa-smoketest': "Basic smoke testing via parsing serial console"};
+const BUILTINS = ['autobuilder',
+                  'checkout',
+                  'prefix',
+                  'git-mirror',
+                  'resolve',
+                  'build',
+                  'shell',
+                  'qa-make-disk',
+                  'qa-build-disks',
+		  'qa-pull-deploy',
+		  'qa-smoketest'];
+
+function getModule(unixName) {
+    return imports.builtins[unixName.replace(/-/g, '_')];
+}
+
+function getClass(unixName) {
+    let module = getModule(unixName);
+    let camelParts = unixName.split(/-/);
+    let camel = camelParts.map(function (part) {
+	return part[0].toLocaleUpperCase() + part.substr(1);
+    }).join('');
+    return module[camel];
+}
 
 function usage(ecode) {
     print("Builtins:");
-    for (let builtin in BUILTINS) {
-	let description = BUILTINS[builtin];
-        print(Format.vprintf("    %s - %s", [builtin, description]));
+    for (let i = 0; i < BUILTINS.length; i++) {
+	let unixName = BUILTINS[i];
+	let description = getClass(unixName).prototype.DESCRIPTION;
+        print(Format.vprintf("    %s - %s", [unixName, description]));
     }
     return ecode;
 }
 
+let ecode;
 if (ARGV.length < 1) {
-    usage(1);
+    ecode = usage(1);
 } else if (ARGV[0] == '-h' || ARGV[0] == '--help') {
-    usage(0);
+    ecode = usage(0);
 } else {
     let name = ARGV[0];
-    if (!BUILTINS[name]) {
+    let found = false;
+    for (let i = 0; i < BUILTINS.length; i++) {
+	if (BUILTINS[i] == name) {
+	    found = true;
+	    break;
+	}
+    }
+    if (!found) {
 	usage(1);
+    } else {
+	let argv = ARGV.concat();
+	argv.shift();
+
+	let ecode = 1;
+	let loop = GLib.MainLoop.new(null, true);
+	let cls = getClass(name);
+	let instance = new cls;
+	let cancellable = null;
+	GLib.idle_add(GLib.PRIORITY_DEFAULT,
+		      function() {
+			  try {
+			      instance.main(argv, loop, cancellable); ecode = 0;
+			  } finally {
+			      loop.quit();
+			  }
+			  return false;
+		      });
+	loop.run();
     }
-    let args = ARGV.concat();
-    args.shift();
-    imports.builtins[name.replace(/-/g, '_')].main(args);
 }
+ecode;
+
     
     
diff --git a/src/ostbuild/js/snapshot.js b/src/ostbuild/js/snapshot.js
index 2ee2b5e..2d6846b 100644
--- a/src/ostbuild/js/snapshot.js
+++ b/src/ostbuild/js/snapshot.js
@@ -94,20 +94,6 @@ const Snapshot = new Lang.Class({
 	return r;
     },
 
-    loadFromDb: function(db, prefix, snapshotPath, cancellable) {
-	let data, path;
-	if (snapshotPath) {
-	    path = Gio.File.new_for_path(snapshotPath);
-	    data = JsonUtil.loadJson(path, cancellable);
-	} else if (prefix) {
-	    path = db.getLatestPath();
-	    data = db.loadFromPath(path, cancellable);
-	} else {
-	    throw new Error("No prefix or snapshot specified");
-	}
-	return new Snapshot(data, path);
-    },
-
     getAllComponentNames: function() {
 	return this._componentNames;
     },



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