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