files-metadata.rst 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. .. _mozbuild_files_metadata:
  2. ==============
  3. Files Metadata
  4. ==============
  5. :ref:`mozbuild-files` provide a mechanism for attaching metadata to
  6. files. Essentially, you define some flags to set on a file or file
  7. pattern. Later, some tool or process queries for metadata attached to a
  8. file of interest and it does something intelligent with that data.
  9. Defining Metadata
  10. =================
  11. Files metadata is defined by using the
  12. :ref:`Files Sub-Context <mozbuild_subcontext_Files>` in ``moz.build``
  13. files. e.g.::
  14. with Files('**/Makefile.in'):
  15. BUG_COMPONENT = ('Core', 'Build Config')
  16. This working example says, *for all Makefile.in files in every directory
  17. underneath this one - including this directory - set the Bugzilla
  18. component to Core :: Build Config*.
  19. For more info, read the
  20. :ref:`docs on Files <mozbuild_subcontext_Files>`.
  21. How Metadata is Read
  22. ====================
  23. ``Files`` metadata is extracted in :ref:`mozbuild_fs_reading_mode`.
  24. Reading starts by specifying a set of files whose metadata you are
  25. interested in. For each file, the filesystem is walked to the root
  26. of the source directory. Any ``moz.build`` encountered during this
  27. walking are marked as relevant to the file.
  28. Let's say you have the following filesystem content::
  29. /moz.build
  30. /root_file
  31. /dir1/moz.build
  32. /dir1/foo
  33. /dir1/subdir1/foo
  34. /dir2/foo
  35. For ``/root_file``, the relevant ``moz.build`` files are just
  36. ``/moz.build``.
  37. For ``/dir1/foo`` and ``/dir1/subdir1/foo``, the relevant files are
  38. ``/moz.build`` and ``/dir1/moz.build``.
  39. For ``/dir2``, the relevant file is just ``/moz.build``.
  40. Once the list of relevant ``moz.build`` files is obtained, each
  41. ``moz.build`` file is evaluated. Root ``moz.build`` file first,
  42. leaf-most files last. This follows the rules of
  43. :ref:`mozbuild_fs_reading_mode`, with the set of evaluated ``moz.build``
  44. files being controlled by filesystem content, not ``DIRS`` variables.
  45. The file whose metadata is being resolved maps to a set of ``moz.build``
  46. files which in turn evaluates to a list of contexts. For file metadata,
  47. we only care about one of these contexts:
  48. :ref:`Files <mozbuild_subcontext_Files>`.
  49. We start with an empty ``Files`` instance to represent the file. As
  50. we encounter a *files sub-context*, we see if it is appropriate to
  51. this file. If it is, we apply its values. This process is repeated
  52. until all *files sub-contexts* have been applied or skipped. The final
  53. state of the ``Files`` instance is used to represent the metadata for
  54. this particular file.
  55. It may help to visualize this. Say we have 2 ``moz.build`` files::
  56. # /moz.build
  57. with Files('*.cpp'):
  58. BUG_COMPONENT = ('Core', 'XPCOM')
  59. with Files('**/*.js'):
  60. BUG_COMPONENT = ('Firefox', 'General')
  61. # /foo/moz.build
  62. with Files('*.js'):
  63. BUG_COMPONENT = ('Another', 'Component')
  64. Querying for metadata for the file ``/foo/test.js`` will reveal 3
  65. relevant ``Files`` sub-contexts. They are evaluated as follows:
  66. 1. ``/moz.build - Files('*.cpp')``. Does ``/*.cpp`` match
  67. ``/foo/test.js``? **No**. Ignore this context.
  68. 2. ``/moz.build - Files('**/*.js')``. Does ``/**/*.js`` match
  69. ``/foo/test.js``? **Yes**. Apply ``BUG_COMPONENT = ('Firefox', 'General')``
  70. to us.
  71. 3. ``/foo/moz.build - Files('*.js')``. Does ``/foo/*.js`` match
  72. ``/foo/test.js``? **Yes**. Apply
  73. ``BUG_COMPONENT = ('Another', 'Component')``.
  74. At the end of execution, we have
  75. ``BUG_COMPONENT = ('Another', 'Component')`` as the metadata for
  76. ``/foo/test.js``.
  77. One way to look at file metadata is as a stack of data structures.
  78. Each ``Files`` sub-context relevant to a given file is applied on top
  79. of the previous state, starting from an empty state. The final state
  80. wins.
  81. .. _mozbuild_files_metadata_finalizing:
  82. Finalizing Values
  83. =================
  84. The default behavior of ``Files`` sub-context evaluation is to apply new
  85. values on top of old. In most circumstances, this results in desired
  86. behavior. However, there are circumstances where this may not be
  87. desired. There is thus a mechanism to *finalize* or *freeze* values.
  88. Finalizing values is useful for scenarios where you want to prevent
  89. wildcard matches from overwriting previously-set values. This is useful
  90. for one-off files.
  91. Let's take ``Makefile.in`` files as an example. The build system module
  92. policy dictates that ``Makefile.in`` files are part of the ``Build
  93. Config`` module and should be reviewed by peers of that module. However,
  94. there exist ``Makefile.in`` files in many directories in the source
  95. tree. Without finalization, a ``*`` or ``**`` wildcard matching rule
  96. would match ``Makefile.in`` files and overwrite their metadata.
  97. Finalizing of values is performed by setting the ``FINAL`` variable
  98. on ``Files`` sub-contexts. See the
  99. :ref:`Files documentation <mozbuild_subcontext_Files>` for more.
  100. Here is an example with ``Makefile.in`` files, showing how it is
  101. possible to finalize the ``BUG_COMPONENT`` value.::
  102. # /moz.build
  103. with Files('**/Makefile.in'):
  104. BUG_COMPONENT = ('Core', 'Build Config')
  105. FINAL = True
  106. # /foo/moz.build
  107. with Files('**'):
  108. BUG_COMPONENT = ('Another', 'Component')
  109. If we query for metadata of ``/foo/Makefile.in``, both ``Files``
  110. sub-contexts match the file pattern. However, since ``BUG_COMPONENT`` is
  111. marked as finalized by ``/moz.build``, the assignment from
  112. ``/foo/moz.build`` is ignored. The final value for ``BUG_COMPONENT``
  113. is ``('Core', 'Build Config')``.
  114. Here is another example::
  115. with Files('*.cpp'):
  116. BUG_COMPONENT = ('One-Off', 'For C++')
  117. FINAL = True
  118. with Files('**'):
  119. BUG_COMPONENT = ('Regular', 'Component')
  120. For every files except ``foo.cpp``, the bug component will be resolved
  121. as ``Regular :: Component``. However, ``foo.cpp`` has its value of
  122. ``One-Off :: For C++`` preserved because it is finalized.
  123. .. important::
  124. ``FINAL`` only applied to variables defined in a context.
  125. If you want to mark one variable as finalized but want to leave
  126. another mutable, you'll need to use 2 ``Files`` contexts.
  127. Guidelines for Defining Metadata
  128. ================================
  129. In general, values defined towards the root of the source tree are
  130. generic and become more specific towards the leaves. For example,
  131. the ``BUG_COMPONENT`` for ``/browser`` might be ``Firefox :: General``
  132. whereas ``/browser/components/preferences`` would list
  133. ``Firefox :: Preferences``.