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 39type BuilderAndOtherModuleProviderContext interface { 40 BuilderContext 41 OtherModuleProviderContext 42} 43 44func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...Module) Paths { 45 result := make(Paths, 0, len(modules)) 46 mctx, isMctx := ctx.(ModuleContext) 47 for _, module := range modules { 48 var mf Path 49 if isMctx && mctx.Module() == module { 50 mf = mctx.LicenseMetadataFile() 51 } else { 52 mf = OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile 53 } 54 if mf != nil { 55 result = append(result, mf) 56 } 57 } 58 return result 59} 60 61// buildNoticeOutputFromLicenseMetadata writes out a notice file. 62func buildNoticeOutputFromLicenseMetadata( 63 ctx BuilderAndOtherModuleProviderContext, tool, ruleName string, outputFile WritablePath, 64 libraryName string, stripPrefix []string, modules ...Module) { 65 depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", ".")) 66 rule := NewRuleBuilder(pctx, ctx) 67 if len(modules) == 0 { 68 if mctx, ok := ctx.(ModuleContext); ok { 69 modules = []Module{mctx.Module()} 70 } else { 71 panic(fmt.Errorf("%s %q needs a module to generate the notice for", ruleName, libraryName)) 72 } 73 } 74 if libraryName == "" { 75 libraryName = modules[0].Name() 76 } 77 cmd := rule.Command(). 78 BuiltTool(tool). 79 FlagWithOutput("-o ", outputFile). 80 FlagWithDepFile("-d ", depsFile) 81 if len(stripPrefix) > 0 { 82 cmd = cmd.FlagForEachArg("--strip_prefix ", stripPrefix) 83 } 84 outputs := modulesOutputDirs(ctx, modules...) 85 if len(outputs) > 0 { 86 cmd = cmd.FlagForEachArg("--strip_prefix ", outputs) 87 } 88 if libraryName != "" { 89 cmd = cmd.FlagWithArg("--product ", libraryName) 90 } 91 cmd = cmd.Inputs(modulesLicenseMetadata(ctx, modules...)) 92 rule.Build(ruleName, "container notice file") 93} 94 95// BuildNoticeTextOutputFromLicenseMetadata writes out a notice text file based 96// on the license metadata files for the input `modules` defaulting to the 97// current context module if none given. 98func BuildNoticeTextOutputFromLicenseMetadata( 99 ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string, 100 stripPrefix []string, modules ...Module) { 101 buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice_"+ruleName, 102 outputFile, libraryName, stripPrefix, modules...) 103} 104 105// BuildNoticeHtmlOutputFromLicenseMetadata writes out a notice text file based 106// on the license metadata files for the input `modules` defaulting to the 107// current context module if none given. 108func BuildNoticeHtmlOutputFromLicenseMetadata( 109 ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string, 110 stripPrefix []string, modules ...Module) { 111 buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice_"+ruleName, 112 outputFile, libraryName, stripPrefix, modules...) 113} 114 115// BuildNoticeXmlOutputFromLicenseMetadata writes out a notice text file based 116// on the license metadata files for the input `modules` defaulting to the 117// current context module if none given. 118func BuildNoticeXmlOutputFromLicenseMetadata( 119 ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string, 120 stripPrefix []string, modules ...Module) { 121 buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice_"+ruleName, 122 outputFile, libraryName, stripPrefix, modules...) 123} 124