ostbuild: Add source-diff builtin

OMG OMG OMG
This commit is contained in:
Colin Walters 2012-05-18 20:12:35 -04:00
parent 58d28ad5a6
commit 6d59b4077c
5 changed files with 141 additions and 7 deletions

View File

@ -37,6 +37,7 @@ pyostbuild_PYTHON = \
src/ostbuild/pyostbuild/builtin_prefix.py \
src/ostbuild/pyostbuild/builtin_resolve.py \
src/ostbuild/pyostbuild/builtin_init.py \
src/ostbuild/pyostbuild/builtin_source_diff.py \
src/ostbuild/pyostbuild/builtins.py \
src/ostbuild/pyostbuild/filemonitor.py \
src/ostbuild/pyostbuild/fileutil.py \

View File

@ -0,0 +1,120 @@
# 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.
# ostbuild-compile-one-make wraps systems that implement the GNOME build API:
# http://people.gnome.org/~walters/docs/build-api.txt
import os,sys,stat,subprocess,tempfile,re,shutil
import argparse
from StringIO import StringIO
import json
from . import builtins
from .ostbuildlog import log, fatal
from . import vcs
from .subprocess_helpers import run_sync, run_sync_get_output
from . import buildutil
class OstbuildSourceDiff(builtins.Builtin):
name = "source-diff"
short_description = "Show differences in source code between builds"
def __init__(self):
builtins.Builtin.__init__(self)
def _snapshot_from_rev(self, rev):
self.init_repo()
text = run_sync_get_output(['ostree', '--repo=' + self.repo,
'cat', rev, '/contents.json'],
log_initiation=False)
return json.loads(text)
def execute(self, argv):
parser = argparse.ArgumentParser(description=self.short_description)
parser.add_argument('--rev-from')
parser.add_argument('--rev-to')
parser.add_argument('--snapshot-from')
parser.add_argument('--snapshot-to')
args = parser.parse_args(argv)
self.parse_config()
to_snap = None
from_snap = None
if args.rev_to:
to_snap = self._snapshot_from_rev(args.rev_to)
if args.rev_from:
from_snap = self._snapshot_from_rev(args.rev_from)
if args.snapshot_from:
from_snap = json.load(open(args.snapshot_from))
if args.snapshot_to:
to_snap = json.load(open(args.snapshot_to))
if to_snap is None:
fatal("One of --rev-to/--snapshot-to must be given")
if from_snap is None:
if args.rev_to:
from_snap = self._snapshot_from_rev(args.rev_to + '^')
else:
fatal("One of --rev-from/--snapshot-from must be given")
diff_replace_re = re.compile(' [ab]')
for from_component in from_snap['components']:
name = from_component['name']
src = from_component['src']
(keytype, uri) = vcs.parse_src_key(src)
if keytype == 'local':
log("Component %r has local URI" % (name, ))
continue
mirrordir = vcs.ensure_vcs_mirror(self.mirrordir, keytype, uri, from_component['branch'])
to_component = self.find_component_in_snapshot(name, to_snap)
if to_component is None:
log("DELETED COMPONENT: %s" % (name, ))
continue
from_revision = from_component.get('revision')
to_revision = to_component.get('revision')
if from_revision is None:
log("From component %s missing revision" % (name, ))
continue
if to_revision is None:
log("From component %s missing revision" % (name, ))
continue
if from_revision != to_revision:
env = dict(os.environ)
env['LANG'] = 'C'
spacename = ' ' + name
proc = subprocess.Popen(['git', 'diff', from_revision, to_revision],
env=env, cwd=mirrordir, stdout=subprocess.PIPE)
for line in proc.stdout:
if (line.startswith('diff --git ')
or line.startswith('--- a/')
or line.startswith('+++ b/')
or line.startswith('Binary files /dev/null and b/')):
line = diff_replace_re.sub(spacename, line)
sys.stdout.write(line)
else:
sys.stdout.write(line)
proc.wait()
builtins.register(OstbuildSourceDiff)

View File

@ -122,12 +122,22 @@ class Builtin(object):
meta['config-opts'] = config_opts
return meta
def get_component(self, name):
assert self.snapshot is not None
for component in self.snapshot['components']:
def find_component_in_snapshot(self, name, snapshot):
for component in snapshot['components']:
if component['name'] == name:
return component
fatal("Couldn't find component '%s' in manifest" % (component_name, ))
return None
def get_component(self, name, in_snapshot=None):
if in_snapshot is None:
assert self.snapshot is not None
target_snapshot = self.snapshot
else:
target_snapshot = in_snapshot
component = self.find_component_in_snapshot(self, target_snapshot)
if component is None:
fatal("Couldn't find component '%s' in manifest" % (component_name, ))
return component
def get_expanded_component(self, name):
return self.expand_component(self.get_component(name))
@ -161,7 +171,9 @@ class Builtin(object):
self._bin_snapshots = self.create_db('bin-snapshot')
return self._bin_snapshots
def _init_repo(self):
def init_repo(self):
if self.repo is not None:
return self.repo
repo = ostbuildrc.get_key('repo', default=None)
if repo is not None:
self.repo = repo
@ -178,7 +190,7 @@ class Builtin(object):
def parse_snapshot(self, prefix, path):
self.parse_prefix(prefix)
self._init_repo()
self.init_repo()
if path is None:
latest_path = self.get_src_snapshot_db().get_latest_path()
if latest_path is None:

View File

@ -36,6 +36,7 @@ from . import builtin_prefix
from . import builtin_privhelper_deploy_qemu
from . import builtin_privhelper_run_qemu
from . import builtin_resolve
from . import builtin_source_diff
def usage(ecode):
print "Builtins:"

View File

@ -84,7 +84,7 @@ def parse_src_key(srckey):
if idx < 0:
raise ValueError("Invalid SRC uri=%s" % (srckey, ))
keytype = srckey[:idx]
if keytype not in ['git']:
if keytype not in ['git', 'local']:
raise ValueError("Unsupported SRC uri=%s" % (srckey, ))
uri = srckey[idx+1:]
return (keytype, uri)