Reworked repa diff
authorEd Bartosh <eduard.bartosh@intel.com>
Fri, 12 Dec 2014 14:43:51 +0000 (16:43 +0200)
committerEd Bartosh <eduard.bartosh@intel.com>
Sun, 14 Dec 2014 14:38:01 +0000 (16:38 +0200)
Now repa diff uses _service:gbs:_git-meta to get tags
from compare project.
It makes it much faster and reliable than previously.

Fixes: #1869
Change-Id: I5b11845afe2c73b2de38cb830d050fb57742c0ed
Signed-off-by: Ed Bartosh <eduard.bartosh@intel.com>
repa.1
repa/common.py
repa/diff.py
repa/obs.py

diff --git a/repa.1 b/repa.1
index 6a14762c6cddfa7818b487d417483cf46c128a8a..c4674efb915e3bf0e8554c9cc724130bb72f8fd1 100644 (file)
--- a/repa.1
+++ b/repa.1
@@ -314,31 +314,31 @@ Print short help text about the "rmgroup" command and exit.
 .\"
 .\" The "diff" command description
 .\"
-.SS \fBdiff\fR [\-\-help] <project1> <manifest of target project> <manifest1>
+.SS \fBdiff\fR [\-\-help] <project to compare> <manifest to compare> <manifest of target project>
 
 .RS 2
-Show the difference between manifest of target project and manifest of <project1> in the following format:
+Show the difference between manifest of target project and manifest of <project to compare> in the following format:
 
-<Git path>  <Revision in project1> <Revision in the target OBS Project>  <Tag, accepted into project1>  <status>
+<Git path>  <Revision in project to compare> <Revision in the target OBS Project>  <Tag, accepted into project to compare>
 .RS 0
 
 Example of output:
 
 $ repa -p Tizen:IVI diff Tizen:Common ivi_0140508.2_ia32.xml common_20140507.5_ia32.xml
 
-platform/core/appfw/aul-1                          3644ad5459 e4f2b22012 submit/tizen/20140502.084937 pending
+platform/core/appfw/aul-1                          3644ad5459  e4f2b22012  submit/tizen/20140502.084937
 .RS 0
-platform/core/appfw/shortcut                       502c7807b3 27bbf892e0 submit/tizen/20140430.020549 pending
+platform/core/appfw/shortcut                       502c7807b3  27bbf892e0  submit/tizen/20140430.020549
 .RS 0
-platform/core/connectivity/nfc-manager-neard       ea952dc454 88793ab1ff
+platform/core/connectivity/nfc-manager-neard       ea952dc454  88793ab1ff  None
 .RS 0
-platform/core/connectivity/smartcard-service       e45ae0bdfb 7d5da70551 submit/tizen/20140506.101200 pending
+platform/core/connectivity/smartcard-service       e45ae0bdfb  7d5da70551  submit/tizen/20140506.101200
 .RS 0
-platform/core/messaging/msg-service                c988cc8b55 a9eed6a734 submit/tizen/20140502.105814 pending
+platform/core/messaging/msg-service                c988cc8b55  a9eed6a734  submit/tizen/20140502.105814
 .RS 0
-platform/core/system/tlm                           3ddbc6bc14 dc72779317 submit/tizen/20140430.130050
+platform/core/system/tlm                           3ddbc6bc14  None        submit/tizen/20140430.130050
 .RS 0
-platform/framework/web/crosswalk                   42dcc1327b 4280e52757 submit/tizen/20140506.123703 pending
+platform/framework/web/crosswalk                   42dcc1327b  4280e52757  submit/tizen/20140506.123703
 .RS 0
 
 Status 'pending' means that submission is pending for the target project. In colorized mode pending submissions are colorized and 'pending' status is not shown.
index 630dc6a0738fcdc09feed31c9691d47dd8461a1d..c98b1ed0044f4f3c3318cb7241a4216438312d7a 100644 (file)
@@ -45,6 +45,13 @@ def get_prerelease_projects(obs, target_prj, tag=None):
     """Get list of prerelease projects for specified target project."""
     return obs.get_project_list('^%s%s:' % (OBS_PROJECT_PREFIX, target_prj))
 
+def prerelease_exists(obs, name, target):
+    """Check if prerelease project exists."""
+    if name.startswith('submitgroup/'):
+        name += '-group'
+    project = '%s%s:%s' % (OBS_PROJECT_PREFIX, target, name.replace('/', ':'))
+    return obs.exists(project)
+
 def get_project_by_name(obs, name, target):
     """Lookup for a project in OBS by submission or group name."""
     if name.startswith('submitgroup/'):
index 58634700029fa6a306f3804daa2892411fba944b..613ec0143195690c28ec2d41bc0df995b655b470 100644 (file)
@@ -29,7 +29,7 @@ import json
 
 import xml.etree.ElementTree as ET
 
-from repa.common import RepaException, Colorizer, get_prerelease_projects
+from repa.common import RepaException, Colorizer, get_prerelease
 from repa.obs import OBS
 from repa.main import sub_main
 
@@ -44,58 +44,55 @@ def gen_data(manifest):
     for project in etree.getroot().findall('project'):
         yield project.get('path'), project.get('revision')
 
