blob: 030caa7fd0e386ac4e049ceb74924c94a3189343 [file] [log] [blame]
Bob Badour6dd00352021-10-01 15:21:58 -07001// Copyright 2021 Google LLC
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 (
Bob Badour6dd00352021-10-01 15:21:58 -070018 "flag"
19 "fmt"
20 "io"
21 "os"
22 "path/filepath"
23 "sort"
Bob Badour103eb0f2022-01-10 13:50:57 -080024 "strings"
Colin Cross38a61932022-01-27 15:26:49 -080025
26 "android/soong/tools/compliance"
Bob Badour6dd00352021-10-01 15:21:58 -070027)
28
29func init() {
30 flag.Usage = func() {
31 fmt.Fprintf(os.Stderr, `Usage: %s file.meta_lic {file.meta_lic...}
32
33Outputs a csv file with 1 project per line in the first field followed
34by target:condition pairs describing why the project must be shared.
35
36Each target is the path to a generated license metadata file for a
37Soong module or Make target, and the license condition is either
38restricted (e.g. GPL) or reciprocal (e.g. MPL).
39`, filepath.Base(os.Args[0]))
40 }
41}
42
43var (
44 failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
Colin Cross35f79c32022-01-27 15:18:52 -080045 failNoLicenses = fmt.Errorf("No licenses found")
Bob Badour6dd00352021-10-01 15:21:58 -070046)
47
48func main() {
49 flag.Parse()
50
51 // Must specify at least one root target.
52 if flag.NArg() == 0 {
53 flag.Usage()
54 os.Exit(2)
55 }
56
57 err := listShare(os.Stdout, os.Stderr, flag.Args()...)
58 if err != nil {
59 if err == failNoneRequested {
60 flag.Usage()
61 }
62 fmt.Fprintf(os.Stderr, "%s\n", err.Error())
63 os.Exit(1)
64 }
65 os.Exit(0)
66}
67
68// listShare implements the listshare utility.
69func listShare(stdout, stderr io.Writer, files ...string) error {
70 // Must be at least one root file.
71 if len(files) < 1 {
72 return failNoneRequested
73 }
74
75 // Read the license graph from the license metadata files (*.meta_lic).
76 licenseGraph, err := compliance.ReadLicenseGraph(os.DirFS("."), stderr, files)
77 if err != nil {
78 return fmt.Errorf("Unable to read license metadata file(s) %q: %v\n", files, err)
79 }
80 if licenseGraph == nil {
81 return failNoLicenses
82 }
83
84 // shareSource contains all source-sharing resolutions.
85 shareSource := compliance.ResolveSourceSharing(licenseGraph)
86
87 // Group the resolutions by project.
Bob Badour103eb0f2022-01-10 13:50:57 -080088 presolution := make(map[string]compliance.LicenseConditionSet)
Bob Badour6dd00352021-10-01 15:21:58 -070089 for _, target := range shareSource.AttachesTo() {
90 rl := shareSource.Resolutions(target)
91 sort.Sort(rl)
92 for _, r := range rl {
93 for _, p := range r.ActsOn().Projects() {
94 if _, ok := presolution[p]; !ok {
Bob Badour103eb0f2022-01-10 13:50:57 -080095 presolution[p] = r.Resolves()
Bob Badour6dd00352021-10-01 15:21:58 -070096 continue
97 }
Bob Badour103eb0f2022-01-10 13:50:57 -080098 presolution[p] = presolution[p].Union(r.Resolves())
Bob Badour6dd00352021-10-01 15:21:58 -070099 }
100 }
101 }
102
103 // Sort the projects for repeatability/stability.
104 projects := make([]string, 0, len(presolution))
105 for p := range presolution {
106 projects = append(projects, p)
107 }
108 sort.Strings(projects)
109
110 // Output the sorted projects and the source-sharing license conditions that each project resolves.
111 for _, p := range projects {
Bob Badour103eb0f2022-01-10 13:50:57 -0800112 if presolution[p].IsEmpty() {
113 fmt.Fprintf(stdout, "%s\n", p)
114 } else {
115 fmt.Fprintf(stdout, "%s,%s\n", p, strings.Join(presolution[p].Names(), ","))
Bob Badour6dd00352021-10-01 15:21:58 -0700116 }
Bob Badour6dd00352021-10-01 15:21:58 -0700117 }
118
119 return nil
120}