blob: 926324dffc5acc157d4bcb92e75e414539d2c74d [file] [log] [blame]
Aditya Choudhary8094b6b2023-10-12 19:40:17 +00001// Copyright 2020 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
15package testing
16
17import (
18 "path/filepath"
19
20 "android/soong/android"
21 "android/soong/testing/code_metadata_internal_proto"
22 "github.com/google/blueprint"
23 "google.golang.org/protobuf/proto"
24)
25
26func CodeMetadataFactory() android.Module {
27 module := &CodeMetadataModule{}
28
29 android.InitAndroidModule(module)
30 android.InitDefaultableModule(module)
31 module.AddProperties(&module.properties)
32
33 return module
34}
35
36type CodeMetadataModule struct {
37 android.ModuleBase
38 android.DefaultableModuleBase
39 android.BazelModuleBase
40
41 // Properties for "code_metadata"
42 properties struct {
43 // Specifies the name of the code_config.
44 Name string
45 // Specifies the team ID.
46 TeamId string
47 // Specifies the list of modules that this code_metadata covers.
48 Code []string
49 // An optional field to specify if multiple ownerships for source files is allowed.
50 MultiOwnership bool
51 }
52}
53
54type codeDepTagType struct {
55 blueprint.BaseDependencyTag
56}
57
58var codeDepTag = codeDepTagType{}
59
60func (module *CodeMetadataModule) DepsMutator(ctx android.BottomUpMutatorContext) {
61 // Validate Properties
62 if len(module.properties.TeamId) == 0 {
63 ctx.PropertyErrorf(
64 "TeamId",
65 "Team Id not found in the code_metadata module. Hint: Maybe the teamId property hasn't been properly specified.",
66 )
67 }
68 if !isInt(module.properties.TeamId) {
69 ctx.PropertyErrorf(
70 "TeamId", "Invalid value for Team ID. The Team ID must be an integer.",
71 )
72 }
73 if len(module.properties.Code) == 0 {
74 ctx.PropertyErrorf(
75 "Code",
76 "Targets to be attributed cannot be empty. Hint: Maybe the code property hasn't been properly specified.",
77 )
78 }
79 ctx.AddDependency(ctx.Module(), codeDepTag, module.properties.Code...)
80}
81
82// Provider published by CodeMetadata
83type CodeMetadataProviderData struct {
84 IntermediatePath android.WritablePath
85}
86
87var CodeMetadataProviderKey = blueprint.NewProvider(CodeMetadataProviderData{})
88
89func (module *CodeMetadataModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
90 metadataList := make(
91 []*code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership, 0,
92 len(module.properties.Code),
93 )
94 bpFilePath := filepath.Join(ctx.ModuleDir(), ctx.BlueprintsFile())
95
96 for _, m := range ctx.GetDirectDepsWithTag(codeDepTag) {
97 targetName := m.Name()
98 var moduleSrcs android.Paths
99 if ctx.OtherModuleHasProvider(m, android.SrcsFileProviderKey) {
100 moduleSrcs = ctx.OtherModuleProvider(
101 m, android.SrcsFileProviderKey,
102 ).(android.SrcsFileProviderData).SrcPaths
103 }
104 if module.properties.MultiOwnership {
105 metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
106 TargetName: &targetName,
107 TrendyTeamId: &module.properties.TeamId,
108 Path: &bpFilePath,
109 MultiOwnership: &module.properties.MultiOwnership,
110 SourceFiles: moduleSrcs.Strings(),
111 }
112 metadataList = append(metadataList, metadata)
113 } else {
114 metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
115 TargetName: &targetName,
116 TrendyTeamId: &module.properties.TeamId,
117 Path: &bpFilePath,
118 SourceFiles: moduleSrcs.Strings(),
119 }
120 metadataList = append(metadataList, metadata)
121 }
122
123 }
124 codeMetadata := &code_metadata_internal_proto.CodeMetadataInternal{TargetOwnershipList: metadataList}
125 protoData, err := proto.Marshal(codeMetadata)
126 if err != nil {
127 ctx.ModuleErrorf("Error marshaling code metadata: %s", err.Error())
128 return
129 }
130 intermediatePath := android.PathForModuleOut(
131 ctx, "intermediateCodeMetadata.pb",
132 )
133 android.WriteFileRule(ctx, intermediatePath, string(protoData))
134
135 ctx.SetProvider(
136 CodeMetadataProviderKey,
137 CodeMetadataProviderData{IntermediatePath: intermediatePath},
138 )
139}