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 16Merges a list of .csv files from Bloaty into a protobuf. It takes the list as 17a first argument and the output as second. For instance: 18 19 $ bloaty_merger binary_sizes.lst binary_sizes.pb.gz 20 21""" 22 23import argparse 24import csv 25import gzip 26 27# pylint: disable=import-error 28import ninja_rsp 29 30import file_sections_pb2 31 32BLOATY_EXTENSION = ".bloaty.csv" 33 34 35def parse_csv(path): 36 """Parses a Bloaty-generated CSV file into a protobuf. 37 38 Args: 39 path: The filepath to the CSV file, relative to $ANDROID_TOP. 40 41 Returns: 42 A file_sections_pb2.File if the file was found; None otherwise. 43 """ 44 file_proto = None 45 with open(path, newline='') as csv_file: 46 file_proto = file_sections_pb2.File() 47 if path.endswith(BLOATY_EXTENSION): 48 file_proto.path = path[: -len(BLOATY_EXTENSION)] 49 section_reader = csv.DictReader(csv_file) 50 for row in section_reader: 51 section = file_proto.sections.add() 52 section.name = row["sections"] 53 section.vm_size = int(row["vmsize"]) 54 section.file_size = int(row["filesize"]) 55 return file_proto 56 57 58def create_file_size_metrics(input_list, output_proto): 59 """Creates a FileSizeMetrics proto from a list of CSV files. 60 61 Args: 62 input_list: The path to the file which contains the list of CSV files. 63 Each filepath is separated by a space. 64 output_proto: The path for the output protobuf. It will be compressed 65 using gzip. 66 """ 67 metrics = file_sections_pb2.FileSizeMetrics() 68 reader = ninja_rsp.NinjaRspFileReader(input_list) 69 for csv_path in reader: 70 file_proto = parse_csv(csv_path) 71 if file_proto: 72 metrics.files.append(file_proto) 73 with gzip.open(output_proto, "wb") as output: 74 output.write(metrics.SerializeToString()) 75 76 77def main(): 78 parser = argparse.ArgumentParser() 79 parser.add_argument("input_list_file", help="List of bloaty csv files.") 80 parser.add_argument("output_proto", help="Output proto.") 81 args = parser.parse_args() 82 create_file_size_metrics(args.input_list_file, args.output_proto) 83 84 85if __name__ == '__main__': 86 main() 87