Bug 1444534 - Part 1: Allow "locales/en-US" relative paths in localized inputs. r=ted.mielczarek
authorNick Alexander <nalexander@mozilla.com>
Thu, 08 Mar 2018 14:12:44 -0800
changeset 461256 264a5497622cf6137d2b27a1071cc7fd69530b90
parent 461255 c49612687020f15197ca5024fc562f405c1df127
child 461257 fcf5174ce1a6ef32d639958ee3582aa0d30074a8
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1444534 - Part 1: Allow "locales/en-US" relative paths in localized inputs. r=ted.mielczarek This cleans up a few things, including simplifying the look of backend.mk by keeping the relsrcdir in MERGE_RELATIVE_FILE similar to the source path in the tree. Before, the locales/ floated around, which is hard to understand but doesn't matter, since it's stripped by MERGE_RELATIVE_FILE. This also tests both relative and topsrcdir-absolute paths. MozReview-Commit-ID: 1v3y9xGiNfL
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -534,22 +534,27 @@ class RecursiveMakeBackend(CommonBackend
                                      % (e.args[0], ', '.join(sorted(substs.keys())), o))
             first_output = outputs[0]
             dep_file = "%s.pp" % first_output
             if obj.inputs:
                 if obj.localized:
                     # Localized generated files can have locale-specific inputs, which are
-                    # indicated by paths starting with `en-US/` or containing `/locales/en-US/`.
+                    # indicated by paths starting with `en-US/` or containing `locales/en-US/`.
                     def srcpath(p):
