[gnome-ostree/wip/integrated-build: 2/4] Move all sources into git submodules
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-ostree/wip/integrated-build: 2/4] Move all sources into git submodules
- Date: Wed, 26 Sep 2012 18:25:58 +0000 (UTC)
commit 606d66e0b3d978afa19020cd3b10f46e7b7bd52e
Author: Colin Walters <walters verbum org>
Date: Fri Sep 21 17:05:08 2012 -0400
Move all sources into git submodules
Git submodules were designed to do exactly what we're doing. While
they have some major drawbacks, I think the benefits outweigh the
drawbacks.
For example, we can speak of "git revision a19e3 of gnome-ostree"
which in turn points to exact revisions of every component. This makes
it far easier to do coordinated changes; you can send a patch that
touches three components, plus the manifest.
Makefile-ostbuild.am | 1 +
deleted-components/README | 2 +
gnomeos-3.6.json => manifest.json | 2 +-
src/ostbuild/pyostbuild/builtin_build.py | 51 ++------------
src/ostbuild/pyostbuild/builtin_fetch.py | 110 ++++++++++++++++++++++++++++++
src/ostbuild/pyostbuild/builtins.py | 79 +++++++--------------
src/ostbuild/pyostbuild/main.py | 1 +
7 files changed, 147 insertions(+), 99 deletions(-)
---
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..e69de29
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index b8035c4..246040c 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -39,6 +39,7 @@ pyostbuild_PYTHON = \
src/ostbuild/pyostbuild/builtin_checkout.py \
src/ostbuild/pyostbuild/builtin_deploy_qemu.py \
src/ostbuild/pyostbuild/builtin_deploy_root.py \
+ src/ostbuild/pyostbuild/builtin_fetch.py \
src/ostbuild/pyostbuild/builtin_run_qemu.py \
src/ostbuild/pyostbuild/builtin_import_tree.py \
src/ostbuild/pyostbuild/builtin_privhelper_deploy_qemu.py \
diff --git a/deleted-components/README b/deleted-components/README
new file mode 100644
index 0000000..0efb3f5
--- /dev/null
+++ b/deleted-components/README
@@ -0,0 +1,2 @@
+Components that used to exist but are no longer listed in the manifest
+are moved here for safety.
diff --git a/gnomeos-3.6.json b/manifest.json
similarity index 99%
rename from gnomeos-3.6.json
rename to manifest.json
index dea57a3..f97bed4 100644
--- a/gnomeos-3.6.json
+++ b/manifest.json
@@ -1,5 +1,5 @@
{
- "00ostbuild-manifest-version": 0,
+ "00ostbuild-manifest-version": 1,
"prefix": "gnomeos-3.6",
"architectures": ["i686"],
diff --git a/src/ostbuild/pyostbuild/builtin_build.py b/src/ostbuild/pyostbuild/builtin_build.py
index 7737f00..8928892 100755
--- a/src/ostbuild/pyostbuild/builtin_build.py
+++ b/src/ostbuild/pyostbuild/builtin_build.py
@@ -245,16 +245,7 @@ class OstbuildBuild(builtins.Builtin):
if 'patches' in expanded_component:
patches_revision = expanded_component['patches']['revision']
- if self.args.patches_path:
- patchdir = self.args.patches_path
- elif self.cached_patchdir_revision == patches_revision:
- patchdir = self.patchdir
- else:
- patchdir = vcs.checkout_patches(self.mirrordir,
- self.patchdir,
- expanded_component,
- patches_path=self.args.patches_path)
- self.cached_patchdir_revision = patches_revision
+ patchdir = os.path.join(self.srcdir, 'patches')
if ((previous_metadata is not None) and
'patches' in previous_metadata and
previous_metadata['patches']['revision'] == patches_revision):
@@ -286,22 +277,9 @@ class OstbuildBuild(builtins.Builtin):
json.dump(expanded_component, f, indent=4, sort_keys=True)
f.close()
- checkoutdir = os.path.join(self.workdir, 'checkouts')
- component_src = os.path.join(checkoutdir, buildname)
- fileutil.ensure_parent_dir(component_src)
- child_args = ['ostbuild', 'checkout', '--snapshot=' + self.snapshot_path,
- '--checkoutdir=' + component_src,
- '--metadata-path=' + temp_metadata_path]
+ component_src = self._component_abspath(expanded_component)
if not self.buildopts.no_clean:
- child_args.append('--clean')
- child_args.extend(['--overwrite', basename])
- if self.args.patches_path:
- child_args.append('--patches-path=' + self.args.patches_path)
- elif patchdir is not None:
- child_args.append('--patches-path=' + patchdir)
- run_sync(child_args)
-
- os.unlink(temp_metadata_path)
+ run_sync(['git', 'clean', '-d', '-f', '-x'], cwd=component_src)
logdir = os.path.join(self.workdir, 'logs', buildname)
fileutil.ensure_dir(logdir)
@@ -392,10 +370,6 @@ class OstbuildBuild(builtins.Builtin):
os.unlink(statoverride_path)
if not self.args.no_clean_results:
- if os.path.islink(component_src):
- os.unlink(component_src)
- else:
- shutil.rmtree(component_src)
shutil.rmtree(component_resultdir)
return run_sync_get_output(['ostree', '--repo=' + self.repo,
@@ -500,23 +474,16 @@ and the manifest input."""
def _build_base(self):
"""Build the Yocto base system."""
basemeta = self.snapshot['base']
- checkoutdir = os.path.join(self.workdir, 'checkouts', basemeta['name'])
- fileutil.ensure_parent_dir(checkoutdir)
-
- (keytype, uri) = buildutil.parse_src_key(basemeta['src'])
- vcs.get_vcs_checkout(self.mirrordir, keytype, uri, checkoutdir,
- basemeta['revision'],
- overwrite=False)
-
builddir = os.path.join(self.workdir, 'build-' + basemeta['name'])
image_deploy_dir = os.path.join(builddir, 'tmp-eglibc', 'deploy', 'images')
repo_link = os.path.join(image_deploy_dir, 'repo')
if not os.path.islink(repo_link):
os.symlink(self.repo, repo_link)
+ src = self._component_abspath(basemeta)
cmd = ['linux-user-chroot', '--unshare-pid', '/',
os.path.join(LIBDIR, 'ostbuild', 'ostree-build-yocto'),
- checkoutdir, builddir]
+ src, builddir]
# We specifically want to kill off any environment variables jhbuild
# may have set.
run_sync(cmd, env=buildutil.BUILD_ENV)
@@ -524,8 +491,6 @@ and the manifest input."""
def execute(self, argv):
parser = argparse.ArgumentParser(description=self.short_description)
parser.add_argument('--prefix')
- parser.add_argument('--src-snapshot')
- parser.add_argument('--patches-path')
parser.add_argument('--status-json-path',
help="Write data to this JSON file as build progresses")
parser.add_argument('--force-rebuild', action='store_true')
@@ -541,9 +506,7 @@ and the manifest input."""
self.args = args
self.parse_config()
- self.parse_snapshot(args.prefix, args.src_snapshot)
-
- log("Using source snapshot: %s" % (os.path.basename(self.snapshot_path), ))
+ self.parse_snapshot()
self._write_status({'state': 'build-starting'})
@@ -555,8 +518,6 @@ and the manifest input."""
self.force_build_components = set()
- self.cached_patchdir_revision = None
-
self._initialize_repo()
self._build_base()
diff --git a/src/ostbuild/pyostbuild/builtin_fetch.py b/src/ostbuild/pyostbuild/builtin_fetch.py
new file mode 100755
index 0000000..4c39a6d
--- /dev/null
+++ b/src/ostbuild/pyostbuild/builtin_fetch.py
@@ -0,0 +1,110 @@
+# 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.
+
+import os,sys,subprocess,tempfile,re,shutil
+import copy
+import argparse
+import json
+import time
+import urlparse
+from StringIO import StringIO
+
+from . import builtins
+from .ostbuildlog import log, fatal
+from .subprocess_helpers import run_sync, run_sync_get_output
+from . import ostbuildrc
+from . import vcs
+from . import jsondb
+from . import buildutil
+from . import kvfile
+from . import odict
+
+class OstbuildFetch(builtins.Builtin):
+ name = "fetch"
+ short_description = "Update components tracking git branches"
+
+ def __init__(self):
+ builtins.Builtin.__init__(self)
+
+ def _fetch_submodule(self, component):
+ run_sync(['git', 'fetch'], cwd=self._component_path(component))
+
+ def _ensure_submodule(self, component):
+ component_path = self._component_path(component)
+ branch = component.get('branch')
+ tag = component.get('tag')
+ if (branch is None) and (tag is not None):
+ branch = 'master' # Hack - git submodule bails trying to check out non-branches
+ (keytype, uri) = vcs.parse_src_key(component['src'])
+ if not os.path.isdir(component_path):
+ run_sync(['git', 'submodule', 'add', '-b', branch, uri, component_path])
+
+ def _sync_submodule(self, component):
+ component_path = self._component_path(component)
+ branch = component.get('branch')
+ tag = component.get('tag')
+ tag_or_branch = tag or branch
+ log("Syncing %s to %s" % (component['name'], tag_or_branch))
+ run_sync(['git', 'checkout', '-q', tag_or_branch], cwd=component_path,
+ log_initiation=False)
+
+ def _clean_submodules(self):
+ all_components = {self.snapshot['base']['name']: self.snapshot['base']}
+ for component in self.snapshot['components']:
+ all_components[component['name']] = component
+ for name in os.listdir(self.componentdir):
+ fullpath = os.path.join(self.componentdir, name)
+ relpath = os.path.relpath(fullpath, self.srcdir)
+ if all_components.has_key(name):
+ continue
+ deleted_name = os.path.join(self.srcdir, 'deleted-components')
+ if os.path.isdir(deleted_name):
+ shutil.rmtree(deleted_name)
+ run_sync(['git', 'rm', '--cached', fullpath])
+ run_sync(['git', 'config', '-f', '.git/config', '--remove-section', 'submodule.' + relpath])
+
+ def execute(self, argv):
+ parser = argparse.ArgumentParser(description=self.short_description)
+ parser.add_argument('--keep-going', action='store_true',
+ help="Don't exit on fetch failures")
+ parser.add_argument('components', nargs='*',
+ help="List of component names to git fetch")
+
+ args = parser.parse_args(argv)
+ self.args = args
+
+ self.parse_config()
+ self.parse_snapshot()
+
+ self._ensure_submodule(self.snapshot['base'])
+ self._sync_submodule(self.snapshot['base'])
+ for component in self.snapshot['components']:
+ self._ensure_submodule(component)
+ self._sync_submodule(component)
+
+ self._clean_submodules()
+
+ if len(args.components) > 0:
+ fetch_components = args.components
+ else:
+ fetch_components = map(lambda x: x['name'], self.snapshot['components'])
+ fetch_components.append(self.snapshot['base']['name'])
+
+ for component_name in fetch_components:
+ self._fetch_submodule(self.get_component(component_name))
+
+builtins.register(OstbuildFetch)
diff --git a/src/ostbuild/pyostbuild/builtins.py b/src/ostbuild/pyostbuild/builtins.py
index a4d5cd4..ef1ae63 100755
--- a/src/ostbuild/pyostbuild/builtins.py
+++ b/src/ostbuild/pyostbuild/builtins.py
@@ -25,7 +25,7 @@ import json
from . import ostbuildrc
from . import fileutil
-from . import jsondb
+from . import buildutil
from .ostbuildlog import log, fatal
from .subprocess_helpers import run_sync, run_sync_get_output
@@ -63,6 +63,14 @@ class Builtin(object):
else:
return (None, None)
+ def _component_path(self, component):
+ component_path = os.path.join(self.componentdir, component['name'])
+ return os.path.relpath(component_path, self.srcdir)
+
+ def _component_abspath(self, component):
+ component_path = os.path.join(self.componentdir, component['name'])
+ return os.path.abspath(component_path)
+
def get_component_from_cwd(self):
cwd = os.getcwd()
parent = os.path.dirname(cwd)
@@ -72,16 +80,10 @@ class Builtin(object):
def parse_config(self):
self.ostbuildrc = ostbuildrc
- self.mirrordir = os.path.expanduser(ostbuildrc.get_key('mirrordir'))
- if not os.path.isdir(self.mirrordir):
- fatal("Specified mirrordir '%s' is not a directory" % (self.mirrordir, ))
self.workdir = os.path.expanduser(ostbuildrc.get_key('workdir'))
if not os.path.isdir(self.workdir):
fatal("Specified workdir '%s' is not a directory" % (self.workdir, ))
- self.snapshot_dir = os.path.join(self.workdir, 'snapshots')
- self.patchdir = os.path.join(self.workdir, 'patches')
-
def get_component_snapshot(self, name):
found = False
for content in self.active_branch_contents['contents']:
@@ -136,35 +138,6 @@ class Builtin(object):
def get_expanded_component(self, name):
return self.expand_component(self.get_component(name))
- def get_prefix(self):
- if self.prefix is None:
- path = os.path.expanduser('~/.config/ostbuild-prefix')
- if not os.path.exists(path):
- fatal("No prefix set; use \"ostbuild prefix\" to set one")
- f = open(path)
- self.prefix = f.read().strip()
- f.close()
- return self.prefix
-
- def create_db(self, dbsuffix, prefix=None):
- if prefix is None:
- target_prefix = self.get_prefix()
- else:
- target_prefix = prefix
- name = '%s-%s' % (target_prefix, dbsuffix)
- fileutil.ensure_dir(self.snapshot_dir)
- return jsondb.JsonDB(self.snapshot_dir, prefix=name)
-
- def get_src_snapshot_db(self):
- if self._src_snapshots is None:
- self._src_snapshots = self.create_db('src-snapshot')
- return self._src_snapshots
-
- def get_bin_snapshot_db(self):
- if self._bin_snapshots is None:
- self._bin_snapshots = self.create_db('bin-snapshot')
- return self._bin_snapshots
-
def init_repo(self):
if self.repo is not None:
return self.repo
@@ -174,27 +147,27 @@ class Builtin(object):
else:
self.repo = os.path.join(self.workdir, 'repo')
- def parse_prefix(self, prefix):
- if prefix is not None:
- self.prefix = prefix
-
- def parse_snapshot(self, prefix, path):
- self.parse_prefix(prefix)
+ def parse_snapshot(self):
self.init_repo()
- if path is None:
- latest_path = self.get_src_snapshot_db().get_latest_path()
- if latest_path is None:
- raise Exception("No source snapshot found for prefix %r" % (self.prefix, ))
- self.snapshot_path = latest_path
- else:
- self.snapshot_path = path
+ cwd_path = os.path.join(os.getcwd(), 'manifest.json')
+ if not os.path.isfile(cwd_path):
+ raise Exception("No source snapshot found here; looking for %s" % (cwd_path, ))
+ self.snapshot_path = cwd_path
self.snapshot = json.load(open(self.snapshot_path))
key = '00ostbuild-manifest-version'
src_ver = self.snapshot[key]
- if src_ver != 0:
- fatal("Unhandled %s version \"%d\", expected 0" % (key, src_ver, ))
- if self.prefix is None:
- self.prefix = self.snapshot['prefix']
+ if src_ver != 1:
+ fatal("Unhandled %s version \"%d\", expected 1" % (key, src_ver, ))
+ self.srcdir = os.getcwd()
+ self.prefix = self.snapshot['prefix']
+ self.componentdir = os.path.join(os.getcwd(), 'components')
+
+ components = map(lambda x: buildutil.resolve_component_meta(self.snapshot, x), self.snapshot['components'])
+ components = map(lambda x: self.expand_component(x), components)
+ self.snapshot['components'] = components
+ base_meta = buildutil.resolve_component_meta(self.snapshot, self.snapshot['base'])
+ self.snapshot['base'] = base_meta
+
def parse_snapshot_from_current(self):
if self.ostree_dir is None:
diff --git a/src/ostbuild/pyostbuild/main.py b/src/ostbuild/pyostbuild/main.py
index 8a0bf27..0ab26e2 100755
--- a/src/ostbuild/pyostbuild/main.py
+++ b/src/ostbuild/pyostbuild/main.py
@@ -26,6 +26,7 @@ from . import builtin_build
from . import builtin_checkout
from . import builtin_deploy_root
from . import builtin_deploy_qemu
+from . import builtin_fetch
from . import builtin_git_mirror
from . import builtin_import_tree
from . import builtin_init
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]