[gnome-ostree/wip/gjs-round2: 6/9] Port resolve to gjs



commit e0bfa21026db3de49746e29f6003c7861076ae5f
Author: Colin Walters <walters verbum org>
Date:   Sun Dec 9 16:24:31 2012 -0500

    Port resolve to gjs
    
    Almost there...

 Makefile-ostbuild.am                       |    2 +-
 src/ostbuild/js/argparse.js                |    1 -
 src/ostbuild/js/buildutil.js               |    5 +-
 src/ostbuild/js/jsondb.js                  |   41 ++++++++-
 src/ostbuild/js/resolve.js                 |  150 ++++++++++++++++++++++++++++
 src/ostbuild/js/vcs.js                     |    8 ++
 src/ostbuild/pyostbuild/builtin_resolve.py |  134 -------------------------
 src/ostbuild/pyostbuild/main.py            |    4 +-
 8 files changed, 204 insertions(+), 141 deletions(-)
---
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index 6a09567..7556b15 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -47,7 +47,6 @@ pyostbuild_PYTHON =					\
 	src/ostbuild/pyostbuild/builtin_build.py	\
 	src/ostbuild/pyostbuild/builtin_deploy_qemu.py	\
 	src/ostbuild/pyostbuild/builtin_privhelper_deploy_qemu.py	\
-	src/ostbuild/pyostbuild/builtin_resolve.py	\
 	src/ostbuild/pyostbuild/builtin_source_diff.py	\
 	src/ostbuild/pyostbuild/builtins.py		\
 	src/ostbuild/pyostbuild/filemonitor.py		\
@@ -81,6 +80,7 @@ jsostbuild_DATA= \
 	src/ostbuild/js/params.js \
 	src/ostbuild/js/prefix.js \
 	src/ostbuild/js/procutil.js \
+	src/ostbuild/js/resolve.js \
 	src/ostbuild/js/snapshot.js \
 	src/ostbuild/js/task.js \
 	src/ostbuild/js/vcs.js \
