diff options
Diffstat (limited to 'testing/code_metadata.go')
-rw-r--r-- | testing/code_metadata.go | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/testing/code_metadata.go b/testing/code_metadata.go new file mode 100644 index 000000000..926324dff --- /dev/null +++ b/testing/code_metadata.go @@ -0,0 +1,139 @@ +// Copyright 2020 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 testing + +import ( + "path/filepath" + + "android/soong/android" + "android/soong/testing/code_metadata_internal_proto" + "github.com/google/blueprint" + "google.golang.org/protobuf/proto" +) + +func CodeMetadataFactory() android.Module { + module := &CodeMetadataModule{} + + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + module.AddProperties(&module.properties) + + return module +} + +type CodeMetadataModule struct { + android.ModuleBase + android.DefaultableModuleBase + android.BazelModuleBase + + // Properties for "code_metadata" + properties struct { + // Specifies the name of the code_config. + Name string + // Specifies the team ID. + TeamId string + // Specifies the list of modules that this code_metadata covers. + Code []string + // An optional field to specify if multiple ownerships for source files is allowed. + MultiOwnership bool + } +} + +type codeDepTagType struct { + blueprint.BaseDependencyTag +} + +var codeDepTag = codeDepTagType{} + +func (module *CodeMetadataModule) DepsMutator(ctx android.BottomUpMutatorContext) { + // Validate Properties + if len(module.properties.TeamId) == 0 { + ctx.PropertyErrorf( + "TeamId", + "Team Id not found in the code_metadata module. Hint: Maybe the teamId property hasn't been properly specified.", + ) + } + if !isInt(module.properties.TeamId) { + ctx.PropertyErrorf( + "TeamId", "Invalid value for Team ID. The Team ID must be an integer.", + ) + } + if len(module.properties.Code) == 0 { + ctx.PropertyErrorf( + "Code", + "Targets to be attributed cannot be empty. Hint: Maybe the code property hasn't been properly specified.", + ) + } + ctx.AddDependency(ctx.Module(), codeDepTag, module.properties.Code...) +} + +// Provider published by CodeMetadata +type CodeMetadataProviderData struct { + IntermediatePath android.WritablePath +} + +var CodeMetadataProviderKey = blueprint.NewProvider(CodeMetadataProviderData{}) + +func (module *CodeMetadataModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + metadataList := make( + []*code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership, 0, + len(module.properties.Code), + ) + bpFilePath := filepath.Join(ctx.ModuleDir(), ctx.BlueprintsFile()) + + for _, m := range ctx.GetDirectDepsWithTag(codeDepTag) { + targetName := m.Name() + var moduleSrcs android.Paths + if ctx.OtherModuleHasProvider(m, android.SrcsFileProviderKey) { + moduleSrcs = ctx.OtherModuleProvider( + m, android.SrcsFileProviderKey, + ).(android.SrcsFileProviderData).SrcPaths + } + if module.properties.MultiOwnership { + metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{ + TargetName: &targetName, + TrendyTeamId: &module.properties.TeamId, + Path: &bpFilePath, + MultiOwnership: &module.properties.MultiOwnership, + SourceFiles: moduleSrcs.Strings(), + } + metadataList = append(metadataList, metadata) + } else { + metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{ + TargetName: &targetName, + TrendyTeamId: &module.properties.TeamId, + Path: &bpFilePath, + SourceFiles: moduleSrcs.Strings(), + } + metadataList = append(metadataList, metadata) + } + + } + codeMetadata := &code_metadata_internal_proto.CodeMetadataInternal{TargetOwnershipList: metadataList} + protoData, err := proto.Marshal(codeMetadata) + if err != nil { + ctx.ModuleErrorf("Error marshaling code metadata: %s", err.Error()) + return + } + intermediatePath := android.PathForModuleOut( + ctx, "intermediateCodeMetadata.pb", + ) + android.WriteFileRule(ctx, intermediatePath, string(protoData)) + + ctx.SetProvider( + CodeMetadataProviderKey, + CodeMetadataProviderData{IntermediatePath: intermediatePath}, + ) +} |