[gnome-ostree/wip/gjs-round2] Rewrite checkout in gjs
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-ostree/wip/gjs-round2] Rewrite checkout in gjs
- Date: Sat, 8 Dec 2012 18:54:47 +0000 (UTC)
commit f4755dd6f1fbcf18f013f9e81a61aa46324b42d5
Author: Colin Walters <walters verbum org>
Date: Thu Dec 6 22:24:46 2012 -0500
Rewrite checkout in gjs
And add lots more infrastructure for that.
Makefile-ostbuild.am | 10 ++-
Makefile.am | 1 +
src/libgsystem | 2 +-
src/ostbuild/js/argparse.js | 142 +++++++++++++++++++++++++++
src/ostbuild/js/autobuilder.js | 6 +-
src/ostbuild/js/buildutil.js | 39 ++++++++
src/ostbuild/js/checkout.js | 124 +++++++++++++++++++++++
src/ostbuild/js/params.js | 35 +++++++
src/ostbuild/js/procutil.js | 63 +++++++++++--
src/ostbuild/js/snapshot.js | 45 +++++++++
src/ostbuild/js/vcs.js | 135 +++++++++++++++++++++++++
src/ostbuild/pyostbuild/builtin_checkout.py | 120 ----------------------
src/ostbuild/pyostbuild/main.py | 6 +-
13 files changed, 592 insertions(+), 136 deletions(-)
---
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index eff0a1a..3ee047c 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -45,7 +45,6 @@ pyostbuilddir=$(libdir)/ostbuild/pyostbuild
pyostbuild_PYTHON = \
src/ostbuild/pyostbuild/buildutil.py \
src/ostbuild/pyostbuild/builtin_build.py \
- src/ostbuild/pyostbuild/builtin_checkout.py \
src/ostbuild/pyostbuild/builtin_deploy_qemu.py \
src/ostbuild/pyostbuild/builtin_deploy_root.py \
src/ostbuild/pyostbuild/builtin_import_tree.py \
@@ -75,13 +74,18 @@ pyostbuild_PYTHON = \
jsostbuilddir=$(pkgdatadir)/js
jsostbuild_DATA= \
+ src/ostbuild/js/argparse.js \
src/ostbuild/js/autobuilder.js \
+ src/ostbuild/js/buildutil.js \
+ src/ostbuild/js/checkout.js \
src/ostbuild/js/config.js \
src/ostbuild/js/jsondb.js \
- src/ostbuild/js/task.js \
+ src/ostbuild/js/jsonutil.js \
+ src/ostbuild/js/params.js \
src/ostbuild/js/procutil.js \
src/ostbuild/js/snapshot.js \
- src/ostbuild/js/jsonutil.js \
+ src/ostbuild/js/task.js \
+ src/ostbuild/js/vcs.js \
$(NULL)
endif
diff --git a/Makefile.am b/Makefile.am
index f9b7fb7..4386e8b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -51,6 +51,7 @@ GSystem_1_0_gir_LIBS = libgsystem.la
GSystem_1_0_gir_CFLAGS = $(libgsystem_cflags)
GSystem_1_0_gir_SCANNERFLAGS = \
--warn-all \
+ --warn-error \
--symbol-prefix=gs_ \
--identifier-prefix=GS \
--c-include="libgsystem.h" \
diff --git a/src/libgsystem b/src/libgsystem
index dd1b303..aac3668 160000
--- a/src/libgsystem
+++ b/src/libgsystem
@@ -1 +1 @@
-Subproject commit dd1b3032b4cd175c2a9b2c611a62525454bad772
+Subproject commit aac3668399f8058877cf21ba35617ec4cfecd500
diff --git a/src/ostbuild/js/argparse.js b/src/ostbuild/js/argparse.js
new file mode 100644
index 0000000..92ef802
--- /dev/null
+++ b/src/ostbuild/js/argparse.js
@@ -0,0 +1,142 @@
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
+
+const ArgumentParser = new Lang.Class({
+ Name: 'ArgumentParser',
+
+ _init: function(description) {
+ this.description = description;
+ this._opts = [];
+ this._namedArgs = [];
+ this._optNames = {};
+ this._argNames = {};
+ },
+
+ usage: function() {
+ let buf = 'Usage: ' + this.description + '\n';
+ for (let i = 0; i < this._opts.length; i++) {
+ let opt = this._opts[i];
+ let names = this._opts._names;
+ for (let j = 0; j < names.length; j++) {
+ let name = names[j];
+ buf += name;
+ if (j < names.length - 1)
+ buf += ", ";
+ }
+ if (opt.description)
+ buf += ' ' + opt.description;
+ buf += '\n';
+ }
+ for (let i = 0; i < this._namedArgs.length; i++) {
+ let arg = this._namedArgs[i];
+ buf += arg + "\n";
+ }
+ return buf;
+ },
+
+ addArgument: function(nameOrNames, opts) {
+ if (!opts)
+ opts = {};
+ let names;
+ if (nameOrNames instanceof Array)
+ names = nameOrNames;
+ else
+ names = [nameOrNames];
+
+ if (opts.action == undefined)
+ opts.action = 'store';
+
+ if (names.length == 0) {
+ throw new Error("Must specify at least one argument");
+ } else if (names.length == 1 && names[0][0] != '-') {
+ let name = names[0];
+ this._namedArgs.push(opts);
+ this._argNames[name] = opts;
+ opts._varName = name;
+ } else {
+ opts._names = names;
+ this._opts.push(opts);
+
+ opts._varName = null;
+
+ let shortOpt = null;
+
+ for (let i = 0; i < names.length; i++) {
+ let name = names[i];
+ if (this._optNames[name]) {
+ throw new Error("Argument " + name + " already added");
+ } else if (names.length != 1 && name[0] != '-') {
+ throw new Error("Argument " + name + " does not start with -");
+ }
+
+ this._optNames[name] = opts;
+ if (opts._varName == null) {
+ if (name.indexOf('--') == 0)
+ opts._varName = name.substr(2);
+ else if (shortOpt == null && name[0] == '-' && name[1] != '-')
+ shortOpt = name.substr(1);
+ }
+ }
+ if (opts._varName == null)
+ opts._varName = shortOpt;
+ }
+ },
+
+ _failed: function() {
+ print(this.usage());
+ throw new Error("Argument parsing failed");
+ },
+
+ parse: function(argv) {
+ let result = {};
+ let rest = [];
+
+ for (let name in this._optNames) {
+ let opts = this._optNames[name];
+ if (opts.action == 'store') {
+ result[opts._varName] = null;
+ } else if (opts.action == 'storeTrue') {
+ result[opts._varName] = false;
+ }
+ }
+ for (let name in this._argNames) {
+ result[name] = null;
+ }
+
+ let rest = [];
+
+ for (let i = 0; i < argv.length; i++) {
+ let arg = argv[i];
+ if (arg[0] == '-') {
+ let equalsIdx = arg.indexOf('=');
+ let opts;
+ if (equalsIdx != -1)
+ opts = this._optNames[arg.substr(0, equalsIdx)];
+ else
+ opts = this._optNames[arg];
+
+ if (!opts) this._failed();
+
+ if (opts.action == 'store') {
+ if (i == argv.length - 1) this._failed();
+ result[opts._varName] = argv[i+1];
+ i++;
+ } else if (opts.action == 'storeTrue') {
+ result[opts._varName] = true;
+ i++;
+ }
+ } else {
+ rest.push(arg);
+ }
+ }
+
+ for (let i = 0; i < this._namedArgs.length; i++) {
+ let a = this._namedArgs[i];
+ if (rest.length == 0) this._failed();
+ let value = rest.shift();
+ result[a._varName] = value;
+ }
+
+ return result;
+ }
+});
diff --git a/src/ostbuild/js/autobuilder.js b/src/ostbuild/js/autobuilder.js
index c6e9d63..f261856 100644
--- a/src/ostbuild/js/autobuilder.js
+++ b/src/ostbuild/js/autobuilder.js
@@ -12,6 +12,7 @@ const JsonDB = imports.jsondb;
const ProcUtil = imports.procutil;
const JsonUtil = imports.jsonutil;
const Snapshot = imports.snapshot;
+const Config = imports.config;
const loop = GLib.MainLoop.new(null, true);
@@ -32,7 +33,7 @@ const AutoBuilder = new Lang.Class({
this._resolve_proc = null;
this._build_proc = null;
- this.config = imports.config.get();
+ 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');
@@ -109,6 +110,7 @@ const AutoBuilder = new Lang.Class({
},
_fetch: function() {
+ let cancellable = null;
if (this._resolve_proc != null) {
this._full_resolve_needed = true;
return false;
@@ -117,7 +119,7 @@ const AutoBuilder = new Lang.Class({
let taskWorkdir = t.path;
if (this._autoupdate_self)
- ProcUtil.runSync(['git', 'pull', '-r'])
+ ProcUtil.runSync(['git', 'pull', '-r'], cancellable)
let args = ['ostbuild', 'resolve', '--manifest=manifest.json',
'--fetch', '--fetch-keep-going'];
diff --git a/src/ostbuild/js/buildutil.js b/src/ostbuild/js/buildutil.js
new file mode 100644
index 0000000..4a26373
--- /dev/null
+++ b/src/ostbuild/js/buildutil.js
@@ -0,0 +1,39 @@
+// 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 BUILD_ENV = {
+ 'HOME' : '/',
+ 'HOSTNAME' : 'ostbuild',
+ 'LANG': 'C',
+ 'PATH' : '/usr/bin:/bin:/usr/sbin:/sbin',
+ 'SHELL' : '/bin/bash',
+ 'TERM' : 'vt100',
+ 'TMPDIR' : '/tmp',
+ 'TZ': 'EST5EDT'
+ };
+
+function parseSrcKey(srckey) {
+ let idx = srckey.indexOf(':');
+ if (idx < 0) {
+ throw new Error("Invalid SRC uri=" + srckey);
+ }
+ let keytype = srckey.substr(0, idx);
+ if (!(keytype == 'git' || keytype == 'local'))
+ throw new Error("Unsupported SRC uri=" + srckey);
+ let uri = srckey.substr(idx+1);
+ return [keytype, uri];
+}
diff --git a/src/ostbuild/js/checkout.js b/src/ostbuild/js/checkout.js
new file mode 100644
index 0000000..e24072b
--- /dev/null
+++ b/src/ostbuild/js/checkout.js
@@ -0,0 +1,124 @@
+#!/usr/bin/env gjs
+
+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;
+
+const loop = GLib.MainLoop.new(null, true);
+
+const Checkout = new Lang.Class({
+ Name: 'Checkout',
+
+ _init: function() {
+ },
+
+ 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'));
+ 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.load(this._srcDb, this.prefix, args.snapshot, cancellable);
+
+ let componentName = args.component;
+
+ let component;
+ if (args.metadata_path != null) {
+ component = JsonUtil.load(Gio.File.new_for_path(args.metadata_path));
+ } else {
+ component = Snapshot.getExpanded(this._snapshot, componentName);
+ }
+ let [keytype, uri] = BuildUtil.parseSrcKey(component['src']);
+
+ let isLocal = (keytype == 'local');
+
+ let checkoutdir;
+ if (isLocal) {
+ if (args.checkoutdir != null) {
+ checkoutdir = Gio.File.new_for_path(args.checkoutdir);
+ let ftype = checkoutdir.query_file_type(Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
+ // Kind of a hack, but...
+ if (ftype == Gio.FileType.SYMBOLIC_LINK)
+ GSystem.file_unlink(checkoutdir, cancellable);
+ if (args.overwrite && ftype == Gio.FileType.DIRECTORY)
+ GSystem.shutil_rm_rf(checkoutdir, cancellable);
+
+ checkoutdir.make_symbolic_link(uri, cancellable);
+ } else {
+ checkoutdir = Gio.File.new_for_path(uri);
+ }
+ } else {
+ if (args.checkoutdir) {
+ checkoutdir = Gio.File.new_for_path(args.checkoutdir);
+ } else {
+ checkoutdir = Gio.File.new_for_path(componentName);
+ GSystem.file_ensure_directory(checkoutdir.get_parent(), true, cancellable);
+ }
+ Vcs.getVcsCheckout(this.mirrordir, keytype, uri, checkoutdir,
+ component['revision'], cancellable,
+ {overwrite: args.overwrite});
+ }
+
+ if (args.clean) {
+ if (isLocal) {
+ log("note: ignoring --clean argument due to \"local:\" specification");
+ } else {
+ Vcs.clean(keytype, checkoutdir, cancellable);
+ }
+ }
+
+ if (component['patches']) {
+ if (args.patches_path == null) {
+ patchdir = Vcs.checkoutPatches(this.mirrordir, this.patchdir, component);
+ } else {
+ patchdir = args.patches_path
+ }
+ patches = BuildUtil.getPatchPathsForComponent(patchdir, component)
+ for (let i = 0; i < patches.length; i++) {
+ let patch = patches[i];
+ ProcUtil.runSync(['git', 'am', '--ignore-date', '-3', patch], cancellable,
+ {cwd:checkoutdir.get_path()});
+ }
+ }
+
+ let metadataPath = checkoutdir.get_child('_ostbuild-meta.json');
+ JsonUtil.writeJsonFileAtomic(metadataPath, component, cancellable);
+
+ log("Checked out: " + checkoutdir.get_path());
+ }
+});
+
+var checkout = new Checkout();
+GLib.idle_add(GLib.PRIORITY_DEFAULT,
+ function() { try { checkout.execute(ARGV); } finally { loop.quit(); }; return false; });
+loop.run();
diff --git a/src/ostbuild/js/params.js b/src/ostbuild/js/params.js
new file mode 100644
index 0000000..3b3798b
--- /dev/null
+++ b/src/ostbuild/js/params.js
@@ -0,0 +1,35 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+// Taken from gnome-shell/js/misc/params.js under the GNU General Public License
+// parse:
+// @params: caller-provided parameter object, or %null
+// @defaults: function-provided defaults object
+// @allowExtras: whether or not to allow properties not in @default
+//
+// Examines @params and fills in default values from @defaults for
+// any properties in @defaults that don't appear in @params. If
+// @allowExtras is not %true, it will throw an error if @params
+// contains any properties that aren't in @defaults.
+//
+// If @params is %null, this returns the values from @defaults.
+//
+// Return value: a new object, containing the merged parameters from
+// @params and @defaults
+function parse(params, defaults, allowExtras) {
+ let ret = {}, prop;
+
+ if (!params)
+ params = {};
+
+ for (prop in params) {
+ if (!(prop in defaults) && !allowExtras)
+ throw new Error('Unrecognized parameter "' + prop + '"');
+ ret[prop] = params[prop];
+ }
+
+ for (prop in defaults) {
+ if (!(prop in params))
+ ret[prop] = defaults[prop];
+ }
+
+ return ret;
+}
diff --git a/src/ostbuild/js/procutil.js b/src/ostbuild/js/procutil.js
index 69c65b6..fe387a8 100644
--- a/src/ostbuild/js/procutil.js
+++ b/src/ostbuild/js/procutil.js
@@ -2,16 +2,65 @@ const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GSystem = imports.gi.GSystem;
+const Params = imports.params;
-function runSync(args, stdoutDisposition, stderrDisposition) {
- if (stdoutDisposition == undefined)
- stdoutDisposition = GSystem.SubprocessStreamDisposition.INHERIT;
- if (stderrDisposition == undefined)
- stderrDisposition = GSystem.SubprocessStreamDisposition.INHERIT;
- var proc = GSystem.Subprocess.new_simple_argv(args, stdoutDisposition, stderrDisposition);
- proc.wait_sync_check(null);
+function _setContextFromParams(context, params) {
+ params = Params.parse(params, {cwd: null});
+ if (params.cwd)
+ context.set_cwd(params.cwd);
}
+function _wait_sync_check_internal(proc, cancellable) {
+ try {
+ proc.wait_sync_check(cancellable);
+ } catch (e) {
+ if (e.domain == GLib.spawn_exit_error_quark() ||
+ e.matches(GLib.SpawnError, GLib.SpawnError.FAILED))
+ throw new Error(Format.vprintf("Child process %s: %s", [JSON.stringify(proc.context.argv), e.message]));
+ else
+ throw e;
+ }
+}
+
+function runSync(args, cancellable, params) {
+ let context = new GSystem.SubprocessContext({argv: args});
+ _setContextFromParams(context, params);
+ let proc = new GSystem.Subprocess({context: context});
+ proc.init(cancellable);
+ _wait_sync_check_internal(proc, cancellable);
+}
+
+function _runSyncGetOutputInternal(args, cancellable, params, splitLines) {
+ params = Params.parse(params, {cwd: null});
+ let context = new GSystem.SubprocessContext({argv: args});
+ context.set_stdout_disposition(GSystem.SubprocessStreamDisposition.PIPE);
+ context.set_stderr_disposition(GSystem.SubprocessStreamDisposition.INHERIT);
+ let proc = new GSystem.Subprocess({context: context});
+ proc.init(cancellable);
+ let input = proc.get_stdout_pipe();
+ let dataIn = Gio.DataInputStream.new(input);
+ let resultLines = [];
+ let resultBuf = '';
+ while (true) {
+ let [line, len] = dataIn.read_line_utf8(cancellable);
+ if (line == null)
+ break;
+ if (splitLines)
+ resultLines.push(line);
+ else
+ resultBuf += line;
+ }
+ _wait_sync_check_internal(proc, cancellable);
+ return splitLines ? resultLines : resultBuf;
+}
+
+function runSyncGetOutputLines(args, cancellable, params) {
+ return _runSyncGetOutputInternal(args, cancellable, params, true);
+}
+
+function runSyncGetOutputUTF8(args, cancellable, params) {
+ return _runSyncGetOutputInternal(args, cancellable, params, false);
+}
function asyncWaitCheckFinish(process, result) {
let [waitSuccess, estatus] = process.wait_finish(result);
diff --git a/src/ostbuild/js/snapshot.js b/src/ostbuild/js/snapshot.js
index f24369c..0038c8a 100644
--- a/src/ostbuild/js/snapshot.js
+++ b/src/ostbuild/js/snapshot.js
@@ -16,6 +16,8 @@
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
+const JsonDB = imports.jsondb;
+
function _componentDict(snapshot) {
let r = {};
let components = snapshot['components'];
@@ -55,3 +57,46 @@ function snapshotDiff(a, b) {
}
return [added, modified, removed];
}
+
+function load(db, prefix, pathName, cancellable) {
+ if (pathName) {
+ return db.loadFromPath(Gio.File.new_for_path(pathName), cancellable);
+ } else if (prefix) {
+ return db.loadFromPath(db.getLatestPath(), cancellable);
+ } else {
+ throw new Error("No prefix or snapshot specified");
+ }
+}
+
+function getComponent(snapshot, name, allowNone) {
+ let d = _componentDict(snapshot);
+ let r = d[name] || null;
+ if (!r && !allowNone)
+ throw new Error("No component " + name + " in snapshot");
+ return r;
+}
+
+function expandComponent(snapshot, component) {
+ let r = {};
+ Lang.copyProperties(component, r);
+ let patchMeta = getComponent(snapshot, 'patches', true);
+ if (patchMeta != null) {
+ let componentPatchFiles = component['patches'] || [];
+ if (componentPatchFiles.length > 0) {
+ let patches = {};
+ Lang.copyProperties(patchMeta, patches);
+ patches['files'] = componentPatchFiles;
+ r['patches'] = patches;
+ }
+ }
+ let configOpts = new Array(snapshot['config-opts'] || []);
+ configOpts.push.apply(configOpts, component['config-opts'] || []);
+ r['config-opts'] = configOpts;
+ return r;
+}
+
+function getExpanded(snapshot, name) {
+ return expandComponent(snapshot, getComponent(snapshot, name));
+}
+
+
diff --git a/src/ostbuild/js/vcs.js b/src/ostbuild/js/vcs.js
new file mode 100644
index 0000000..168b474
--- /dev/null
+++ b/src/ostbuild/js/vcs.js
@@ -0,0 +1,135 @@
+// Copyright (C) 2011,2012 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 Params = imports.params;
+const Gio = imports.gi.Gio;
+const GSystem = imports.gi.GSystem;
+
+const ProcUtil = imports.procutil;
+
+function getMirrordir(mirrordir, keytype, uri, params) {
+ params = Params.parse(params, {prefix: ''});
+ let colon = uri.indexOf('://');
+ let scheme = uri.substr(0, colon);
+ let rest = uri.substr(colon+3);
+ let slash = rest.indexOf('/');
+ let netloc = rest.substr(0, slash);
+ let path = rest.substr(slash+1);
+ let prefix = params.prefix ? params.prefix + '/' : '';
+ return mirrordir.resolve_relative_path(prefix + keytype + '/' +
+ scheme + '/' + netloc + '/' +
+ path);
+}
+
+function _fixupSubmoduleReferences(mirrordir, cwd, cancellable) {
+ let lines = ProcUtil.runSyncGetOutputLines(['git', 'submodule', 'status'],
+ cancellable, {cwd: cwd.get_path()});
+ let haveSubmodules = false;
+ for (let i = 0; i < lines.length; i++) {
+ let line = lines[i];
+ if (line == '') continue;
+ haveSubmodules = true;
+ line = line.substr(1);
+ let [subChecksum, subName, rest] = line.split(' ');
+ let configKey = Format.vprintf('submodule.%s.url', [subName]);
+ let subUrl = ProcUtil.runSyncGetOutputUTF8(['git', 'config', '-f', '.gitmodules', configKey],
+ cancellable, {cwd: cwd.get_path()});
+ let localMirror = getMirrordir(mirrordir, 'git', subUrl);
+ ProcUtil.runSync(['git', 'config', configKey, 'file://' + localMirror.get_path()],
+ cancellable, {cwd:cwd.get_path()});
+ }
+ return haveSubmodules;
+}
+
+function getVcsCheckout(mirrordir, keytype, uri, dest, branch, cancellable, params) {
+ params = Params.parse(params, {overwrite: true,
+ quiet: false});
+ let moduleMirror = getMirrordir(mirrordir, keytype, uri);
+ let checkoutdirParent = dest.get_parent();
+ GSystem.file_ensure_directory(checkoutdirParent, true, cancellable);
+ let tmpDest = checkoutdirParent.get_child(dest.get_basename() + '.tmp');
+ GSystem.shutil_rm_rf(tmpDest, cancellable);
+ let ftype = dest.query_file_type(Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, cancellable);
+ if (ftype == Gio.FileType.SYMBOLIC_LINK) {
+ GSystem.file_unlink(dest, cancellable);
+ } else if (ftype == Gio.FileType.DIRECTORY) {
+ if (params.overwrite) {
+ GSystem.shutil_rm_rf(dest);
+ } else {
+ tmpDest = dest;
+ }
+ }
+ ftype = tmpDest.query_file_type(Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, cancellable);
+ if (ftype != Gio.FileType.DIRECTORY) {
+ ProcUtil.runSync(['git', 'clone', '-q', '--origin', 'localmirror',
+ '--no-checkout', moduleMirror.get_path(), tmpDest.get_path()], cancellable);
+ ProcUtil.runSync(['git', 'remote', 'add', 'upstream', uri], cancellable, {cwd: tmpDest.get_path()});
+ } else {
+ ProcUtil.runSync(['git', 'fetch', 'localmirror'], cancellable, {cwd: tmpDest.get_path()});
+ }
+ ProcUtil.runSync(['git', 'checkout', '-q', branch], cancellable, {cwd: tmpDest.get_path()});
+ ProcUtil.runSync(['git', 'submodule', 'init'], cancellable, {cwd: tmpDest.get_path()});
+ let haveSubmodules = _fixupSubmoduleReferences(mirrordir, tmpDest, cancellable);
+ if (haveSubmodules) {
+ ProcUtil.runSync(['git', 'submodule', 'update'], cancellable, {cwd: tmpDest.get_path()});
+ }
+ if (!tmpDest.equal(dest)) {
+ GSystem.file_rename(tmpDest, dest, cancellable);
+ }
+ return dest;
+}
+
+function clean(keytype, checkoutdir, cancellable) {
+ ProcUtil.runSync(['git', 'clean', '-d', '-f', '-x'], cancellable,
+ {cwd: checkoutdir.get_path()});
+}
+
+function parseSrcKey(srckey) {
+ let idx = srckey.indexOf(':');
+ if (idx < 0) {
+ throw new Error("Invalid SRC uri=" + srckey);
+ }
+ let keytype = srckey.substr(0, idx);
+ if (!(keytype == 'git' || keytype == 'local')) {
+ throw new Error("Unsupported SRC uri=" + srckey);
+ }
+ let uri = srckey.substr(idx+1);
+ return [keytype, uri];
+}
+
+function checkoutPatches(mirrordir, patchdir, component, cancellable, params) {
+ params = Params.parse(params, { patches_path: null });
+ let patches = component['patches'];
+ let patches_keytype = null;
+ let patches_uri = null;
+ if (params.patches_path != null) {
+ patches_keytype = local;
+ patches_uri = patches_path;
+ patchdir = patches_uri;
+ } else {
+ [patches_keytype, patches_uri] = parseSrcKey(patches['src']);
+ let patchesMirror = getMirrordir(mirrordir, patches_keytype, patches_uri);
+ getVcsCheckout(mirrordir, patches_keytype, patches_uri,
+ patchdir, patches['revision'], cancellable,
+ {overwrite: true,
+ quiet: true});
+ }
+
+ return patchdir;
+}
+
+
diff --git a/src/ostbuild/pyostbuild/main.py b/src/ostbuild/pyostbuild/main.py
index 2c4d4a3..0c7939c 100755
--- a/src/ostbuild/pyostbuild/main.py
+++ b/src/ostbuild/pyostbuild/main.py
@@ -23,7 +23,6 @@ import argparse
from . import builtins
from . import builtin_build
-from . import builtin_checkout
from . import builtin_deploy_root
from . import builtin_deploy_qemu
from . import builtin_git_mirror
@@ -33,7 +32,8 @@ from . import builtin_privhelper_deploy_qemu
from . import builtin_resolve
from . import builtin_source_diff
-JS_BUILTINS = {'autobuilder': 'Run resolve and build'}
+JS_BUILTINS = {'autobuilder': 'Run resolve and build',
+ 'checkout': 'Check out source tree'}
def usage(ecode):
print "Builtins:"
@@ -60,7 +60,7 @@ def main(args):
return usage(1)
else:
child_args = ['ostbuild-js', name]
- child_args.extend(args[:1])
+ child_args.extend(args[1:])
os.execvp('ostbuild-js', child_args)
return builtin.execute(args[1:])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]