blob: 1be4a34887f110f0e3a66276b947ccc039723bc0 [file] [log] [blame]
Bob Badoura99ac622021-10-25 16:21:00 -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 compliance
16
17import (
18 "fmt"
19 "strings"
20)
21
Bob Badoura99ac622021-10-25 16:21:00 -070022// ResolutionSet describes an immutable set of targets and the license
23// conditions each target must satisfy or "resolve" in a specific context.
24//
25// Ultimately, the purpose of recording the license metadata and building a
26// license graph is to identify, describe, and verify the necessary actions or
27// operations for compliance policy.
28//
29// i.e. What is the source-sharing policy? Has it been met? Meet it.
30//
31// i.e. Are there incompatible policy requirements? Such as a source-sharing
32// policy applied to code that policy also says may not be shared? If so, stop
33// and remove the dependencies that create the situation.
34//
35// The ResolutionSet is the base unit for mapping license conditions to the
36// targets triggering some necessary action per policy. Different ResolutionSet
37// values may be calculated for different contexts.
38//
39// e.g. Suppose an unencumbered binary links in a notice .a library.
40//
41// An "unencumbered" condition would originate from the binary, and a "notice"
42// condition would originate from the .a library. A ResolutionSet for the
Bob Badour103eb0f2022-01-10 13:50:57 -080043// context of the Notice policy might attach both conditions to the binary to
44// act on the origin of each condition. By attaching the notice condition to
Bob Badoura99ac622021-10-25 16:21:00 -070045// the binary, the ResolutionSet stipulates the policy that the release of the
46// unencumbered binary must provide suitable notice for the .a library.
47//
48// The resulting ResolutionSet could be used for building a notice file, for
49// validating that a suitable notice has been built into the distribution, or
50// for reporting what notices need to be given.
51//
Bob Badour103eb0f2022-01-10 13:50:57 -080052// The action is defined by the context. In the above example, the action is
53// providing notice for the module acted on. In another context, the action
54// might be sharing the source-code or preserving the privacy of the module
55// acted on.
56type ResolutionSet map[*TargetNode]ActionSet
57
58// AttachesTo identifies the list of targets triggering action to resolve
59// conditions. (unordered)
60func (rs ResolutionSet) AttachesTo() TargetNodeList {
61 result := make(TargetNodeList, 0, len(rs))
62 for attachesTo := range rs {
63 result = append(result, attachesTo)
64 }
65 return result
Bob Badoura99ac622021-10-25 16:21:00 -070066}
67
Bob Badour103eb0f2022-01-10 13:50:57 -080068// AttachesToTarget returns true if the set contains conditions that
69// are `attachedTo`.
70func (rs ResolutionSet) AttachesToTarget(target *TargetNode) bool {
71 _, isPresent := rs[target]
72 return isPresent
73}
74
Bob Badour085a2c22022-09-21 19:36:59 -070075// IsPureAggregate returns true if `target`, which must be in
76// `AttachesTo()` resolves to a pure aggregate in the resolution.
77func (rs ResolutionSet) IsPureAggregate(target *TargetNode) bool {
78 _, isPresent := rs[target]
79 if !isPresent {
80 panic(fmt.Errorf("ResolutionSet.IsPureAggregate(%s): not attached to %s", target.Name(), target.Name()))
81 }
82 return target.pure
83}
84
Bob Badour103eb0f2022-01-10 13:50:57 -080085// Resolutions returns the list of resolutions that `attachedTo`
86// target must resolve. Returns empty list if no conditions apply.
87func (rs ResolutionSet) Resolutions(attachesTo *TargetNode) ResolutionList {
88 as, ok := rs[attachesTo]
89 if !ok {
90 return nil
91 }
92 result := make(ResolutionList, 0, len(as))
93 for actsOn, cs := range as {
94 result = append(result, Resolution{attachesTo, actsOn, cs})
95 }
96 return result
97}
98
Bob Badourc8178452022-01-31 13:05:53 -080099// AllActions returns the set of actions required to resolve the set omitting
100// the attachment.
101func (rs ResolutionSet) AllActions() ActionSet {
102 result := make(ActionSet)
103 for _, as := range rs {
104 for actsOn, cs := range as {
105 if _, ok := result[actsOn]; ok {
106 result[actsOn] = cs.Union(result[actsOn])
107 } else {
108 result[actsOn] = cs
109 }
110 }
111 }
112 return result
113}
114
Bob Badour103eb0f2022-01-10 13:50:57 -0800115// String returns a human-readable string representation of the set.
116func (rs ResolutionSet) String() string {
Bob Badoura99ac622021-10-25 16:21:00 -0700117 var sb strings.Builder
118 fmt.Fprintf(&sb, "{")
119 sep := ""
Bob Badour103eb0f2022-01-10 13:50:57 -0800120 for attachesTo, as := range rs {
121 fmt.Fprintf(&sb, "%s%s -> %s", sep, attachesTo.Name(), as.String())
Bob Badoura99ac622021-10-25 16:21:00 -0700122 sep = ", "
123 }
124 fmt.Fprintf(&sb, "}")
125 return sb.String()
126}
127
Bob Badour103eb0f2022-01-10 13:50:57 -0800128// ActionSet identifies a set of targets to act on and the license conditions
129// the action will resolve.
130type ActionSet map[*TargetNode]LicenseConditionSet
Bob Badoura99ac622021-10-25 16:21:00 -0700131
Bob Badour103eb0f2022-01-10 13:50:57 -0800132// String returns a human-readable string representation of the set.
133func (as ActionSet) String() string {
134 var sb strings.Builder
135 fmt.Fprintf(&sb, "{")
136 sep := ""
Bob Badoura99ac622021-10-25 16:21:00 -0700137 for actsOn, cs := range as {
Bob Badour103eb0f2022-01-10 13:50:57 -0800138 fmt.Fprintf(&sb, "%s%s%s", sep, actsOn.Name(), cs.String())
139 sep = ", "
Bob Badoura99ac622021-10-25 16:21:00 -0700140 }
Bob Badour103eb0f2022-01-10 13:50:57 -0800141 fmt.Fprintf(&sb, "}")
142 return sb.String()
Bob Badoura99ac622021-10-25 16:21:00 -0700143}