1// Copyright 2019 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 android
16
17import (
18	"fmt"
19	"path/filepath"
20	"strings"
21)
22
23func modulesOutputDirs(ctx BuilderContext, modules ...Module) []string {
24	dirs := make([]string, 0, len(modules))
25	for _, module := range modules {
26		paths, err := outputFilesForModule(ctx, module, "")
27		if err != nil {
28			continue
29		}
30		for _, path := range paths {
31			if path != nil {
32				dirs = append(dirs, filepath.Dir(path.String()))
33			}
34		}
35	}
36	return SortedUniqueStrings(dirs)
37}
38
39func modulesLicenseMetadata(ctx BuilderContext, modules ...Module) Paths {
40	result := make(Paths, 0, len(modules))
41	for _, module := range modules {
42		if mf := module.base().licenseMetadataFile; mf != nil {
43			result = append(result, mf)
44		}
45	}
46	return result
47}
48
49// buildNoticeOutputFromLicenseMetadata writes out a notice file.
50func buildNoticeOutputFromLicenseMetadata(
51	ctx BuilderContext, tool, ruleName string, outputFile WritablePath,
52	libraryName string, stripPrefix []string, modules ...Module) {
53	depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", "."))
54	rule := NewRuleBuilder(pctx, ctx)
55	if len(modules) == 0 {
56		if mctx, ok := ctx.(ModuleContext); ok {
57			modules = []Module{mctx.Module()}
58		} else {
59			panic(fmt.Errorf("%s %q needs a module to generate the notice for", ruleName, libraryName))
60		}
61	}
62	if libraryName == "" {
63		libraryName = modules[0].Name()
64	}
65	cmd := rule.Command().
66		BuiltTool(tool).
67		FlagWithOutput("-o ", outputFile).
68		FlagWithDepFile("-d ", depsFile)
69	if len(stripPrefix) > 0 {
70		cmd = cmd.FlagForEachArg("--strip_prefix ", stripPrefix)
71	}
72	outputs := modulesOutputDirs(ctx, modules...)
73	if len(outputs) > 0 {
74		cmd = cmd.FlagForEachArg("--strip_prefix ", outputs)
75	}
76	if libraryName != "" {
77		cmd = cmd.FlagWithArg("--product ", libraryName)
78	}
79	cmd = cmd.Inputs(modulesLicenseMetadata(ctx, modules...))
80	rule.Build(ruleName, "container notice file")
81}
82
83// BuildNoticeTextOutputFromLicenseMetadata writes out a notice text file based
84// on the license metadata files for the input `modules` defaulting to the
85// current context module if none given.
86func BuildNoticeTextOutputFromLicenseMetadata(
87	ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
88	stripPrefix []string, modules ...Module) {
89	buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice_"+ruleName,
90		outputFile, libraryName, stripPrefix, modules...)
91}
92
93// BuildNoticeHtmlOutputFromLicenseMetadata writes out a notice text file based
94// on the license metadata files for the input `modules` defaulting to the
95// current context module if none given.
96func BuildNoticeHtmlOutputFromLicenseMetadata(
97	ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
98	stripPrefix []string, modules ...Module) {
99	buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice_"+ruleName,
100		outputFile, libraryName, stripPrefix, modules...)
101}
102
103// BuildNoticeXmlOutputFromLicenseMetadata writes out a notice text file based
104// on the license metadata files for the input `modules` defaulting to the
105// current context module if none given.
106func BuildNoticeXmlOutputFromLicenseMetadata(
107	ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
108	stripPrefix []string, modules ...Module) {
109	buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice_"+ruleName,
110		outputFile, libraryName, stripPrefix, modules...)
111}
112