-                        if '/locales/en-US' in p:
-                            e, f = p.split('/locales/en-US/', 1)
+                        if 'locales/en-US' in p:
+                            # We need an "absolute source path" relative to
+                            # topsrcdir, like "/source/path".
+                            if not p.startswith('/'):
+                                p = '/' + mozpath.relpath(p.full_path, obj.topsrcdir)
+                            e, f = p.split('locales/en-US/', 1)
-                            return '$(call MERGE_RELATIVE_FILE,%s,/locales/%s)' % (f, e)
+                            return '$(call MERGE_RELATIVE_FILE,{},{}locales)'.format(
+                                f, e if not e.startswith('/') else e[len('/'):])
                         elif p.startswith('en-US/'):
                             e, f = p.split('en-US/', 1)
                             assert(not e)
                             return '$(call MERGE_FILE,%s)' % f
                         return self._pretty_path(p, backend_file)
                     inputs = [srcpath(f) for f in obj.inputs]
                     inputs = [self._pretty_path(f, backend_file) for f in obj.inputs]
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1456,17 +1456,17 @@ VARIABLES = {
         For simple cases of text substitution, prefer ``LOCALIZED_PP_FILES``.
         Refer to the documentation of ``GENERATED_FILES``; for the most part things work the same.
         The two major differences are:
         1. The function in the Python script will be passed an additional keyword argument `locale`
            which provides the locale in use, i.e. ``en-US``.
         2. The ``inputs`` list may contain paths to files that will be taken from the locale
            source directory (see ``LOCALIZED_FILES`` for a discussion of the specifics). Paths
-           in ``inputs`` starting with ``en-US/`` or containing ``/locales/en-US/`` are considered
+           in ``inputs`` starting with ``en-US/`` or containing ``locales/en-US/`` are considered
            localized files.
         To place the generated output file in a specific location, list its objdir path in
         In addition, ``LOCALIZED_GENERATED_FILES`` can use the special substitutions ``{AB_CD}``
         and ``{AB_rCD}`` in their output paths.  ``{AB_CD}`` expands to the current locale during
         multi-locale builds and single-locale repacks and ``{AB_rCD}`` expands to an
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -1183,22 +1183,22 @@ class TreeMetadataEmitter(LoggingMixin):
                         raise SandboxValidationError(
                                 ('Only source directory paths allowed in ' +
                                  '%s: %s')
                                 % (var, f,), context)
                     if var.startswith('LOCALIZED_'):
                         if isinstance(f, SourcePath):
                             if f.startswith('en-US/'):
-                            elif '/locales/en-US/' in f:
+                            elif 'locales/en-US/' in f:
                                 raise SandboxValidationError(
                                         '%s paths must start with `en-US/` or '
-                                        'contain `/locales/en-US/`: %s'
+                                        'contain `locales/en-US/`: %s'
                                         % (var, f,), context)
                     if not isinstance(f, ObjDirPath):
                         path = f.full_path
                         if '*' not in path and not os.path.exists(path):
                             raise SandboxValidationError(
                                 'File listed in %s does not exist: %s'
                                 % (var, path), context)
copy from python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/inner/locales/en-US/localized-input
copy to python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/locales/en-US/localized-input
--- a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/moz.build
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/moz.build
@@ -11,11 +11,22 @@ foo.inputs = [
 bar.script = 'generate-foo.py'
 bar.inputs = [
-    'inner/locales/en-US/localized-input',
+    # Absolute source path.
+    '/inner/locales/en-US/localized-input',
+bar.script = 'generate-foo.py'
+bar.inputs = [
+    # Relative source path.
+    'locales/en-US/localized-input',
+    'non-localized-input',
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -456,19 +456,25 @@ class TestRecursiveMakeBackend(BackendTe
             'EXTRA_MDDEPEND_FILES += foo$(AB_CD).xyz.pp',
             'foo$(AB_CD).xyz: %s/generate-foo.py $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)' % env.topsrcdir,
             '$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main foo$(AB_CD).xyz $(MDDEPDIR)/foo$(AB_CD).xyz.pp $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input)' % env.topsrcdir,
             'include $(topsrcdir)/config/AB_rCD.mk',
             'GARBAGE += bar$(AB_rCD).xyz',
             'EXTRA_MDDEPEND_FILES += bar$(AB_rCD).xyz.pp',
-            'bar$(AB_rCD).xyz: %s/generate-foo.py $(call MERGE_RELATIVE_FILE,localized-input,/locales/inner) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)' % env.topsrcdir,
+            'bar$(AB_rCD).xyz: %s/generate-foo.py $(call MERGE_RELATIVE_FILE,localized-input,inner/locales) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)' % env.topsrcdir,
-            '$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main bar$(AB_rCD).xyz $(MDDEPDIR)/bar$(AB_rCD).xyz.pp $(call MERGE_RELATIVE_FILE,localized-input,/locales/inner) $(srcdir)/non-localized-input)' % env.topsrcdir,
+            '$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main bar$(AB_rCD).xyz $(MDDEPDIR)/bar$(AB_rCD).xyz.pp $(call MERGE_RELATIVE_FILE,localized-input,inner/locales) $(srcdir)/non-localized-input)' % env.topsrcdir,
+            '',
+            'GARBAGE += zot$(AB_rCD).xyz',
+            'EXTRA_MDDEPEND_FILES += zot$(AB_rCD).xyz.pp',
+            'zot$(AB_rCD).xyz: %s/generate-foo.py $(call MERGE_RELATIVE_FILE,localized-input,locales) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)' % env.topsrcdir,
+            '$(REPORT_BUILD)',
+            '$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main zot$(AB_rCD).xyz $(MDDEPDIR)/zot$(AB_rCD).xyz.pp $(call MERGE_RELATIVE_FILE,localized-input,locales) $(srcdir)/non-localized-input)' % env.topsrcdir,
         self.maxDiff = None
         self.assertEqual(lines, expected)
     def test_exports_generated(self):
         """Ensure EXPORTS that are listed in GENERATED_FILES
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -1366,20 +1366,20 @@ class TestEmitterBasic(unittest.TestCase
             self.assertEqual(len(files), 3)
             expected = {'en-US/bar.ini', 'en-US/code/*.js', 'en-US/foo.js'}
             for f in files:
                 self.assertTrue(unicode(f) in expected)
     def test_localized_files_no_en_us(self):
         """Test that LOCALIZED_FILES errors if a path does not start with
-        `en-US/` or contain `/locales/en-US/`."""
+        `en-US/` or contain `locales/en-US/`."""
         reader = self.reader('localized-files-no-en-us')
         with self.assertRaisesRegexp(SandboxValidationError,
-             'LOCALIZED_FILES paths must start with `en-US/` or contain `/locales/en-US/`: foo.js'):
+             'LOCALIZED_FILES paths must start with `en-US/` or contain `locales/en-US/`: foo.js'):
             objs = self.read_topsrcdir(reader)
     def test_localized_pp_files(self):
         """Test that LOCALIZED_PP_FILES works properly."""
         reader = self.reader('localized-pp-files')
         objs = self.read_topsrcdir(reader)
         self.assertEqual(len(objs), 1)