metrics_xml_format.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/usr/bin/env vpython3
  2. # Copyright (c) 2024 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Redirects to the version of the metrics XML formatter in the Chromium tree.
  6. """
  7. import gclient_paths
  8. import os
  9. import shutil
  10. import subprocess
  11. import sys
  12. def GetMetricsDir(top_dir, path):
  13. metrics_xml_dirs = [
  14. os.path.join(top_dir, 'tools', 'metrics', 'actions'),
  15. os.path.join(top_dir, 'tools', 'metrics', 'histograms'),
  16. os.path.join(top_dir, 'tools', 'metrics', 'structured'),
  17. os.path.join(top_dir, 'tools', 'metrics', 'ukm'),
  18. ]
  19. abs_dirname = os.path.dirname(os.path.realpath(path))
  20. for xml_dir in metrics_xml_dirs:
  21. if abs_dirname.startswith(xml_dir):
  22. return xml_dir
  23. return None
  24. def IsSupportedHistogramsXML(path):
  25. supported_xmls = set([
  26. 'histograms.xml',
  27. 'enums.xml',
  28. 'histogram_suffixes_list.xml',
  29. ])
  30. return os.path.basename(path) in supported_xmls
  31. def log(msg, verbose):
  32. if verbose:
  33. print(msg)
  34. def FindMetricsXMLFormatterTool(path, verbose=False):
  35. """Returns a path to the metrics XML formatter executable."""
  36. top_dir = gclient_paths.GetPrimarySolutionPath()
  37. if not top_dir:
  38. log('Not executed in a Chromium checkout; skip formatting', verbose)
  39. return ''
  40. xml_dir = GetMetricsDir(top_dir, path)
  41. if not xml_dir:
  42. log(f'{path} is not a metric XML; skip formatting', verbose)
  43. return ''
  44. # Just to ensure that the given file is located in the current checkout
  45. # folder. If not, skip the formatting.
  46. if not os.path.realpath(path).startswith(os.path.realpath(top_dir)):
  47. log(
  48. f'{path} is not located in the current Chromium checkout; '
  49. 'skip formatting', verbose)
  50. return ''
  51. histograms_base_dir = os.path.join(top_dir, 'tools', 'metrics',
  52. 'histograms')
  53. if xml_dir.startswith(histograms_base_dir):
  54. # Skips the formatting, if the XML file is not one of the known types.
  55. if not IsSupportedHistogramsXML(path):
  56. log(f'{path} is not a supported histogram XML; skip formatting',
  57. verbose)
  58. return ''
  59. return os.path.join(xml_dir, 'pretty_print.py')
  60. usage_text = """Usage: %s [option] filepath
  61. Format a given metrics XML file with the metrics XML formatters in the Chromium
  62. checkout. Noop, if executed out of a Chromium checkout.
  63. Note that not all the options are understood by all the formatters.
  64. Find the formatter binaries for all the options supported by each formatter.
  65. positional arguments:
  66. filepath if the path is not under tools/metrics,
  67. no formatter will be run.
  68. options:,
  69. -h, --help show this help message and exit'
  70. --presubmit
  71. --diff"""
  72. def _print_help():
  73. print(usage_text % sys.argv[0])
  74. def main(args):
  75. path = next((arg for arg in args if not arg.startswith('-')), None)
  76. if not path:
  77. _print_help()
  78. return 0
  79. if not os.path.exists(path):
  80. raise FileNotFoundError(f'{path} does not exist.')
  81. tool = FindMetricsXMLFormatterTool(path, verbose=True)
  82. if not tool:
  83. # Fail (almost) silently.
  84. return 0
  85. subprocess.run([
  86. shutil.which('vpython3'),
  87. tool,
  88. ] + args)
  89. return 0
  90. if __name__ == '__main__':
  91. try:
  92. sys.exit(main(sys.argv[1:]))
  93. except KeyboardInterrupt:
  94. sys.stderr.write('interrupted\n')
  95. sys.exit(1)