mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-11 09:18:20 +03:00
ostbuild: Add source-diff builtin
OMG OMG OMG
This commit is contained in:
parent
58d28ad5a6
commit
6d59b4077c
@ -37,6 +37,7 @@ pyostbuild_PYTHON = \
|
|||||||
src/ostbuild/pyostbuild/builtin_prefix.py \
|
src/ostbuild/pyostbuild/builtin_prefix.py \
|
||||||
src/ostbuild/pyostbuild/builtin_resolve.py \
|
src/ostbuild/pyostbuild/builtin_resolve.py \
|
||||||
src/ostbuild/pyostbuild/builtin_init.py \
|
src/ostbuild/pyostbuild/builtin_init.py \
|
||||||
|
src/ostbuild/pyostbuild/builtin_source_diff.py \
|
||||||
src/ostbuild/pyostbuild/builtins.py \
|
src/ostbuild/pyostbuild/builtins.py \
|
||||||
src/ostbuild/pyostbuild/filemonitor.py \
|
src/ostbuild/pyostbuild/filemonitor.py \
|
||||||
src/ostbuild/pyostbuild/fileutil.py \
|
src/ostbuild/pyostbuild/fileutil.py \
|
||||||
|
120
src/ostbuild/pyostbuild/builtin_source_diff.py
Executable file
120
src/ostbuild/pyostbuild/builtin_source_diff.py
Executable 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)
|
@ -122,12 +122,22 @@ class Builtin(object):
|
|||||||
meta['config-opts'] = config_opts
|
meta['config-opts'] = config_opts
|
||||||
return meta
|
return meta
|
||||||
|
|
||||||
def get_component(self, name):
|
def find_component_in_snapshot(self, name, snapshot):
|
||||||
assert self.snapshot is not None
|
for component in snapshot['components']:
|
||||||
for component in self.snapshot['components']:
|
|
||||||
if component['name'] == name:
|
if component['name'] == name:
|
||||||
return component
|
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):
|
def get_expanded_component(self, name):
|
||||||
return self.expand_component(self.get_component(name))
|
return self.expand_component(self.get_component(name))
|
||||||
@ -161,7 +171,9 @@ class Builtin(object):
|
|||||||
self._bin_snapshots = self.create_db('bin-snapshot')
|
self._bin_snapshots = self.create_db('bin-snapshot')
|
||||||
return self._bin_snapshots
|
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)
|
repo = ostbuildrc.get_key('repo', default=None)
|
||||||
if repo is not None:
|
if repo is not None:
|
||||||
self.repo = repo
|
self.repo = repo
|
||||||
@ -178,7 +190,7 @@ class Builtin(object):
|
|||||||
|
|
||||||
def parse_snapshot(self, prefix, path):
|
def parse_snapshot(self, prefix, path):
|
||||||
self.parse_prefix(prefix)
|
self.parse_prefix(prefix)
|
||||||
self._init_repo()
|
self.init_repo()
|
||||||
if path is None:
|
if path is None:
|
||||||
latest_path = self.get_src_snapshot_db().get_latest_path()
|
latest_path = self.get_src_snapshot_db().get_latest_path()
|
||||||
if latest_path is None:
|
if latest_path is None:
|
||||||
|
@ -36,6 +36,7 @@ from . import builtin_prefix
|
|||||||
from . import builtin_privhelper_deploy_qemu
|
from . import builtin_privhelper_deploy_qemu
|
||||||
from . import builtin_privhelper_run_qemu
|
from . import builtin_privhelper_run_qemu
|
||||||
from . import builtin_resolve
|
from . import builtin_resolve
|
||||||
|
from . import builtin_source_diff
|
||||||
|
|
||||||
def usage(ecode):
|
def usage(ecode):
|
||||||
print "Builtins:"
|
print "Builtins:"
|
||||||
|
@ -84,7 +84,7 @@ def parse_src_key(srckey):
|
|||||||
if idx < 0:
|
if idx < 0:
|
||||||
raise ValueError("Invalid SRC uri=%s" % (srckey, ))
|
raise ValueError("Invalid SRC uri=%s" % (srckey, ))
|
||||||
keytype = srckey[:idx]
|
keytype = srckey[:idx]
|
||||||
if keytype not in ['git']:
|
if keytype not in ['git', 'local']:
|
||||||
raise ValueError("Unsupported SRC uri=%s" % (srckey, ))
|
raise ValueError("Unsupported SRC uri=%s" % (srckey, ))
|
||||||
uri = srckey[idx+1:]
|
uri = srckey[idx+1:]
|
||||||
return (keytype, uri)
|
return (keytype, uri)
|
||||||
|
Loading…
Reference in New Issue
Block a user