diff options
23 files changed, 1032 insertions, 526 deletions
diff --git a/cmd/find_input_delta/find_input_delta/main.go b/cmd/find_input_delta/find_input_delta/main.go index a8645843c..036b239d0 100644 --- a/cmd/find_input_delta/find_input_delta/main.go +++ b/cmd/find_input_delta/find_input_delta/main.go @@ -80,15 +80,16 @@ func main() { panic(err) } - file_list := *fid_lib.CompareInternalState(prior_state, new_state, target) + file_list := fid_lib.CompareInternalState(prior_state, new_state, target) if err = file_list.Format(os.Stdout, template); err != nil { panic(err) } - metrics_file := os.Getenv("SOONG_METRICS_AGGREGATION_FILE") - if metrics_file != "" { - if err = file_list.SendMetrics(metrics_file); err != nil { + metrics_dir := os.Getenv("SOONG_METRICS_AGGREGATION_DIR") + out_dir := os.Getenv("OUT_DIR") + if metrics_dir != "" { + if err = file_list.WriteMetrics(metrics_dir, out_dir); err != nil { panic(err) } } diff --git a/cmd/find_input_delta/find_input_delta_lib/file_list.go b/cmd/find_input_delta/find_input_delta_lib/file_list.go index 01242a0e7..f1d588b88 100644 --- a/cmd/find_input_delta/find_input_delta_lib/file_list.go +++ b/cmd/find_input_delta/find_input_delta_lib/file_list.go @@ -16,10 +16,11 @@ package find_input_delta_lib import ( "fmt" + "hash/fnv" "io" "os" "path/filepath" - "slices" + "strings" "text/template" fid_exp "android/soong/cmd/find_input_delta/find_input_delta_proto" @@ -106,95 +107,75 @@ func (fl *FileList) changeFile(name string, ch *FileList) { fl.ExtCountMap[ext].Changes += 1 } -func (fl FileList) ToProto() (*fid_exp.FileList, error) { - var count uint32 - return fl.toProto(&count) -} +// Write a SoongExecutionMetrics FileList proto to `dir`. +// +// Path +// Prune any paths that +// begin with `pruneDir` (usually ${OUT_DIR}). The file is only written if any +// non-pruned changes are present. +func (fl *FileList) WriteMetrics(dir, pruneDir string) (err error) { + if dir == "" { + return fmt.Errorf("No directory given") + } + var needed bool -func (fl FileList) toProto(count *uint32) (*fid_exp.FileList, error) { - ret := &fid_exp.FileList{ - Name: proto.String(fl.Name), + if !strings.HasSuffix(pruneDir, "/") { + pruneDir += "/" } + + // Hash the dir and `fl.Name` to simplify scanning the metrics + // aggregation directory. + h := fnv.New128() + h.Write([]byte(dir + " " + fl.Name + ".FileList")) + path := fmt.Sprintf("%x.pb", h.Sum([]byte{})) + path = filepath.Join(dir, path[0:2], path[2:]) + + var msg = &fid_exp.FileList{Name: proto.String(fl.Name)} for _, a := range fl.Additions { - if *count >= MaxFilesRecorded { - break + if strings.HasPrefix(a, pruneDir) { + continue } - ret.Additions = append(ret.Additions, a) - *count += 1 + msg.Additions = append(msg.Additions, a) + needed = true } for _, ch := range fl.Changes { - if *count >= MaxFilesRecorded { - break - } else { - // Pre-increment to limit what the call adds. - *count += 1 - change, err := ch.toProto(count) - if err != nil { - return nil, err - } - ret.Changes = append(ret.Changes, change) + if strings.HasPrefix(ch.Name, pruneDir) { + continue } + msg.Changes = append(msg.Changes, ch.Name) + needed = true } for _, d := range fl.Deletions { - if *count >= MaxFilesRecorded { - break + if strings.HasPrefix(d, pruneDir) { + continue } - ret.Deletions = append(ret.Deletions, d) - } - ret.TotalDelta = proto.Uint32(*count) - exts := []string{} - for k := range fl.ExtCountMap { - exts = append(exts, k) + msg.Deletions = append(msg.Deletions, d) + needed = true } - slices.Sort(exts) - for _, k := range exts { - v := fl.ExtCountMap[k] - ret.Counts = append(ret.Counts, &fid_exp.FileCount{ - Extension: proto.String(k), - Additions: proto.Uint32(v.Additions), - Deletions: proto.Uint32(v.Deletions), - Modifications: proto.Uint32(v.Changes), - }) + if !needed { + return nil } - return ret, nil -} - -func (fl FileList) SendMetrics(path string) error { - if path == "" { - return fmt.Errorf("No path given") - } - message, err := fl.ToProto() - if err != nil { - return err - } - - // Marshal the message wrapped in SoongCombinedMetrics. data := protowire.AppendVarint( []byte{}, protowire.EncodeTag( protowire.Number(fid_exp.FieldNumbers_FIELD_NUMBERS_FILE_LIST), protowire.BytesType)) - size := uint64(proto.Size(message)) + size := uint64(proto.Size(msg)) data = protowire.AppendVarint(data, size) - data, err = proto.MarshalOptions{UseCachedSize: true}.MarshalAppend(data, message) + data, err = proto.MarshalOptions{UseCachedSize: true}.MarshalAppend(data, msg) if err != nil { return err } - out, err := os.Create(path) + err = os.MkdirAll(filepath.Dir(path), 0777) if err != nil { return err } - defer func() { - if err := out.Close(); err != nil { - fmt.Fprintf(os.Stderr, "Failed to close %s: %v\n", path, err) - } - }() - _, err = out.Write(data) - return err + + return os.WriteFile(path, data, 0644) } -func (fl FileList) Format(wr io.Writer, format string) error { +func (fl *FileList) Format(wr io.Writer, format string) error { tmpl, err := template.New("filelist").Parse(format) if err != nil { return err diff --git a/cmd/find_input_delta/find_input_delta_lib/internal_state.go b/cmd/find_input_delta/find_input_delta_lib/internal_state.go index 2b8c39527..bf4f86686 100644 --- a/cmd/find_input_delta/find_input_delta_lib/internal_state.go +++ b/cmd/find_input_delta/find_input_delta_lib/internal_state.go @@ -51,6 +51,9 @@ func CreateState(inputs []string, inspect_contents bool, fsys StatReadFileFS) (* for _, input := range inputs { stat, err := fs.Stat(fsys, input) if err != nil { + if errors.Is(err, fs.ErrNotExist) { + continue + } return ret, err } pci := &fid_proto.PartialCompileInput{ diff --git a/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go b/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go index 745de2db2..b6adc45b9 100644 --- a/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go +++ b/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go @@ -96,20 +96,14 @@ type FileList struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The name of the file. - // In the outermost message, this is the name of the Ninja target. - // When used in `changes`, this is the name of the changed file. + // The name of the output file (Ninja target). Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // The added files. Additions []string `protobuf:"bytes,2,rep,name=additions" json:"additions,omitempty"` // The changed files. - Changes []*FileList `protobuf:"bytes,3,rep,name=changes" json:"changes,omitempty"` + Changes []string `protobuf:"bytes,3,rep,name=changes" json:"changes,omitempty"` // The deleted files. Deletions []string `protobuf:"bytes,4,rep,name=deletions" json:"deletions,omitempty"` - // Count of files added/changed/deleted. - TotalDelta *uint32 `protobuf:"varint,5,opt,name=total_delta,json=totalDelta" json:"total_delta,omitempty"` - // Counts by extension. - Counts []*FileCount `protobuf:"bytes,6,rep,name=counts" json:"counts,omitempty"` } func (x *FileList) Reset() { @@ -158,7 +152,7 @@ func (x *FileList) GetAdditions() []string { return nil } -func (x *FileList) GetChanges() []*FileList { +func (x *FileList) GetChanges() []string { if x != nil { return x.Changes } @@ -172,135 +166,28 @@ func (x *FileList) GetDeletions() []string { return nil } -func (x *FileList) GetTotalDelta() uint32 { - if x != nil && x.TotalDelta != nil { - return *x.TotalDelta - } - return 0 -} - -func (x *FileList) GetCounts() []*FileCount { - if x != nil { - return x.Counts - } - return nil -} - -type FileCount struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The file extension - Extension *string `protobuf:"bytes,1,opt,name=extension" json:"extension,omitempty"` - // Number of added files with this extension. - Additions *uint32 `protobuf:"varint,2,opt,name=additions" json:"additions,omitempty"` - // Number of modified files with this extension. - Modifications *uint32 `protobuf:"varint,3,opt,name=modifications" json:"modifications,omitempty"` - // Number of deleted files with this extension. - Deletions *uint32 `protobuf:"varint,4,opt,name=deletions" json:"deletions,omitempty"` -} - -func (x *FileCount) Reset() { - *x = FileCount{} - if protoimpl.UnsafeEnabled { - mi := &file_file_list_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FileCount) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FileCount) ProtoMessage() {} - -func (x *FileCount) ProtoReflect() protoreflect.Message { - mi := &file_file_list_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FileCount.ProtoReflect.Descriptor instead. -func (*FileCount) Descriptor() ([]byte, []int) { - return file_file_list_proto_rawDescGZIP(), []int{1} -} - -func (x *FileCount) GetExtension() string { - if x != nil && x.Extension != nil { - return *x.Extension - } - return "" -} - -func (x *FileCount) GetAdditions() uint32 { - if x != nil && x.Additions != nil { - return *x.Additions - } - return 0 -} - -func (x *FileCount) GetModifications() uint32 { - if x != nil && x.Modifications != nil { - return *x.Modifications - } - return 0 -} - -func (x *FileCount) GetDeletions() uint32 { - if x != nil && x.Deletions != nil { - return *x.Deletions - } - return 0 -} - var File_file_list_proto protoreflect.FileDescriptor var file_file_list_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x82, 0x02, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x42, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64, - 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x74, - 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65, - 0x6c, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69, - 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x4a, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, - 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, - 0x42, 0x45, 0x52, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, - 0x42, 0x3b, 0x5a, 0x39, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, - 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x6f, 0x22, 0x74, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x4a, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x49, 0x45, 0x4c, 0x44, + 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, + 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x4c, 0x49, 0x53, + 0x54, 0x10, 0x01, 0x42, 0x3b, 0x5a, 0x39, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, + 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, } var ( @@ -316,20 +203,17 @@ func file_file_list_proto_rawDescGZIP() []byte { } var file_file_list_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_file_list_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_file_list_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_file_list_proto_goTypes = []interface{}{ (FieldNumbers)(0), // 0: android.find_input_delta_proto.FieldNumbers (*FileList)(nil), // 1: android.find_input_delta_proto.FileList - (*FileCount)(nil), // 2: android.find_input_delta_proto.FileCount } var file_file_list_proto_depIdxs = []int32{ - 1, // 0: android.find_input_delta_proto.FileList.changes:type_name -> android.find_input_delta_proto.FileList - 2, // 1: android.find_input_delta_proto.FileList.counts:type_name -> android.find_input_delta_proto.FileCount - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_file_list_proto_init() } @@ -350,18 +234,6 @@ func file_file_list_proto_init() { return nil } } - file_file_list_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FileCount); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ @@ -369,7 +241,7 @@ func file_file_list_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_file_list_proto_rawDesc, NumEnums: 1, - NumMessages: 2, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, diff --git a/cmd/find_input_delta/find_input_delta_proto/file_list.proto b/cmd/find_input_delta/find_input_delta_proto/file_list.proto index 7180358c8..5309d66ed 100644 --- a/cmd/find_input_delta/find_input_delta_proto/file_list.proto +++ b/cmd/find_input_delta/find_input_delta_proto/file_list.proto @@ -23,37 +23,15 @@ enum FieldNumbers { } message FileList { - // The name of the file. - // In the outermost message, this is the name of the Ninja target. - // When used in `changes`, this is the name of the changed file. + // The name of the output file (Ninja target). optional string name = 1; // The added files. repeated string additions = 2; // The changed files. - repeated FileList changes = 3; + repeated string changes = 3; // The deleted files. repeated string deletions = 4; - - // Count of files added/changed/deleted. - optional uint32 total_delta = 5; - - // Counts by extension. - repeated FileCount counts = 6; -} - -message FileCount { - // The file extension - optional string extension = 1; - - // Number of added files with this extension. - optional uint32 additions = 2; - - // Number of modified files with this extension. - optional uint32 modifications = 3; - - // Number of deleted files with this extension. - optional uint32 deletions = 4; } diff --git a/cmd/find_input_delta/find_input_delta_proto/regen.sh b/cmd/find_input_delta/find_input_delta_proto/regen.sh index d77365941..d77365941 100644..100755 --- a/cmd/find_input_delta/find_input_delta_proto/regen.sh +++ b/cmd/find_input_delta/find_input_delta_proto/regen.sh diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go index c7134d70d..972179422 100644 --- a/cmd/soong_ui/main.go +++ b/cmd/soong_ui/main.go @@ -27,6 +27,7 @@ import ( "android/soong/shared" "android/soong/ui/build" + "android/soong/ui/execution_metrics" "android/soong/ui/logger" "android/soong/ui/metrics" "android/soong/ui/signal" @@ -170,14 +171,16 @@ func main() { stat.Finish() }) criticalPath := status.NewCriticalPath() + emet := execution_metrics.NewExecutionMetrics(log) buildCtx := build.Context{ContextImpl: &build.ContextImpl{ - Context: ctx, - Logger: log, - Metrics: met, - Tracer: trace, - Writer: output, - Status: stat, - CriticalPath: criticalPath, + Context: ctx, + Logger: log, + Metrics: met, + ExecutionMetrics: emet, + Tracer: trace, + Writer: output, + Status: stat, + CriticalPath: criticalPath, }} freshConfig := func() build.Config { @@ -194,6 +197,7 @@ func main() { rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb") soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb") buildTraceFile := filepath.Join(logsDir, c.logsPrefix+"build.trace.gz") + executionMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_execution_metrics.pb") metricsFiles := []string{ buildErrorFile, // build error strings @@ -204,9 +208,16 @@ func main() { } defer func() { + emet.Finish(buildCtx) stat.Finish() criticalPath.WriteToMetrics(met) met.Dump(soongMetricsFile) + emet.Dump(executionMetricsFile, args) + // If there are execution metrics, upload them. + if _, err := os.Stat(executionMetricsFile); err == nil { + // TODO: Upload the metrics file. + // metricsFiles = append(metricsFiles, executionMetricsFile) + } if !config.SkipMetricsUpload() { build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, metricsFiles...) } diff --git a/ui/build/Android.bp b/ui/build/Android.bp index cd93f8775..a868d6acb 100644 --- a/ui/build/Android.bp +++ b/ui/build/Android.bp @@ -41,6 +41,7 @@ bootstrap_go_package { "soong-remoteexec", "soong-shared", "soong-ui-build-paths", + "soong-ui-execution-metrics", "soong-ui-logger", "soong-ui-metrics", "soong-ui-status", diff --git a/ui/build/context.go b/ui/build/context.go index fd20e265c..69e5f96a9 100644 --- a/ui/build/context.go +++ b/ui/build/context.go @@ -18,6 +18,7 @@ import ( "context" "io" + "android/soong/ui/execution_metrics" "android/soong/ui/logger" "android/soong/ui/metrics" soong_metrics_proto "android/soong/ui/metrics/metrics_proto" @@ -33,7 +34,8 @@ type ContextImpl struct { context.Context logger.Logger - Metrics *metrics.Metrics + Metrics *metrics.Metrics + ExecutionMetrics *execution_metrics.ExecutionMetrics Writer io.Writer Status *status.Status diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index 5df3a959b..e0b2c08b9 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -273,6 +273,7 @@ func runMakeProductConfig(ctx Context, config Config) { "BUILD_BROKEN_USES_BUILD_SHARED_LIBRARY", "BUILD_BROKEN_USES_BUILD_STATIC_JAVA_LIBRARY", "BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY", + "RELEASE_BUILD_EXECUTION_METRICS", }, exportEnvVars...), BannerVars...) makeVars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true, "") diff --git a/ui/build/ninja.go b/ui/build/ninja.go index ced1e2064..b0c9c07d9 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -245,6 +245,9 @@ func runNinjaForBuild(ctx Context, config Config) { // SOONG_USE_PARTIAL_COMPILE only determines which half of the rule we execute. "SOONG_USE_PARTIAL_COMPILE", + + // Directory for ExecutionMetrics + "SOONG_METRICS_AGGREGATION_DIR", }, config.BuildBrokenNinjaUsesEnvVars()...)...) } @@ -257,6 +260,10 @@ func runNinjaForBuild(ctx Context, config Config) { // Only set RUST_BACKTRACE for n2. } + // Set up the metrics aggregation directory. + ctx.ExecutionMetrics.SetDir(filepath.Join(config.OutDir(), "soong", "metrics_aggregation")) + cmd.Environment.Set("SOONG_METRICS_AGGREGATION_DIR", ctx.ExecutionMetrics.MetricsAggregationDir) + // Print the environment variables that Ninja is operating in. ctx.Verboseln("Ninja environment: ") envVars := cmd.Environment.Environ() @@ -301,6 +308,8 @@ func runNinjaForBuild(ctx Context, config Config) { } }() + ctx.ExecutionMetrics.Start() + defer ctx.ExecutionMetrics.Finish(ctx) ctx.Status.Status("Starting ninja...") cmd.RunAndStreamOrFatal() } diff --git a/ui/execution_metrics/Android.bp b/ui/execution_metrics/Android.bp new file mode 100644 index 000000000..542e55076 --- /dev/null +++ b/ui/execution_metrics/Android.bp @@ -0,0 +1,35 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-ui-execution-metrics", + pkgPath: "android/soong/ui/execution_metrics", + deps: [ + "golang-protobuf-proto", + "soong-shared", + "soong-ui-logger", + "soong-ui-execution_metrics_proto", + "soong-ui-metrics_proto", + "soong-cmd-find_input_delta-proto", + ], + srcs: [ + "execution_metrics.go", + ], + testSrcs: [ + ], +} diff --git a/ui/execution_metrics/execution_metrics.go b/ui/execution_metrics/execution_metrics.go new file mode 100644 index 000000000..4ea251fa4 --- /dev/null +++ b/ui/execution_metrics/execution_metrics.go @@ -0,0 +1,273 @@ +// Copyright 2024 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package execution_metrics represents the metrics system for Android Platform Build Systems. +package execution_metrics + +// This is the main heart of the metrics system for Android Platform Build Systems. +// The starting of the soong_ui (cmd/soong_ui/main.go), the metrics system is +// initialized by the invocation of New and is then stored in the context +// (ui/build/context.go) to be used throughout the system. During the build +// initialization phase, several functions in this file are invoked to store +// information such as the environment, build configuration and build metadata. +// There are several scoped code that has Begin() and defer End() functions +// that captures the metrics and is them added as a perfInfo into the set +// of the collected metrics. Finally, when soong_ui has finished the build, +// the defer Dump function is invoked to store the collected metrics to the +// raw protobuf file in the $OUT directory and this raw protobuf file will be +// uploaded to the destination. See ui/build/upload.go for more details. The +// filename of the raw protobuf file and the list of files to be uploaded is +// defined in cmd/soong_ui/main.go. See ui/metrics/event.go for the explanation +// of what an event is and how the metrics system is a stack based system. + +import ( + "context" + "io/fs" + "maps" + "os" + "path/filepath" + "slices" + "sync" + + "android/soong/ui/logger" + + fid_proto "android/soong/cmd/find_input_delta/find_input_delta_proto" + "android/soong/ui/metrics" + soong_execution_proto "android/soong/ui/metrics/execution_metrics_proto" + soong_metrics_proto "android/soong/ui/metrics/metrics_proto" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" +) + +type ExecutionMetrics struct { + MetricsAggregationDir string + ctx context.Context + logger logger.Logger + waitGroup sync.WaitGroup + fileList *fileList +} + +type fileList struct { + totalChanges uint32 + changes fileChanges + seenFiles map[string]bool +} + +type fileChanges struct { + additions changeInfo + deletions changeInfo + modifications changeInfo +} + +type fileChangeCounts struct { + additions uint32 + deletions uint32 + modifications uint32 +} + +type changeInfo struct { + total uint32 + list []string + byExtension map[string]uint32 +} + +var MAXIMUM_FILES uint32 = 50 + +// Setup the handler for SoongExecutionMetrics. +func NewExecutionMetrics(log logger.Logger) *ExecutionMetrics { + return &ExecutionMetrics{ + logger: log, + fileList: &fileList{seenFiles: make(map[string]bool)}, + } +} + +// Save the path for ExecutionMetrics communications. +func (c *ExecutionMetrics) SetDir(path string) { + c.MetricsAggregationDir = path +} + +// Start collecting SoongExecutionMetrics. +func (c *ExecutionMetrics) Start() { + if c.MetricsAggregationDir == "" { + return + } + + tmpDir := c.MetricsAggregationDir + ".rm" + if _, err := fs.Stat(os.DirFS("."), c.MetricsAggregationDir); err == nil { + if err = os.RemoveAll(tmpDir); err != nil { + c.logger.Fatalf("Failed to remove %s: %v", tmpDir, err) + } + if err = os.Rename(c.MetricsAggregationDir, tmpDir); err != nil { + c.logger.Fatalf("Failed to rename %s to %s: %v", c.MetricsAggregationDir, tmpDir) + } + } + if err := os.MkdirAll(c.MetricsAggregationDir, 0777); err != nil { + c.logger.Fatalf("Failed to create %s: %v", c.MetricsAggregationDir) + } + + c.waitGroup.Add(1) + go func(d string) { + defer c.waitGroup.Done() + os.RemoveAll(d) + }(tmpDir) + + c.logger.Verbosef("ExecutionMetrics running\n") +} + +type hasTrace interface { + BeginTrace(name, desc string) + EndTrace() +} + +// Aggregate any execution metrics. +func (c *ExecutionMetrics) Finish(ctx hasTrace) { + ctx.BeginTrace(metrics.RunSoong, "execution_metrics.Finish") + defer ctx.EndTrace() + if c.MetricsAggregationDir == "" { + return + } + c.waitGroup.Wait() + + // Find and process all of the metrics files. + aggFs := os.DirFS(c.MetricsAggregationDir) + fs.WalkDir(aggFs, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + c.logger.Fatalf("ExecutionMetrics.Finish: Error walking %s: %v", c.MetricsAggregationDir, err) + } + if d.IsDir() { + return nil + } + path = filepath.Join(c.MetricsAggregationDir, path) + r, err := os.ReadFile(path) + if err != nil { + c.logger.Fatalf("ExecutionMetrics.Finish: Failed to read %s: %v", path, err) + } + msg := &soong_execution_proto.SoongExecutionMetrics{} + err = proto.Unmarshal(r, msg) + if err != nil { + c.logger.Verbosef("ExecutionMetrics.Finish: Error unmarshalling SoongExecutionMetrics message: %v\n", err) + return nil + } + switch { + case msg.GetFileList() != nil: + if err := c.fileList.aggregateFileList(msg.GetFileList()); err != nil { + c.logger.Verbosef("ExecutionMetrics.Finish: Error processing SoongExecutionMetrics message: %v\n", err) + } + // Status update for all others. + default: + tag, _ := protowire.ConsumeVarint(r) + id, _ := protowire.DecodeTag(tag) + c.logger.Verbosef("ExecutionMetrics.Finish: Unexpected SoongExecutionMetrics submessage id=%d\n", id) + } + return nil + }) +} + +func (fl *fileList) aggregateFileList(msg *fid_proto.FileList) error { + fl.updateChangeInfo(msg.GetAdditions(), &fl.changes.additions) + fl.updateChangeInfo(msg.GetDeletions(), &fl.changes.deletions) + fl.updateChangeInfo(msg.GetChanges(), &fl.changes.modifications) + return nil +} + +func (fl *fileList) updateChangeInfo(list []string, info *changeInfo) { + for _, filename := range list { + if fl.seenFiles[filename] { + continue + } + fl.seenFiles[filename] = true + if info.total < MAXIMUM_FILES { + info.list = append(info.list, filename) + } + ext := filepath.Ext(filename) + if info.byExtension == nil { + info.byExtension = make(map[string]uint32) + } + info.byExtension[ext] += 1 + info.total += 1 + fl.totalChanges += 1 + } +} + +func (c *ExecutionMetrics) Dump(path string, args []string) error { + if c.MetricsAggregationDir == "" { + return nil + } + msg := c.GetMetrics() + msg.CommandArgs = args + + if _, err := os.Stat(filepath.Dir(path)); err != nil { + if err = os.MkdirAll(filepath.Dir(path), 0775); err != nil { + return err + } + } + data, err := proto.Marshal(msg) + if err != nil { + return err + } + return os.WriteFile(path, data, 0644) +} + +func (c *ExecutionMetrics) GetMetrics() *soong_metrics_proto.AggregatedFileList { + fl := c.fileList + if fl == nil { + return nil + } + var count uint32 + fileCounts := make(map[string]*soong_metrics_proto.FileCount) + ret := &soong_metrics_proto.AggregatedFileList{TotalDelta: proto.Uint32(c.fileList.totalChanges)} + + // MAXIMUM_FILES is the upper bound on total file names reported. + if limit := min(MAXIMUM_FILES-min(MAXIMUM_FILES, count), fl.changes.additions.total); limit > 0 { + ret.Additions = fl.changes.additions.list[:limit] + count += limit + } + if limit := min(MAXIMUM_FILES-min(MAXIMUM_FILES, count), fl.changes.modifications.total); limit > 0 { + ret.Changes = fl.changes.modifications.list[:limit] + count += limit + } + if limit := min(MAXIMUM_FILES-min(MAXIMUM_FILES, count), fl.changes.deletions.total); limit > 0 { + ret.Deletions = fl.changes.deletions.list[:limit] + count += limit + } + + addExt := func(key string) *soong_metrics_proto.FileCount { + // Create the fileCounts map entry if needed, and return the address to the caller. + if _, ok := fileCounts[key]; !ok { + fileCounts[key] = &soong_metrics_proto.FileCount{Extension: proto.String(key)} + } + return fileCounts[key] + } + addCount := func(loc **uint32, count uint32) { + if *loc == nil { + *loc = proto.Uint32(0) + } + **loc += count + } + for k, v := range fl.changes.additions.byExtension { + addCount(&addExt(k).Additions, v) + } + for k, v := range fl.changes.modifications.byExtension { + addCount(&addExt(k).Modifications, v) + } + for k, v := range fl.changes.deletions.byExtension { + addCount(&addExt(k).Deletions, v) + } + + keys := slices.Sorted(maps.Keys(fileCounts)) + for _, k := range keys { + ret.Counts = append(ret.Counts, fileCounts[k]) + } + return ret +} diff --git a/ui/execution_metrics/execution_metrics_test.go b/ui/execution_metrics/execution_metrics_test.go new file mode 100644 index 000000000..28fa973e9 --- /dev/null +++ b/ui/execution_metrics/execution_metrics_test.go @@ -0,0 +1,63 @@ +// Copyright 2024 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package execution_metrics represents the metrics system for Android Platform Build Systems. +package execution_metrics + +import ( + "reflect" + "testing" + + fid_proto "android/soong/cmd/find_input_delta/find_input_delta_proto" +) + +func TestUpdateChangeInfo(t *testing.T) { + testCases := []struct { + Name string + Message *fid_proto.FileList + FileList *fileList + Expected *fileList + }{ + { + Name: "various", + Message: &fid_proto.FileList{ + Additions: []string{"file1", "file2", "file3", "file2"}, + Deletions: []string{"file5.go", "file6"}, + }, + FileList: &fileList{seenFiles: make(map[string]bool)}, + Expected: &fileList{ + seenFiles: map[string]bool{"file1": true, "file2": true, "file3": true, "file5.go": true, "file6": true}, + totalChanges: 5, + changes: fileChanges{ + additions: changeInfo{ + total: 3, + list: []string{"file1", "file2", "file3"}, + byExtension: map[string]uint32{"": 3}, + }, + deletions: changeInfo{ + total: 2, + list: []string{"file5.go", "file6"}, + byExtension: map[string]uint32{"": 1, ".go": 1}, + }, + }, + }, + }, + } + for _, tc := range testCases { + tc.FileList.aggregateFileList(tc.Message) + if !reflect.DeepEqual(tc.FileList, tc.Expected) { + t.Errorf("Expected: %v, Actual: %v", tc.Expected, tc.FileList) + } + } +} diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp index 591e3cca6..2e19f7aa7 100644 --- a/ui/metrics/Android.bp +++ b/ui/metrics/Android.bp @@ -26,7 +26,7 @@ bootstrap_go_package { "soong-ui-metrics_proto", "soong-ui-mk_metrics_proto", "soong-shared", - "soong-ui-metrics_combined_proto", + "soong-ui-execution_metrics_proto", ], srcs: [ "hostinfo.go", @@ -64,15 +64,15 @@ bootstrap_go_package { } bootstrap_go_package { - name: "soong-ui-metrics_combined_proto", - pkgPath: "android/soong/ui/metrics/combined_metrics_proto", + name: "soong-ui-execution_metrics_proto", + pkgPath: "android/soong/ui/metrics/execution_metrics_proto", deps: [ "golang-protobuf-reflect-protoreflect", "golang-protobuf-runtime-protoimpl", "soong-cmd-find_input_delta-proto", ], srcs: [ - "metrics_proto/metrics.pb.go", + "execution_metrics_proto/execution_metrics.pb.go", ], } diff --git a/ui/metrics/execution_metrics_proto/execution_metrics.pb.go b/ui/metrics/execution_metrics_proto/execution_metrics.pb.go new file mode 100644 index 000000000..a065dbd00 --- /dev/null +++ b/ui/metrics/execution_metrics_proto/execution_metrics.pb.go @@ -0,0 +1,240 @@ +// Copyright 2024 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: execution_metrics.proto + +package execution_metrics_proto + +import ( + find_input_delta_proto "android/soong/cmd/find_input_delta/find_input_delta_proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// These field numbers are also found in the inner message declarations. +// We verify that the values are the same, and that every enum value is checked +// in execution_metrics_test.go. +// Do not change this enum without also updating: +// - the submessage's .proto file +// - execution_metrics_test.go +type FieldNumbers int32 + +const ( + FieldNumbers_FIELD_NUMBERS_UNSPECIFIED FieldNumbers = 0 + FieldNumbers_FIELD_NUMBERS_FILE_LIST FieldNumbers = 1 +) + +// Enum value maps for FieldNumbers. +var ( + FieldNumbers_name = map[int32]string{ + 0: "FIELD_NUMBERS_UNSPECIFIED", + 1: "FIELD_NUMBERS_FILE_LIST", + } + FieldNumbers_value = map[string]int32{ + "FIELD_NUMBERS_UNSPECIFIED": 0, + "FIELD_NUMBERS_FILE_LIST": 1, + } +) + +func (x FieldNumbers) Enum() *FieldNumbers { + p := new(FieldNumbers) + *p = x + return p +} + +func (x FieldNumbers) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FieldNumbers) Descriptor() protoreflect.EnumDescriptor { + return file_execution_metrics_proto_enumTypes[0].Descriptor() +} + +func (FieldNumbers) Type() protoreflect.EnumType { + return &file_execution_metrics_proto_enumTypes[0] +} + +func (x FieldNumbers) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *FieldNumbers) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = FieldNumbers(num) + return nil +} + +// Deprecated: Use FieldNumbers.Descriptor instead. +func (FieldNumbers) EnumDescriptor() ([]byte, []int) { + return file_execution_metrics_proto_rawDescGZIP(), []int{0} +} + +type SoongExecutionMetrics struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // cmd/find_input_delta/find_input_delta_proto.FileList + FileList *find_input_delta_proto.FileList `protobuf:"bytes,1,opt,name=file_list,json=fileList" json:"file_list,omitempty"` +} + +func (x *SoongExecutionMetrics) Reset() { + *x = SoongExecutionMetrics{} + if protoimpl.UnsafeEnabled { + mi := &file_execution_metrics_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SoongExecutionMetrics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SoongExecutionMetrics) ProtoMessage() {} + +func (x *SoongExecutionMetrics) ProtoReflect() protoreflect.Message { + mi := &file_execution_metrics_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SoongExecutionMetrics.ProtoReflect.Descriptor instead. +func (*SoongExecutionMetrics) Descriptor() ([]byte, []int) { + return file_execution_metrics_proto_rawDescGZIP(), []int{0} +} + +func (x *SoongExecutionMetrics) GetFileList() *find_input_delta_proto.FileList { + if x != nil { + return x.FileList + } + return nil +} + +var File_execution_metrics_proto protoreflect.FileDescriptor + +var file_execution_metrics_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x73, 0x6f, 0x6f, 0x6e, 0x67, + 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x3b, + 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, + 0x65, 0x6c, 0x74, 0x61, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, + 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x69, 0x6c, 0x65, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5e, 0x0a, 0x15, 0x53, + 0x6f, 0x6f, 0x6e, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, + 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, + 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2a, 0x4a, 0x0a, 0x0c, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x46, + 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, + 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, + 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x42, 0x32, 0x5a, 0x30, 0x61, 0x6e, 0x64, 0x72, 0x6f, + 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, +} + +var ( + file_execution_metrics_proto_rawDescOnce sync.Once + file_execution_metrics_proto_rawDescData = file_execution_metrics_proto_rawDesc +) + +func file_execution_metrics_proto_rawDescGZIP() []byte { + file_execution_metrics_proto_rawDescOnce.Do(func() { + file_execution_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_execution_metrics_proto_rawDescData) + }) + return file_execution_metrics_proto_rawDescData +} + +var file_execution_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_execution_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_execution_metrics_proto_goTypes = []interface{}{ + (FieldNumbers)(0), // 0: soong_build_metrics.FieldNumbers + (*SoongExecutionMetrics)(nil), // 1: soong_build_metrics.SoongExecutionMetrics + (*find_input_delta_proto.FileList)(nil), // 2: android.find_input_delta_proto.FileList +} +var file_execution_metrics_proto_depIdxs = []int32{ + 2, // 0: soong_build_metrics.SoongExecutionMetrics.file_list:type_name -> android.find_input_delta_proto.FileList + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_execution_metrics_proto_init() } +func file_execution_metrics_proto_init() { + if File_execution_metrics_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_execution_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SoongExecutionMetrics); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_execution_metrics_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_execution_metrics_proto_goTypes, + DependencyIndexes: file_execution_metrics_proto_depIdxs, + EnumInfos: file_execution_metrics_proto_enumTypes, + MessageInfos: file_execution_metrics_proto_msgTypes, + }.Build() + File_execution_metrics_proto = out.File + file_execution_metrics_proto_rawDesc = nil + file_execution_metrics_proto_goTypes = nil + file_execution_metrics_proto_depIdxs = nil +} diff --git a/ui/metrics/metrics_proto/combined_metrics.proto b/ui/metrics/execution_metrics_proto/execution_metrics.proto index 3cd9a5313..381dcd10a 100644 --- a/ui/metrics/metrics_proto/combined_metrics.proto +++ b/ui/metrics/execution_metrics_proto/execution_metrics.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. All Rights Reserved. +// Copyright 2024 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,22 +15,22 @@ syntax = "proto2"; package soong_build_metrics; -option go_package = "android/soong/ui/metrics/metrics_proto"; +option go_package = "android/soong/ui/metrics/execution_metrics_proto"; import "cmd/find_input_delta/find_input_delta_proto/file_list.proto"; // These field numbers are also found in the inner message declarations. // We verify that the values are the same, and that every enum value is checked -// in combined_metrics_test.go. +// in execution_metrics_test.go. // Do not change this enum without also updating: // - the submessage's .proto file -// - combined_metrics_test.go +// - execution_metrics_test.go enum FieldNumbers { FIELD_NUMBERS_UNSPECIFIED = 0; FIELD_NUMBERS_FILE_LIST = 1; } -message SoongCombinedMetrics { +message SoongExecutionMetrics { // cmd/find_input_delta/find_input_delta_proto.FileList optional android.find_input_delta_proto.FileList file_list = 1; } diff --git a/ui/metrics/metrics_proto/combined_metrics_test.go b/ui/metrics/execution_metrics_proto/execution_metrics_test.go index eedb12a34..2f71c21dd 100644 --- a/ui/metrics/metrics_proto/combined_metrics_test.go +++ b/ui/metrics/execution_metrics_proto/execution_metrics_test.go @@ -1,4 +1,4 @@ -package metrics_proto +package execution_metrics_proto import ( "testing" @@ -6,7 +6,7 @@ import ( find_input_delta_proto "android/soong/cmd/find_input_delta/find_input_delta_proto" ) -func TestCombinedMetricsMessageNums(t *testing.T) { +func TestExecutionMetricsMessageNums(t *testing.T) { testCases := []struct { Name string FieldNumbers map[string]int32 diff --git a/ui/metrics/execution_metrics_proto/regen.sh b/ui/metrics/execution_metrics_proto/regen.sh new file mode 100755 index 000000000..5339a9ac9 --- /dev/null +++ b/ui/metrics/execution_metrics_proto/regen.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Generates the golang source file of metrics.proto protobuf file. + +set -e + +function die() { echo "ERROR: $1" >&2; exit 1; } + +readonly error_msg="Maybe you need to run 'lunch aosp_arm-eng && m aprotoc blueprint_tools'?" + +if ! hash aprotoc &>/dev/null; then + die "could not find aprotoc. ${error_msg}" +fi + +if ! aprotoc --go_out=paths=source_relative:. -I .:../../.. execution_metrics.proto; then + die "build failed. ${error_msg}" +fi diff --git a/ui/metrics/metrics_proto/combined_metrics.pb.go b/ui/metrics/metrics_proto/combined_metrics.pb.go deleted file mode 100644 index f49d64d54..000000000 --- a/ui/metrics/metrics_proto/combined_metrics.pb.go +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2018 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.33.0 -// protoc v3.21.12 -// source: combined_metrics.proto - -package metrics_proto - -import ( - find_input_delta_proto "android/soong/cmd/find_input_delta/find_input_delta_proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// These field numbers are also found in the inner message declarations. -// We verify that the values are the same, and that every enum value is checked -// in combined_metrics_test.go. -// Do not change this enum without also updating: -// - the submessage's .proto file -// - combined_metrics_test.go -type FieldNumbers int32 - -const ( - FieldNumbers_FIELD_NUMBERS_UNSPECIFIED FieldNumbers = 0 - FieldNumbers_FIELD_NUMBERS_FILE_LIST FieldNumbers = 1 -) - -// Enum value maps for FieldNumbers. -var ( - FieldNumbers_name = map[int32]string{ - 0: "FIELD_NUMBERS_UNSPECIFIED", - 1: "FIELD_NUMBERS_FILE_LIST", - } - FieldNumbers_value = map[string]int32{ - "FIELD_NUMBERS_UNSPECIFIED": 0, - "FIELD_NUMBERS_FILE_LIST": 1, - } -) - -func (x FieldNumbers) Enum() *FieldNumbers { - p := new(FieldNumbers) - *p = x - return p -} - -func (x FieldNumbers) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (FieldNumbers) Descriptor() protoreflect.EnumDescriptor { - return file_combined_metrics_proto_enumTypes[0].Descriptor() -} - -func (FieldNumbers) Type() protoreflect.EnumType { - return &file_combined_metrics_proto_enumTypes[0] -} - -func (x FieldNumbers) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Do not use. -func (x *FieldNumbers) UnmarshalJSON(b []byte) error { - num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) - if err != nil { - return err - } - *x = FieldNumbers(num) - return nil -} - -// Deprecated: Use FieldNumbers.Descriptor instead. -func (FieldNumbers) EnumDescriptor() ([]byte, []int) { - return file_combined_metrics_proto_rawDescGZIP(), []int{0} -} - -type SoongCombinedMetrics struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // cmd/find_input_delta/find_input_delta_proto.FileList - FileList *find_input_delta_proto.FileList `protobuf:"bytes,1,opt,name=file_list,json=fileList" json:"file_list,omitempty"` -} - -func (x *SoongCombinedMetrics) Reset() { - *x = SoongCombinedMetrics{} - if protoimpl.UnsafeEnabled { - mi := &file_combined_metrics_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SoongCombinedMetrics) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SoongCombinedMetrics) ProtoMessage() {} - -func (x *SoongCombinedMetrics) ProtoReflect() protoreflect.Message { - mi := &file_combined_metrics_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SoongCombinedMetrics.ProtoReflect.Descriptor instead. -func (*SoongCombinedMetrics) Descriptor() ([]byte, []int) { - return file_combined_metrics_proto_rawDescGZIP(), []int{0} -} - -func (x *SoongCombinedMetrics) GetFileList() *find_input_delta_proto.FileList { - if x != nil { - return x.FileList - } - return nil -} - -var File_combined_metrics_proto protoreflect.FileDescriptor - -var file_combined_metrics_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, - 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x3b, 0x63, - 0x6d, 0x64, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, - 0x6c, 0x74, 0x61, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, - 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x14, 0x53, 0x6f, - 0x6f, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, - 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, - 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2a, 0x4a, 0x0a, 0x0c, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x49, 0x45, - 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, 0x45, 0x4c, - 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x4c, - 0x49, 0x53, 0x54, 0x10, 0x01, 0x42, 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, - 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, -} - -var ( - file_combined_metrics_proto_rawDescOnce sync.Once - file_combined_metrics_proto_rawDescData = file_combined_metrics_proto_rawDesc -) - -func file_combined_metrics_proto_rawDescGZIP() []byte { - file_combined_metrics_proto_rawDescOnce.Do(func() { - file_combined_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_combined_metrics_proto_rawDescData) - }) - return file_combined_metrics_proto_rawDescData -} - -var file_combined_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_combined_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_combined_metrics_proto_goTypes = []interface{}{ - (FieldNumbers)(0), // 0: soong_build_metrics.FieldNumbers - (*SoongCombinedMetrics)(nil), // 1: soong_build_metrics.SoongCombinedMetrics - (*find_input_delta_proto.FileList)(nil), // 2: android.find_input_delta_proto.FileList -} -var file_combined_metrics_proto_depIdxs = []int32{ - 2, // 0: soong_build_metrics.SoongCombinedMetrics.file_list:type_name -> android.find_input_delta_proto.FileList - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_combined_metrics_proto_init() } -func file_combined_metrics_proto_init() { - if File_combined_metrics_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_combined_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SoongCombinedMetrics); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_combined_metrics_proto_rawDesc, - NumEnums: 1, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_combined_metrics_proto_goTypes, - DependencyIndexes: file_combined_metrics_proto_depIdxs, - EnumInfos: file_combined_metrics_proto_enumTypes, - MessageInfos: file_combined_metrics_proto_msgTypes, - }.Build() - File_combined_metrics_proto = out.File - file_combined_metrics_proto_rawDesc = nil - file_combined_metrics_proto_goTypes = nil - file_combined_metrics_proto_depIdxs = nil -} diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go index 72fdbe829..0aa51b166 100644 --- a/ui/metrics/metrics_proto/metrics.pb.go +++ b/ui/metrics/metrics_proto/metrics.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.30.0 // protoc v3.21.12 // source: metrics.proto @@ -2080,6 +2080,177 @@ func (x *OptimizedBuildMetrics) GetTargetResult() []*OptimizedBuildMetrics_Targe return nil } +// This is created by soong_ui from the various +// android.find_input_delta_proto.FileList metrics provided to it by +// find_input_delta. +type AggregatedFileList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The arguments provided on the command line. + CommandArgs []string `protobuf:"bytes,1,rep,name=command_args,json=commandArgs" json:"command_args,omitempty"` + // The (possibly truncated list of) added files. + Additions []string `protobuf:"bytes,2,rep,name=additions" json:"additions,omitempty"` + // The (possibly truncated list of) changed files. + Changes []string `protobuf:"bytes,3,rep,name=changes" json:"changes,omitempty"` + // The (possibly truncated list of) deleted files. + Deletions []string `protobuf:"bytes,4,rep,name=deletions" json:"deletions,omitempty"` + // Count of files added/changed/deleted. + TotalDelta *uint32 `protobuf:"varint,5,opt,name=total_delta,json=totalDelta" json:"total_delta,omitempty"` + // Counts by extension. + Counts []*FileCount `protobuf:"bytes,6,rep,name=counts" json:"counts,omitempty"` +} + +func (x *AggregatedFileList) Reset() { + *x = AggregatedFileList{} + if protoimpl.UnsafeEnabled { + mi := &file_metrics_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AggregatedFileList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AggregatedFileList) ProtoMessage() {} + +func (x *AggregatedFileList) ProtoReflect() protoreflect.Message { + mi := &file_metrics_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AggregatedFileList.ProtoReflect.Descriptor instead. +func (*AggregatedFileList) Descriptor() ([]byte, []int) { + return file_metrics_proto_rawDescGZIP(), []int{19} +} + +func (x *AggregatedFileList) GetCommandArgs() []string { + if x != nil { + return x.CommandArgs + } + return nil +} + +func (x *AggregatedFileList) GetAdditions() []string { + if x != nil { + return x.Additions + } + return nil +} + +func (x *AggregatedFileList) GetChanges() []string { + if x != nil { + return x.Changes + } + return nil +} + +func (x *AggregatedFileList) GetDeletions() []string { + if x != nil { + return x.Deletions + } + return nil +} + +func (x *AggregatedFileList) GetTotalDelta() uint32 { + if x != nil && x.TotalDelta != nil { + return *x.TotalDelta + } + return 0 +} + +func (x *AggregatedFileList) GetCounts() []*FileCount { + if x != nil { + return x.Counts + } + return nil +} + +type FileCount struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The file extension + Extension *string `protobuf:"bytes,1,opt,name=extension" json:"extension,omitempty"` + // Number of added files with this extension. + Additions *uint32 `protobuf:"varint,2,opt,name=additions" json:"additions,omitempty"` + // Number of modified files with this extension. + Modifications *uint32 `protobuf:"varint,3,opt,name=modifications" json:"modifications,omitempty"` + // Number of deleted files with this extension. + Deletions *uint32 `protobuf:"varint,4,opt,name=deletions" json:"deletions,omitempty"` +} + +func (x *FileCount) Reset() { + *x = FileCount{} + if protoimpl.UnsafeEnabled { + mi := &file_metrics_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileCount) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileCount) ProtoMessage() {} + +func (x *FileCount) ProtoReflect() protoreflect.Message { + mi := &file_metrics_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileCount.ProtoReflect.Descriptor instead. +func (*FileCount) Descriptor() ([]byte, []int) { + return file_metrics_proto_rawDescGZIP(), []int{20} +} + +func (x *FileCount) GetExtension() string { + if x != nil && x.Extension != nil { + return *x.Extension + } + return "" +} + +func (x *FileCount) GetAdditions() uint32 { + if x != nil && x.Additions != nil { + return *x.Additions + } + return 0 +} + +func (x *FileCount) GetModifications() uint32 { + if x != nil && x.Modifications != nil { + return *x.Modifications + } + return 0 +} + +func (x *FileCount) GetDeletions() uint32 { + if x != nil && x.Deletions != nil { + return *x.Deletions + } + return 0 +} + type OptimizedBuildMetrics_TargetOptimizationResult struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2101,7 +2272,7 @@ type OptimizedBuildMetrics_TargetOptimizationResult struct { func (x *OptimizedBuildMetrics_TargetOptimizationResult) Reset() { *x = OptimizedBuildMetrics_TargetOptimizationResult{} if protoimpl.UnsafeEnabled { - mi := &file_metrics_proto_msgTypes[19] + mi := &file_metrics_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2114,7 +2285,7 @@ func (x *OptimizedBuildMetrics_TargetOptimizationResult) String() string { func (*OptimizedBuildMetrics_TargetOptimizationResult) ProtoMessage() {} func (x *OptimizedBuildMetrics_TargetOptimizationResult) ProtoReflect() protoreflect.Message { - mi := &file_metrics_proto_msgTypes[19] + mi := &file_metrics_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2181,7 +2352,7 @@ type OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact struct { func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) Reset() { *x = OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact{} if protoimpl.UnsafeEnabled { - mi := &file_metrics_proto_msgTypes[20] + mi := &file_metrics_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2194,7 +2365,7 @@ func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) String() func (*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) ProtoMessage() {} func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) ProtoReflect() protoreflect.Message { - mi := &file_metrics_proto_msgTypes[20] + mi := &file_metrics_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2637,10 +2808,33 @@ var file_metrics_proto_rawDesc = []byte{ 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x28, 0x5a, - 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, - 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xe6, 0x01, + 0x0a, 0x12, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, + 0x61, 0x72, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, + 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, + 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x36, + 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, + 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, } var ( @@ -2656,7 +2850,7 @@ func file_metrics_proto_rawDescGZIP() []byte { } var file_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_metrics_proto_goTypes = []interface{}{ (MetricsBase_BuildVariant)(0), // 0: soong_build_metrics.MetricsBase.BuildVariant (MetricsBase_Arch)(0), // 1: soong_build_metrics.MetricsBase.Arch @@ -2682,8 +2876,10 @@ var file_metrics_proto_goTypes = []interface{}{ (*CriticalPathInfo)(nil), // 21: soong_build_metrics.CriticalPathInfo (*JobInfo)(nil), // 22: soong_build_metrics.JobInfo (*OptimizedBuildMetrics)(nil), // 23: soong_build_metrics.OptimizedBuildMetrics - (*OptimizedBuildMetrics_TargetOptimizationResult)(nil), // 24: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult - (*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact)(nil), // 25: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact + (*AggregatedFileList)(nil), // 24: soong_build_metrics.AggregatedFileList + (*FileCount)(nil), // 25: soong_build_metrics.FileCount + (*OptimizedBuildMetrics_TargetOptimizationResult)(nil), // 26: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult + (*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact)(nil), // 27: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact } var file_metrics_proto_depIdxs = []int32{ 0, // 0: soong_build_metrics.MetricsBase.target_build_variant:type_name -> soong_build_metrics.MetricsBase.BuildVariant @@ -2719,14 +2915,15 @@ var file_metrics_proto_depIdxs = []int32{ 22, // 30: soong_build_metrics.CriticalPathInfo.long_running_jobs:type_name -> soong_build_metrics.JobInfo 10, // 31: soong_build_metrics.OptimizedBuildMetrics.analysis_perf:type_name -> soong_build_metrics.PerfInfo 10, // 32: soong_build_metrics.OptimizedBuildMetrics.packaging_perf:type_name -> soong_build_metrics.PerfInfo - 24, // 33: soong_build_metrics.OptimizedBuildMetrics.target_result:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult - 10, // 34: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.packaging_perf:type_name -> soong_build_metrics.PerfInfo - 25, // 35: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.output_artifact:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact - 36, // [36:36] is the sub-list for method output_type - 36, // [36:36] is the sub-list for method input_type - 36, // [36:36] is the sub-list for extension type_name - 36, // [36:36] is the sub-list for extension extendee - 0, // [0:36] is the sub-list for field type_name + 26, // 33: soong_build_metrics.OptimizedBuildMetrics.target_result:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult + 25, // 34: soong_build_metrics.AggregatedFileList.counts:type_name -> soong_build_metrics.FileCount + 10, // 35: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.packaging_perf:type_name -> soong_build_metrics.PerfInfo + 27, // 36: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.output_artifact:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact + 37, // [37:37] is the sub-list for method output_type + 37, // [37:37] is the sub-list for method input_type + 37, // [37:37] is the sub-list for extension type_name + 37, // [37:37] is the sub-list for extension extendee + 0, // [0:37] is the sub-list for field type_name } func init() { file_metrics_proto_init() } @@ -2964,7 +3161,7 @@ func file_metrics_proto_init() { } } file_metrics_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult); i { + switch v := v.(*AggregatedFileList); i { case 0: return &v.state case 1: @@ -2976,6 +3173,30 @@ func file_metrics_proto_init() { } } file_metrics_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileCount); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metrics_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metrics_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact); i { case 0: return &v.state @@ -2994,7 +3215,7 @@ func file_metrics_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_metrics_proto_rawDesc, NumEnums: 5, - NumMessages: 21, + NumMessages: 23, NumExtensions: 0, NumServices: 0, }, diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto index 3fbe97c0b..8437b65ae 100644 --- a/ui/metrics/metrics_proto/metrics.proto +++ b/ui/metrics/metrics_proto/metrics.proto @@ -451,3 +451,40 @@ message OptimizedBuildMetrics { } } } + +// This is created by soong_ui from the various +// android.find_input_delta_proto.FileList metrics provided to it by +// find_input_delta. +message AggregatedFileList { + // The arguments provided on the command line. + repeated string command_args = 1; + + // The (possibly truncated list of) added files. + repeated string additions = 2; + + // The (possibly truncated list of) changed files. + repeated string changes = 3; + + // The (possibly truncated list of) deleted files. + repeated string deletions = 4; + + // Count of files added/changed/deleted. + optional uint32 total_delta = 5; + + // Counts by extension. + repeated FileCount counts = 6; +} + +message FileCount { + // The file extension + optional string extension = 1; + + // Number of added files with this extension. + optional uint32 additions = 2; + + // Number of modified files with this extension. + optional uint32 modifications = 3; + + // Number of deleted files with this extension. + optional uint32 deletions = 4; +} diff --git a/ui/metrics/metrics_proto/regen.sh b/ui/metrics/metrics_proto/regen.sh index 5e5f9b83f..8eb2d747b 100755 --- a/ui/metrics/metrics_proto/regen.sh +++ b/ui/metrics/metrics_proto/regen.sh @@ -12,6 +12,6 @@ if ! hash aprotoc &>/dev/null; then die "could not find aprotoc. ${error_msg}" fi -if ! aprotoc --go_out=paths=source_relative:. -I .:../../.. metrics.proto combined_metrics.proto; then +if ! aprotoc --go_out=paths=source_relative:. metrics.proto; then die "build failed. ${error_msg}" fi |