blob: b26b046d2797943e869e76be6075d7761760f4fa [file] [log] [blame]
Colin Crosscb933592017-11-22 13:49:43 -08001// Copyright 2017 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 java
16
17// Rules for instrumenting classes using jacoco
18
19import (
20 "strings"
21
22 "github.com/google/blueprint"
23
24 "android/soong/android"
25)
26
27var (
28 jacoco = pctx.AndroidStaticRule("jacoco", blueprint.RuleParams{
29 Command: `${config.Zip2ZipCmd} -i $in -o $strippedJar $stripSpec && ` +
30 `${config.JavaCmd} -jar ${config.JacocoCLIJar} instrument -quiet -dest $instrumentedJar $strippedJar && ` +
31 `${config.Ziptime} $instrumentedJar && ` +
32 `${config.MergeZipsCmd} --ignore-duplicates -j $out $instrumentedJar $in`,
33 CommandDeps: []string{
34 "${config.Zip2ZipCmd}",
35 "${config.JavaCmd}",
36 "${config.JacocoCLIJar}",
37 "${config.Ziptime}",
38 "${config.MergeZipsCmd}",
39 },
40 },
41 "strippedJar", "stripSpec", "instrumentedJar")
42)
43
44func jacocoInstrumentJar(ctx android.ModuleContext, outputJar, strippedJar android.WritablePath,
45 inputJar android.Path, stripSpec string) {
46 instrumentedJar := android.PathForModuleOut(ctx, "jacoco/instrumented.jar")
47
48 ctx.Build(pctx, android.BuildParams{
49 Rule: jacoco,
50 Description: "jacoco",
51 Output: outputJar,
52 ImplicitOutput: strippedJar,
53 Input: inputJar,
54 Args: map[string]string{
55 "strippedJar": strippedJar.String(),
56 "stripSpec": stripSpec,
57 "instrumentedJar": instrumentedJar.String(),
58 },
59 })
60}
61
62func (j *Module) jacocoStripSpecs(ctx android.ModuleContext) string {
63 includes := jacocoFiltersToSpecs(ctx,
64 j.properties.Jacoco.Include_filter, "jacoco.include_filter")
65 excludes := jacocoFiltersToSpecs(ctx,
66 j.properties.Jacoco.Exclude_filter, "jacoco.exclude_filter")
67
68 specs := ""
69 if len(excludes) > 0 {
70 specs += android.JoinWithPrefix(excludes, "-x") + " "
71 }
72
73 if len(includes) > 0 {
74 specs += strings.Join(includes, " ")
75 } else {
76 specs += "**/*.class"
77 }
78
79 return specs
80}
81
82func jacocoFiltersToSpecs(ctx android.ModuleContext, filters []string, property string) []string {
83 specs := make([]string, len(filters))
84 for i, f := range filters {
85 specs[i] = jacocoFilterToSpec(ctx, f, property)
86 }
87 return specs
88}
89
90func jacocoFilterToSpec(ctx android.ModuleContext, filter string, property string) string {
91 wildcard := strings.HasSuffix(filter, "*")
92 filter = strings.TrimSuffix(filter, "*")
93 recursiveWildcard := wildcard && (strings.HasSuffix(filter, ".") || filter == "")
94
95 if strings.ContainsRune(filter, '*') {
96 ctx.PropertyErrorf(property, "'*' is only supported as the last character in a filter")
97 }
98
99 spec := strings.Replace(filter, ".", "/", -1)
100
101 if recursiveWildcard {
102 spec += "**/*.class"
103 } else if wildcard {
104 spec += "*.class"
105 }
106
107 return spec
108}