1// Copyright 2022 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 main 16 17import ( 18 "flag" 19 "fmt" 20 "io/ioutil" 21 "os" 22 "strings" 23 24 "google.golang.org/protobuf/encoding/prototext" 25 "google.golang.org/protobuf/proto" 26 27 "android/soong/compliance/license_metadata_proto" 28 "android/soong/response" 29) 30 31func newMultiString(flags *flag.FlagSet, name, usage string) *multiString { 32 var f multiString 33 flags.Var(&f, name, usage) 34 return &f 35} 36 37type multiString []string 38 39func (ms *multiString) String() string { return strings.Join(*ms, ", ") } 40func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil } 41 42func main() { 43 var expandedArgs []string 44 for _, arg := range os.Args[1:] { 45 if strings.HasPrefix(arg, "@") { 46 f, err := os.Open(strings.TrimPrefix(arg, "@")) 47 if err != nil { 48 fmt.Fprintln(os.Stderr, err.Error()) 49 os.Exit(1) 50 } 51 52 respArgs, err := response.ReadRspFile(f) 53 f.Close() 54 if err != nil { 55 fmt.Fprintln(os.Stderr, err.Error()) 56 os.Exit(1) 57 } 58 expandedArgs = append(expandedArgs, respArgs...) 59 } else { 60 expandedArgs = append(expandedArgs, arg) 61 } 62 } 63 64 flags := flag.NewFlagSet("flags", flag.ExitOnError) 65 66 installed := flags.String("i", "", "installed target") 67 sources := newMultiString(flags, "s", "source (input) file") 68 dep := flags.String("d", "", "license metadata file dependency") 69 outFile := flags.String("o", "", "output file") 70 71 flags.Parse(expandedArgs) 72 73 if len(*dep) == 0 || len(*installed) == 0 || len(*sources) == 0 { 74 flags.Usage() 75 if len(*dep) == 0 { 76 fmt.Fprintf(os.Stderr, "source license metadata (-d flag) required\n") 77 } 78 if len(*sources) == 0 { 79 fmt.Fprintf(os.Stderr, "source copy (-s flag required\n") 80 } 81 if len(*installed) == 0 { 82 fmt.Fprintf(os.Stderr, "installed copy (-i flag) required\n") 83 } 84 os.Exit(1) 85 } 86 87 src_metadata := license_metadata_proto.LicenseMetadata{} 88 err := readMetadata(*dep, &src_metadata) 89 if err != nil { 90 fmt.Fprintf(os.Stderr, "error: %s\n", err.Error()) 91 os.Exit(2) 92 } 93 94 metadata := src_metadata 95 metadata.Built = nil 96 metadata.InstallMap = nil 97 metadata.Installed = []string{*installed} 98 metadata.Sources = *sources 99 metadata.Deps = []*license_metadata_proto.AnnotatedDependency{&license_metadata_proto.AnnotatedDependency{ 100 File: proto.String(*dep), 101 Annotations: []string{"static"}, 102 }} 103 104 err = writeMetadata(*outFile, &metadata) 105 if err != nil { 106 fmt.Fprintf(os.Stderr, "error: %s\n", err.Error()) 107 os.Exit(2) 108 } 109} 110 111func readMetadata(file string, metadata *license_metadata_proto.LicenseMetadata) error { 112 if file == "" { 113 return fmt.Errorf("source metadata file (-d) required") 114 } 115 buf, err := ioutil.ReadFile(file) 116 if err != nil { 117 return fmt.Errorf("error reading textproto %q: %w", file, err) 118 } 119 120 err = prototext.Unmarshal(buf, metadata) 121 if err != nil { 122 return fmt.Errorf("error unmarshalling textproto: %w", err) 123 } 124 125 return nil 126} 127 128func writeMetadata(file string, metadata *license_metadata_proto.LicenseMetadata) error { 129 buf, err := prototext.MarshalOptions{Multiline: true}.Marshal(metadata) 130 if err != nil { 131 return fmt.Errorf("error marshalling textproto: %w", err) 132 } 133 134 if file != "" { 135 err = ioutil.WriteFile(file, buf, 0666) 136 if err != nil { 137 return fmt.Errorf("error writing textproto %q: %w", file, err) 138 } 139 } else { 140 _, _ = os.Stdout.Write(buf) 141 } 142 143 return nil 144} 145