bug 1361037, part 5: support locale subsets, r=flod, stas
authorAxel Hecht <axel@pike.org>
Tue, 16 May 2017 13:43:50 +0200
changeset 236 e2174b93de6d89a60208bfdc389d5c5b1c7eb33b
parent 235 bb991de43bbaeca50e4ced3c42d69a059c6b3d0d
child 237 f9fb89c4d86ad2e1f6a84b24340ad1c88b74a8b1
push id48
push useraxel@mozilla.com
push dateFri, 26 May 2017 11:10:47 +0000
reviewersflod, stas
bugs1361037
bug 1361037, part 5: support locale subsets, r=flod, stas MozReview-Commit-ID: J9hlE5t8IvM
compare_locales/paths.py
compare_locales/tests/test_paths.py
--- a/compare_locales/paths.py
+++ b/compare_locales/paths.py
@@ -59,17 +59,23 @@ class Matcher(object):
 
 
 class ProjectConfig(object):
     '''Abstraction of l10n project configuration data.
     '''
 
     def __init__(self):
         self.filter_py = None  # legacy filter code
-        self.paths = []  # {'reference': pattern, 'l10n': pattern, 'test': []}
+        # {
+        #  'l10n': pattern,
+        #  'reference': pattern,  # optional
+        #  'locales': [],  # optional
+        #  'test': [],  # optional
+        # }
+        self.paths = []
         self.rules = []
         self.locales = []
         self.projects = []  # TODO: add support for sub-projects
 
     def add_paths(self, *paths):
         '''Add path dictionaries to this config.
         The dictionaries must have a `l10n` key. For monolingual files,
         `reference` is also required.
@@ -81,17 +87,18 @@ class ProjectConfig(object):
             rv = {
                 'l10n': d['l10n'],
                 'module': d.get('module')
             }
             if 'reference' in d:
                 rv['reference'] = Matcher(d['reference'])
             if 'test' in d:
                 rv['test'] = d['test']
-            # TODO: locale
+            if 'locales' in d:
+                rv['locales'] = d['locales'][:]
             self.paths.append(rv)
 
     def set_filter_py(self, filter):
         '''Set legacy filter.py code.
         Assert that no rules are set.
         Also, normalize output already here.
         '''
         assert not self.rules
@@ -172,23 +179,27 @@ class ProjectFiles(object):
     '''
     def __init__(self, locale, *projects):
         self.locale = locale
         self.matchers = []
         for pc in projects:
             if locale not in pc.locales:
                 continue
             for paths in pc.paths:
+                if 'locales' in paths and locale not in paths['locales']:
+                    continue
                 m = {
                     'l10n': Matcher(paths['l10n'], locale),
                     'module': paths.get('module')
                 }
                 if 'reference' in paths:
                     m['reference'] = paths['reference']
                 m['test'] = set(paths.get('test', []))
+                if 'locales' in paths:
+                    m['locales'] = paths['locales'][:]
                 self.matchers.append(m)
         self.matchers.reverse()  # we always iterate last first
         # Remove duplicate patterns, comparing each matcher
         # against all other matchers.
         # Avoid n^2 comparisons by only scanning the upper triangle
         # of a n x n matrix of all possible combinations.
         # Using enumerate and keeping track of indexes, as we can't
         # modify the list while iterating over it.
--- a/compare_locales/tests/test_paths.py
+++ b/compare_locales/tests/test_paths.py
@@ -319,8 +319,48 @@ class TestProjectPaths(unittest.TestCase
             list(files),
             [
                 ('/tmp/l10n/de/good.ftl', '/tmp/reference/good.ftl', set()),
                 ('/tmp/l10n/de/ref.ftl', '/tmp/reference/ref.ftl', set()),
             ])
         # 'fr' is not in the locale list, should return no files
         files = MockProjectFiles(mocks, 'fr', cfg)
         self.assertListEqual(list(files), [])
+
+    def test_partial_l10n(self):
+        cfg = ProjectConfig()
+        cfg.locales.extend(['de', 'fr'])
+        cfg.add_paths({
+            'l10n': '/tmp/{locale}/major/*'
+        }, {
+            'l10n': '/tmp/{locale}/minor/*',
+            'locales': ['de']
+        })
+        mocks = {
+            '/tmp/de/major/': [
+                'good.ftl',
+                'not/subdir/bad.ftl'
+            ],
+            '/tmp/de/minor/': [
+                'good.ftl',
+            ],
+            '/tmp/fr/major/': [
+                'good.ftl',
+                'not/subdir/bad.ftl'
+            ],
+            '/tmp/fr/minor/': [
+                'good.ftl',
+            ],
+        }
+        files = MockProjectFiles(mocks, 'de', cfg)
+        self.assertListEqual(
+            list(files),
+            [
+                ('/tmp/de/major/good.ftl', None, set()),
+                ('/tmp/de/minor/good.ftl', None, set()),
+            ])
+        # 'fr' is not in the locale list of minor, should only return major
+        files = MockProjectFiles(mocks, 'fr', cfg)
+        self.assertListEqual(
+            list(files),
+            [
+                ('/tmp/fr/major/good.ftl', None, set()),
+            ])