Bug 1132771 - Implement file-info mach command draft
authorGregory Szorc <gps@mozilla.com>
Tue, 24 Feb 2015 15:56:25 -0800
changeset 245748 9cabc294c3d221a173d9e8d4151306198cba908d
parent 245747 1faaf5ff358080740129ca61e644272e680d9858
child 245749 3fdafd1c15f0ec2b79f6f7f374166225d0789c2f
push id795
push usergszorc@mozilla.com
push dateWed, 25 Feb 2015 00:26:50 +0000
bugs1132771
milestone39.0a1
Bug 1132771 - Implement file-info mach command Now that we have a mechanism for defining file-based metadata, let's add a mach command to interface with it. Currently, we limit ourselves to simple Bugzilla data dumping. Features will be added over time.
python/mozbuild/mozbuild/frontend/mach_commands.py
--- a/python/mozbuild/mozbuild/frontend/mach_commands.py
+++ b/python/mozbuild/mozbuild/frontend/mach_commands.py
@@ -1,21 +1,25 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import print_function, unicode_literals
 
+from collections import defaultdict
+
 from mach.decorators import (
     CommandArgument,
     CommandProvider,
-    Command
+    Command,
+    SubCommand,
 )
 
 from mozbuild.base import MachCommandBase
+import mozpack.path as mozpath
 
 
 @CommandProvider
 class MozbuildFileCommands(MachCommandBase):
     @Command('mozbuild-reference', category='build-dev',
         description='View reference documentation on mozbuild files.')
     @CommandArgument('symbol', default=None, nargs='*',
         help='Symbol to view help on. If not specified, all will be shown.')
@@ -67,8 +71,63 @@ class MozbuildFileCommands(MachCommandBa
                 return 1
 
             return 0
 
         for line in format_module(m):
             print(line)
 
         return 0
+
+    @Command('file-info', category='build-dev',
+             description='Query for metadata about files.')
+    def file_info(self):
+        pass
+
+    @SubCommand('file-info', 'bugzilla-component',
+                'Show Bugzilla component info for files listed.')
+    @CommandArgument('paths', nargs='+',
+                     help='Paths whose data to query')
+    def file_info_bugzilla(self, paths):
+        components = defaultdict(set)
+        for p, m in self._get_file_info(paths).items():
+            components[m.get('BUG_COMPONENT', None)].add(p)
+
+        for component, files in sorted(components.items()):
+            if component is None:
+                continue
+
+            print('%s :: %s' % (component.product, component.component))
+            for f in sorted(files):
+                print('  %s' % f)
+            print('')
+
+        if None in components:
+            print('UNKNOWN')
+            for f in sorted(components[None]):
+                print('  %s' % f)
+
+    @SubCommand('file-info', 'missing-bugzilla',
+                'Show files missing Bugzilla component info')
+    @CommandArgument('paths', nargs='+',
+                     help='Paths whose data to query')
+    def file_info_missing_bugzilla(self, paths):
+        for p, m in sorted(self._get_file_info(paths).items()):
+            if 'BUG_COMPONENT' not in m:
+                print(p)
+
+    def _get_reader(self):
+        from mozbuild.frontend.reader import BuildReader
+        config = self.config_environment
+        return BuildReader(config)
+
+    def _get_file_info(self, paths):
+        relpaths = []
+        for p in paths:
+            a = mozpath.abspath(p)
+            if not mozpath.basedir(a, [self.topsrcdir]):
+                print('path is not inside topsrcdir: %s' % p)
+                return 1
+
+            relpaths.append(mozpath.relpath(a, self.topsrcdir))
+
+        reader = self._get_reader()
+        return reader.get_metadata_for_files(relpaths)