-
-def get_tag(obs, project, package, revision):
-    """Get tag from the latest accepted SR."""
-    for sreq in obs.get_srs(project, 'accepted', package):
-        descr = sreq[-1]
-        if descr and 'Commit: %s' % revision in descr:
-            return descr.split('Tag: ')[-1].split()[0]
-    return 'Not found'
-
-
-def get_pending(obs, target_proj):
-    """Get pair of git path: tag for pending prerelease projects."""
-    result = {}
-    for proj in get_prerelease_projects(obs, target_proj):
-        meta = json.loads(obs.get_description(proj))
-        for path in meta["projects"]:
-            result[path] = meta["git_tag"]
-    return result
-
-
-def diff(obs, target_project, project1, target_manifest, manifest1,
-         is_colorize=False):
-    """Show the difference between project1 and project2."""
+def get_tag(obs, project, package):
+    """Get tag from _git-meta file in target project."""
+    context = obs.get_file(project, package, "_service:gbs:_git-meta")
+    if not context:
+        return None
+    try:
+        data = json.loads(context)
+    except ValueError:
+        return None
+    if "tag" in data:
+        return data["tag"]["tagname"]
+
+    return None
+
+def diff(obs, cmp_project, target_project, cmp_manifest,
+         target_manifest, is_colorize=False):
+    """
+    Show the difference between two projects in terms of
+    revisions and tags.
+    """
     colorizer = Colorizer(is_colorize)
 
     target_data = dict(gen_data(target_manifest))
-    data1 = dict(gen_data(manifest1))
-
-    pending = get_pending(obs, target_project)
-
-    for path in sorted(data1):
-        # if submission is not pending in target project
-        # and revisions are the same - skip it
-        if path not in pending and \
-            (path in target_data and data1[path] == target_data[path]):
-            continue
-
-        package = os.path.basename(path)
-        tag1 = get_tag(obs, project1, package, data1[path])
-        target_tag = get_tag(obs, target_project, package,
-                             target_data.get(path))
-
-        if tag1 in pending.values():
-            if is_colorize:
-                tag1 = colorizer.green(tag1)
-            else:
-                tag1 += ' ready'
-        print "%-50s %s %s %-37s %-37s %s" % \
-                  (path, target_data.get(path, 'Not found ')[:10],
-                   data1[path][:10], target_tag, tag1,
-                   pending.get(path, 'Not found'))
-
+    cmp_data = dict(gen_data(cmp_manifest))
+
+    for path in sorted(cmp_data):
+        rev_target = target_data.get(path)
+        rev_cmp = cmp_data[path]
+        if rev_target != rev_cmp:
+            package = os.path.basename(path)
+
+            # Get tag, accepted to cmp_project
+            cmp_tag = get_tag(obs, cmp_project, package)
+            status = ''
+            # Colorize tag if it's pending in target project
+            if cmp_tag:
+                try:
+                    prerelease = get_prerelease(cmp_tag, target_project)
+                    if obs.exists(prerelease):
+                        if is_colorize:
+                            cmp_tag = colorizer.green(cmp_tag)
+                        else:
+                            status = 'pending'
+                except RepaException:
+                    pass
+
+            print "%-55s %-12s %-12s %-40s %s" % (path, rev_cmp[:10],
+                                               str(rev_target)[:10],
+                                               cmp_tag, status)
 
 class Diff(object):
     """Subcommand: diff projects."""
@@ -107,16 +104,16 @@ class Diff(object):
     @staticmethod
     def add_arguments(parser, _config):
         """Adds arguments to the parser. Called from [sub_]main."""
-        parser.add_argument('project1', help='Compared OBS project')
+        parser.add_argument('cmp_project', help='Compared OBS project')
+        parser.add_argument('cmp_manifest', help='Manifest of compared project')
         parser.add_argument('manifest', help='Manifest of current project')
-        parser.add_argument('manifest1', help='Manifest of compared project')
 
     @staticmethod
     def run(argv):
         """Command line entry point. Called from [sub_]main."""
         obs = OBS(argv.apiurl, argv.apiuser, argv.apipasswd)
-        return diff(obs, argv.project, argv.project1,
-                    argv.manifest, argv.manifest1, argv.colorize)
+        return diff(obs, argv.cmp_project, argv.project,
+                    argv.cmp_manifest, argv.manifest, argv.colorize)
 
 if __name__ == '__main__':
     sys.exit(sub_main(sys.argv[1:], Diff()))
index dd3d37338d1da5249d092a17f9c244472dfce287..6cfd8106bbfa93060f891d0bc0d04c65a40edaf6 100644 (file)
@@ -36,6 +36,7 @@ should be contributed to oscapi.
 import sys
 import re
 import cgi
+import locale
 
 from base64 import b64encode
 from xml.etree import cElementTree as ET
@@ -239,3 +240,20 @@ class OBS(OSC):
         elem.clear()
         ET.SubElement(elem, value)
         self.set_meta(ET.tostring(root), prj, pkg)
+
+    def get_file(self, prj, pkg, fname, rev=None):
+        """Get file content from OBS."""
+        query = {'expand': 1}
+        if rev:
+            query['rev'] = rev
+        encoded_fname = core.pathname2url(
+            fname.encode(locale.getpreferredencoding(), 'replace'))
+        url = core.makeurl(self.apiurl,
+                           ['source', prj, pkg, encoded_fname],
+                           query=query)
+        try:
+            return self.core_http(core.http_GET, url).read()
+        except OSCError as error:
+            if error.message == "HTTP Error 404: Not Found":
+                return None
+            raise