diff --git a/src/ostbuild/js/argparse.js b/src/ostbuild/js/argparse.js
index b1867ca..475d35a 100644
--- a/src/ostbuild/js/argparse.js
+++ b/src/ostbuild/js/argparse.js
@@ -133,7 +133,6 @@ const ArgumentParser = new Lang.Class({
 		    }
 		} else if (opts.action == 'storeTrue') {
 		    result[opts._varName] = true;
-		    i++;
 		}
 	    } else {
 		rest.push(arg);
diff --git a/src/ostbuild/js/buildutil.js b/src/ostbuild/js/buildutil.js
index 8a615f6..0d8fe0e 100644
--- a/src/ostbuild/js/buildutil.js
+++ b/src/ostbuild/js/buildutil.js
@@ -67,7 +67,8 @@ function resolveComponent(manifest, componentMeta) {
             idx = src.lastIndexOf('/');
             name = src.substr(idx+1);
 	}
-        if (name.lastIndexOf('.git') == name.length - 4) {
+	let i = name.lastIndexOf('.git');
+        if (i != -1 && i == name.length - 4) {
             name = name.substr(0, name.length - 4);
 	}
         name = name.replace(/\//g, '-');
@@ -78,6 +79,6 @@ function resolveComponent(manifest, componentMeta) {
     if (!branchOrTag) {
         result['branch'] = 'master';
     }
-    
+
     return result;
 }
diff --git a/src/ostbuild/js/jsondb.js b/src/ostbuild/js/jsondb.js
index 79d8da4..41fd943 100644
--- a/src/ostbuild/js/jsondb.js
+++ b/src/ostbuild/js/jsondb.js
@@ -12,6 +12,7 @@ const JsonDB = new Lang.Class({
 	this._path = path;
 	this._prefix = prefix;
 	this._re = /-(\d+)\.(\d+)-([0-9a-f]+).json$/;
+	this._maxVersions = 5;
     },
 
     parseVersion: function(basename) {
@@ -34,7 +35,7 @@ const JsonDB = new Lang.Class({
 	    let name = info.get_name();
 	    if (name.indexOf(this._prefix) != 0)
 		continue;
-	    if (name.lastIndexOf('.json') != name.length-5)
+	    if (name.length < 6 || name.lastIndexOf('.json') != name.length-5)
 		continue;
 	    let match = this._re.exec(name);
 	    if (!match)
@@ -82,5 +83,43 @@ const JsonDB = new Lang.Class({
 
     loadFromPath: function(path, cancellable) {
 	return JsonUtil.loadJson(this._path.get_child(path.get_basename()), cancellable);
+    },
+
+    store: function(obj, cancellable) {
+        let files = this._getAll();
+	let latest = null;
+        if (files.length > 0) {
+            latest = files[0];
+	}
+	
+	let currentTime = GLib.DateTime.new_now_utc();
+
+	let buf = JSON.stringify(obj);
+	let csum = GLib.compute_checksum_for_string(GLib.ChecksumType.SHA256, buf, -1);
+        
+	let latestVersion;
+        if (latest) {
+            if (csum == latest[2]) {
+                return [this._path.get_child(latest[3]), false];
+	    }
+            latestVersion = [latest[0], latest[1]];
+        } else {
+            latestVersion = [currentTime.get_year(), 0];
+	}
+
+        let targetName = Format.vprintf('%s-%d.%d-%s.json', [this._prefix, 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);
+
+        if (files.length + 1 > this._maxVersions) {
+	    for (let i = Math.max(files.length-(this._maxVersions-1), 0);
+		 i < files.length;
+		 i++) {
+		GSystem.file_unlink(this._path.get_child(files[i][3]), cancellable);
+	    }
+	}
+
+        return [targetPath, true];
     }
 });
diff --git a/src/ostbuild/js/resolve.js b/src/ostbuild/js/resolve.js
new file mode 100644
index 0000000..48c547e
--- /dev/null
+++ b/src/ostbuild/js/resolve.js
@@ -0,0 +1,150 @@
+// Copyright (C) 2011 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 Task = imports.task;
+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;
+
+var loop = GLib.MainLoop.new(null, true);
+
+const Resolve = new Lang.Class({
+    Name: "Resolve",
+
+    _init: function() {
+    },
+
+    execute: function(argv) {
+	let cancellable = null;
+        let parser = new ArgParse.ArgumentParser("Expand git revisions in source to exact targets");
+        parser.addArgument('--manifest', {required:true,
+					  help:"Path to manifest file"});
+        parser.addArgument('--fetch', {action:'storeTrue',
+					help:"Also perform a git fetch"});
+        parser.addArgument('--fetch-keep-going', {action:'storeTrue',
+						  help:"Don't exit on fetch failures"});
+        parser.addArgument('--stamp-file',
+                           {help: "If manifest changes, create this file"});
+        parser.addArgument('components', {nargs:'*',
+					  help:"List of component names to git fetch"});
+
+        let args = parser.parse(argv);
+
+	let componentsToFetch = {};
+	args.components.forEach(function (name) {
+	    componentsToFetch[name] = true;
+	});
+
+        if (args.components.length > 0 && !args.fetch) {
+            throw new Error("Can't specify components without --fetch");
+	}
+
+	this.config = Config.get();
+	this.workdir = Gio.File.new_for_path(this.config.getGlobal('workdir'));
+        this._snapshot = JsonUtil.loadJson(Gio.File.new_for_path(args.manifest), cancellable);
+	this._mirrordir = Gio.File.new_for_path(this.config.getGlobal('mirrordir'));
+        this.prefix = this._snapshot['prefix'];
+
+	let components = this._snapshot['components'];
+	let resolvedComponents = [];
+	for (let i = 0; i < components.length; i++) {
+	    resolvedComponents.push(BuildUtil.resolveComponent(this._snapshot, components[i]));
+	}
+        this._snapshot['components'] = components = resolvedComponents;
+
+        let uniqueComponentNames = {};
+        for (let i = 0; i < components.length; i++) {
+	    let component = components[i];
+            let name = component['name'];
+            if (uniqueComponentNames[name]) {
+                throw new Error("Duplicate component name " + name);
+	    }
+            uniqueComponentNames[name] = true;
+	}
+
+        let baseMeta = BuildUtil.resolveComponent(this._snapshot, this._snapshot['base']);
+        this._snapshot['base'] = baseMeta;
+        let [keytype, uri] = Vcs.parseSrcKey(baseMeta['src']);
+        let mirrordir = Vcs.ensureVcsMirror(this._mirrordir, keytype, uri, baseMeta['branch'], cancellable);
+        if (componentsToFetch[baseMeta['name']]) {
+            ProcUtil.runSync(['git', 'fetch'], cancellable, {cwd:mirrordir});
+	}
+
+        let baseRevision = Vcs.describeVersion(mirrordir, baseMeta['branch']);
+        baseMeta['revision'] = baseRevision;
+
+        let globalPatchesMeta = BuildUtil.resolveComponent(this._snapshot, this._snapshot['patches']);
+        this._snapshot['patches'] = globalPatchesMeta;
+        let [keytype, uri] = Vcs.parseSrcKey(globalPatchesMeta['src']);
+        let mirrordir = Vcs.ensureVcsMirror(this._mirrordir, keytype, uri, globalPatchesMeta['branch'], cancellable);
+        if (componentsToFetch[globalPatchesMeta['name']]) {
+            ProcUtil.runSync(['git', 'fetch'], cancellable,
+			     {cwd:mirrordir});
+	}
+
+        let gitMirrorArgs = ['ostbuild', 'git-mirror', '--manifest=' + args.manifest];
+        if (args.fetch) {
+            gitMirrorArgs.push('--fetch');
+            if (args.fetch_keep_going) {
+                gitMirrorArgs.push('-k');
+	    }
+            gitMirrorArgs.push.apply(gitMirrorArgs, args.components);
+	}
+        ProcUtil.runSync(gitMirrorArgs, cancellable);
+
+        let patchRevision = Vcs.describeVersion(mirrordir, globalPatchesMeta['branch']);
+        globalPatchesMeta['revision'] = patchRevision;
+
+        for (let i = 0; i < components.length; i++) {
+	    let component = components[i];
+            let src = component['src'];
+            let [keytype, uri] = Vcs.parseSrcKey(src);
+            let branch = component['branch'];
+            let tag = component['tag'];
+            let branchOrTag = branch || tag;
+            let mirrordir = Vcs.ensureVcsMirror(this._mirrordir, keytype, uri, branchOrTag, cancellable);
+            let revision = Vcs.describeVersion(mirrordir, branchOrTag);
+            component['revision'] = revision;
+	}
+
+	let snapshotdir = this.workdir.get_child('snapshots');
+	this._src_db = new JsonDB.JsonDB(snapshotdir, this.prefix + '-src-snapshot');
+        let [path, modified] = this._src_db.store(this._snapshot, cancellable);
+        if (modified) {
+            log("New source snapshot: " + path.get_path());
+        } else {
+            log("Source snapshot unchanged: " + path.get_path());
+	}
+    }
+});
+
+var resolve = new Resolve();
+GLib.idle_add(GLib.PRIORITY_DEFAULT,
+	      function() { try { resolve.execute(ARGV); } finally { loop.quit(); }; return false; });
+loop.run();
diff --git a/src/ostbuild/js/vcs.js b/src/ostbuild/js/vcs.js
index 34c4d9a..ab60044 100644
--- a/src/ostbuild/js/vcs.js
+++ b/src/ostbuild/js/vcs.js
@@ -216,3 +216,11 @@ function fetch(mirrordir, keytype, uri, branch, cancellable, params) {
     ensureVcsMirror(mirrordir, keytype, uri, branch, cancellable,
 		      {fetch:true, fetchKeepGoing: params.keepGoing});
 }
+
+function describeVersion(dirpath, branch) {
+    let args = ['git', 'describe', '--long', '--abbrev=42', '--always'];
+    if (branch) {
+        args.push(branch);
+    }
+    return ProcUtil.runSyncGetOutputUTF8(args, null, {cwd:dirpath}).replace(/[ \n]/g, '');
+}
diff --git a/src/ostbuild/pyostbuild/main.py b/src/ostbuild/pyostbuild/main.py
index 37b3ad6..f75f0bc 100755
--- a/src/ostbuild/pyostbuild/main.py
+++ b/src/ostbuild/pyostbuild/main.py
@@ -25,13 +25,13 @@ from . import builtins
 from . import builtin_build
 from . import builtin_deploy_qemu
 from . import builtin_privhelper_deploy_qemu
-from . import builtin_resolve
 from . import builtin_source_diff
 
 JS_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"};
+               'git-mirror': "Update internal git mirror for one or more components",
+               'resolve': "Expand git revisions in source to exact targets"};
 
 def usage(ecode):
     print "Builtins:"



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