From 5e6b7c677445245370d7f0e1c1e39c02aa771057 Mon Sep 17 00:00:00 2001 From: Lingchao Xin Date: Fri, 6 Dec 2013 16:56:15 +0800 Subject: [PATCH] Integrate repo and image diff From now, you can invoke unified API to diff repo and image. Fixes: #1523 Change-Id: I1324d23f012873fb3bb9cbdc1c4c135877affd4b --- setup.py | 2 +- snapdiff/__init__.py | 125 +++++++++++++++++++++++++++++++-- snapdiff/repo.py | 93 ------------------------ tools/{repo-diff => snap-diff} | 7 +- 4 files changed, 124 insertions(+), 103 deletions(-) rename tools/{repo-diff => snap-diff} (63%) diff --git a/setup.py b/setup.py index b2b682d..294b0db 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup(name=snapdiff.__title__, author='Lingchao Xin', author_email='lingchaox.xin@intel.com', url='http://www.tizen.org/', - scripts=['tools/repo-diff',], + scripts=['tools/snap-diff',], packages=['snapdiff',], include_package_data=True, install_requires=['Jinja2>=2.6', 'requests>=2.0.1', diff --git a/snapdiff/__init__.py b/snapdiff/__init__.py index 9e20679..e94c528 100644 --- a/snapdiff/__init__.py +++ b/snapdiff/__init__.py @@ -2,18 +2,131 @@ Snapdiff is used to generate image and repo diffs. You can use it as a module: >>> import snapdiff - >>> snapdiff.diff_to_JSON('old url', 'new url') - >>> snapdiff.diff_to_HTML('old url', 'new url') + >>> snapdiff.diff_to_JSON('old url', 'new url', style='repo') + >>> snapdiff.diff_to_HTML('old url', 'new url', style='image') or use it directly: - repo-diff [old url] [new url] - ... + snap-diff [-h] [--json] [-t] old new + + Diff two repos with different urls + + positional arguments: + old old repo + new new repo + + optional arguments: + -h, --help show this help message and exit + --json output json diffs + -t which diff you want(repo | image, default is repo) + ... """ __title__ = 'python-snapdiff' __version__ = '0.1' -from .repo import * -from .image import * +from .render import output_html +from .repo import Repo +from .image import ks_diff, packages + +import json + +def diff_to_JSON(old_url, new_url, style='repo'): + """Output diffs' json format""" + + if not old_url or not new_url: + return + + if style == 'repo': + old, new = Repo(old_url).packages, Repo(new_url).packages + elif style == 'image': + old, new = packages(old_url), packages(new_url) + else: + return + + added, removed, modified, rebuilded = [], [], [], [] + package_names = set(old.keys() + new.keys()) + + def _pair_old_new(): + for name in package_names: + if old.get(name) is None: + for pkg in new[name]: + yield (None, pkg) + elif new.get(name) is None: + for pkg in old[name]: + yield (pkg, None) + else: + for old_pkg in old[name]: + for new_pkg in new[name]: + if old_pkg.version.ver == new_pkg.version.ver: + yield (old_pkg, new_pkg) + old[name].remove(old_pkg) + new[name].remove(new_pkg) + for pair in map(None, old[name], new[name]): + yield pair + for old_pkg, new_pkg in _pair_old_new(): + if old_pkg is None: + added.append(new_pkg) + elif new_pkg is None: + removed.append(old_pkg) + elif old_pkg.version.vcs != new_pkg.version.vcs or \ + old_pkg.version.ver != new_pkg.version.ver: + modified.append((old_pkg, new_pkg)) + elif old_pkg.version.rel != new_pkg.version.rel: + rebuilded.append((old_pkg, new_pkg)) + + obj = {style: {'old': old_url, 'new': new_url}, + 'diff': { + 'added': [{'oldpkg': None, 'newpkg': {'name': _new.name, \ + 'version': {'epoch': _new.version.epoch, \ + 'rel': _new.version.rel, 'ver': _new.version.ver}, \ + 'vcs': _new.version.vcs}, 'codediff': None} \ + for _new in added], + 'removed': [{'oldpkg': {'name': _old.name, \ + 'version': {'epoch': _old.version.epoch, \ + 'rel': _old.version.rel, 'ver': _old.version.ver}, \ + 'vcs': _old.version.vcs}, 'newpkg': None, \ + 'codediff': None} for _old in added], + 'modified': [{'oldpkg': {'name': _old.name, \ + 'version': {'epoch': _old.version.epoch, \ + 'rel': _old.version.rel, 'ver': _old.version.ver}, \ + 'vcs': _old.version.vcs}, \ + 'newpkg': {'name': _new.name, \ + 'version': {'epoch': _new.version.epoch, \ + 'rel': _new.version.rel, 'ver': _new.version.ver}, + 'vcs': _new.version.vcs}, 'codediff': None} \ + for _old, _new in modified], + 'rebuilded': [{'oldpkg': {'name': _old.name, \ + 'version': {'epoch': _old.version.epoch, \ + 'rel': _old.version.rel, 'ver': _old.version.ver}, \ + 'vcs': _old.version.vcs}, \ + 'newpkg': {'name': _new.name, \ + 'version': {'epoch': _new.version.epoch, \ + 'rel': _new.version.rel, 'ver': _new.version.ver}, + 'vcs': _new.version.vcs}, 'codediff': None} \ + for _old, _new in rebuilded], + } + } + + if style == 'image': + obj['diff']['ks'] = ''.join([d for d in ks_diff(old_url, new_url)]) + + return json.dumps(obj, indent=4) + +def diff_to_HTML(old_url, new_url, style='repo'): + """Output diffs' html format""" + + json_obj = diff_to_JSON(old_url, new_url, style) + + if json_obj is None: + return + + data = json.loads(json_obj) + + context = {'old_url': old_url, + 'new_url': new_url, + 'diff': data['diff'], + } + + return output_html('diff.html', **context) diff --git a/snapdiff/repo.py b/snapdiff/repo.py index eb2f504..cccb932 100644 --- a/snapdiff/repo.py +++ b/snapdiff/repo.py @@ -1,10 +1,7 @@ from .utils import xml2obj -from .render import output_html import gzip -import json import mimetypes -import os import requests from StringIO import StringIO @@ -71,94 +68,4 @@ class Repo(object): return packages_info -def diff_to_JSON(old_url, new_url): - """Output diffs' json format""" - - if not old_url or not new_url: - return - - old, new = Repo(old_url).packages, Repo(new_url).packages - - added, removed, modified, rebuilded = [], [], [], [] - package_names = set(old.keys() + new.keys()) - - def _pair_old_new(): - for name in package_names: - if old.get(name) is None: - for pkg in new[name]: - yield (None, pkg) - elif new.get(name) is None: - for pkg in old[name]: - yield (pkg, None) - else: - for old_pkg in old[name]: - for new_pkg in new[name]: - if old_pkg.version.ver == new_pkg.version.ver: - yield (old_pkg, new_pkg) - old[name].remove(old_pkg) - new[name].remove(new_pkg) - for pair in map(None, old[name], new[name]): - yield pair - for old_pkg, new_pkg in _pair_old_new(): - if old_pkg is None: - added.append(new_pkg) - elif new_pkg is None: - removed.append(old_pkg) - elif old_pkg.version.vcs != new_pkg.version.vcs or \ - old_pkg.version.ver != new_pkg.version.ver: - modified.append((old_pkg, new_pkg)) - elif old_pkg.version.rel != new_pkg.version.rel: - rebuilded.append((old_pkg, new_pkg)) - - obj = {'repo': {'old': old_url, 'new': new_url}, - 'diff': { - 'added': [{'oldpkg': None, 'newpkg': {'name': _new.name, \ - 'version': {'epoch': _new.version.epoch, \ - 'rel': _new.version.rel, 'ver': _new.version.ver}, \ - 'vcs': _new.version.vcs}, 'codediff': None} \ - for _new in added], - 'removed': [{'oldpkg': {'name': _old.name, \ - 'version': {'epoch': _old.version.epoch, \ - 'rel': _old.version.rel, 'ver': _old.version.ver}, \ - 'vcs': _old.version.vcs}, 'newpkg': None, \ - 'codediff': None} for _old in added], - 'modified': [{'oldpkg': {'name': _old.name, \ - 'version': {'epoch': _old.version.epoch, \ - 'rel': _old.version.rel, 'ver': _old.version.ver}, \ - 'vcs': _old.version.vcs}, \ - 'newpkg': {'name': _new.name, \ - 'version': {'epoch': _new.version.epoch, \ - 'rel': _new.version.rel, 'ver': _new.version.ver}, - 'vcs': _new.version.vcs}, 'codediff': None} \ - for _old, _new in modified], - 'rebuilded': [{'oldpkg': {'name': _old.name, \ - 'version': {'epoch': _old.version.epoch, \ - 'rel': _old.version.rel, 'ver': _old.version.ver}, \ - 'vcs': _old.version.vcs}, \ - 'newpkg': {'name': _new.name, \ - 'version': {'epoch': _new.version.epoch, \ - 'rel': _new.version.rel, 'ver': _new.version.ver}, - 'vcs': _new.version.vcs}, 'codediff': None} \ - for _old, _new in rebuilded], - } - } - - return json.dumps(obj, indent=4) - -def diff_to_HTML(old_url, new_url): - """Output diffs' html format""" - - json_obj = diff_to_JSON(old_url, new_url) - - if json_obj is None: - return - - data = json.loads(json_obj) - - context = {'old_url': old_url, - 'new_url': new_url, - 'diff': data['diff'], - } - - return output_html('diff.html', **context) diff --git a/tools/repo-diff b/tools/snap-diff similarity index 63% rename from tools/repo-diff rename to tools/snap-diff index d94eebe..1217d5b 100755 --- a/tools/repo-diff +++ b/tools/snap-diff @@ -1,6 +1,6 @@ #!/usr/bin/env python -from snapdiff import diff_to_JSON, diff_to_HTML +import snapdiff import argparse import sys @@ -11,12 +11,13 @@ def main(argv): parser.add_argument(dest='old', help='old repo') parser.add_argument(dest='new', help='new repo') parser.add_argument('--json', help='output json diffs', action='store_true') + parser.add_argument('-t', dest='type', help="which diff you want(repo | image, default is repo)") args = parser.parse_args(argv) if args.json: - print diff_to_JSON(args.old, args.new) + print snapdiff.diff_to_JSON(args.old, args.new, style=args.type or 'repo') else: - print diff_to_HTML(args.old, args.new) + print snapdiff.diff_to_HTML(args.old, args.new, style=args.type or 'repo') if __name__ == '__main__': sys.exit(main(sys.argv[1:])) -- 2.34.1