bloaty_merger.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. # Copyright 2021 Google Inc. All rights reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """Bloaty CSV Merger
  15. Merges a list of .csv files from Bloaty into a protobuf. It takes the list as
  16. a first argument and the output as second. For instance:
  17. $ bloaty_merger binary_sizes.lst binary_sizes.pb.gz
  18. """
  19. import argparse
  20. import csv
  21. import gzip
  22. # pylint: disable=import-error
  23. import ninja_rsp
  24. import file_sections_pb2
  25. BLOATY_EXTENSION = ".bloaty.csv"
  26. def parse_csv(path):
  27. """Parses a Bloaty-generated CSV file into a protobuf.
  28. Args:
  29. path: The filepath to the CSV file, relative to $ANDROID_TOP.
  30. Returns:
  31. A file_sections_pb2.File if the file was found; None otherwise.
  32. """
  33. file_proto = None
  34. with open(path, newline='') as csv_file:
  35. file_proto = file_sections_pb2.File()
  36. if path.endswith(BLOATY_EXTENSION):
  37. file_proto.path = path[: -len(BLOATY_EXTENSION)]
  38. section_reader = csv.DictReader(csv_file)
  39. for row in section_reader:
  40. section = file_proto.sections.add()
  41. section.name = row["sections"]
  42. section.vm_size = int(row["vmsize"])
  43. section.file_size = int(row["filesize"])
  44. return file_proto
  45. def create_file_size_metrics(input_list, output_proto):
  46. """Creates a FileSizeMetrics proto from a list of CSV files.
  47. Args:
  48. input_list: The path to the file which contains the list of CSV files.
  49. Each filepath is separated by a space.
  50. output_proto: The path for the output protobuf. It will be compressed
  51. using gzip.
  52. """
  53. metrics = file_sections_pb2.FileSizeMetrics()
  54. reader = ninja_rsp.NinjaRspFileReader(input_list)
  55. for csv_path in reader:
  56. file_proto = parse_csv(csv_path)
  57. if file_proto:
  58. metrics.files.append(file_proto)
  59. with gzip.open(output_proto, "wb") as output:
  60. output.write(metrics.SerializeToString())
  61. def main():
  62. parser = argparse.ArgumentParser()
  63. parser.add_argument("input_list_file", help="List of bloaty csv files.")
  64. parser.add_argument("output_proto", help="Output proto.")
  65. args = parser.parse_args()
  66. create_file_size_metrics(args.input_list_file, args.output_proto)
  67. if __name__ == '__main__':
  68. main()