• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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
24	"google.golang.org/protobuf/proto"
25)
26
27func CodeMetadataFactory() android.Module {
28	module := &CodeMetadataModule{}
29
30	android.InitAndroidModule(module)
31	android.InitDefaultableModule(module)
32	module.AddProperties(&module.properties)
33
34	return module
35}
36
37type CodeMetadataModule struct {
38	android.ModuleBase
39	android.DefaultableModuleBase
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 []string
99		if srcsFileInfo, ok := android.OtherModuleProvider(ctx, m, blueprint.SrcsFileProviderKey); ok {
100			moduleSrcs = srcsFileInfo.SrcPaths
101		}
102		if module.properties.MultiOwnership {
103			metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
104				TargetName:     &targetName,
105				TrendyTeamId:   &module.properties.TeamId,
106				Path:           &bpFilePath,
107				MultiOwnership: &module.properties.MultiOwnership,
108				SourceFiles:    moduleSrcs,
109			}
110			metadataList = append(metadataList, metadata)
111		} else {
112			metadata := &code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership{
113				TargetName:   &targetName,
114				TrendyTeamId: &module.properties.TeamId,
115				Path:         &bpFilePath,
116				SourceFiles:  moduleSrcs,
117			}
118			metadataList = append(metadataList, metadata)
119		}
120
121	}
122	codeMetadata := &code_metadata_internal_proto.CodeMetadataInternal{TargetOwnershipList: metadataList}
123	protoData, err := proto.Marshal(codeMetadata)
124	if err != nil {
125		ctx.ModuleErrorf("Error marshaling code metadata: %s", err.Error())
126		return
127	}
128	intermediatePath := android.PathForModuleOut(
129		ctx, "intermediateCodeMetadata.pb",
130	)
131	android.WriteFileRuleVerbatim(ctx, intermediatePath, string(protoData))
132
133	android.SetProvider(ctx,
134		CodeMetadataProviderKey,
135		CodeMetadataProviderData{IntermediatePath: intermediatePath},
136	)
137}
138