166 lines
4.5 KiB
Go
166 lines
4.5 KiB
Go
// Copyright 2021 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package compliance
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// LicenseCondition describes an individual license condition or requirement
|
|
// originating at a specific target node. (immutable)
|
|
//
|
|
// e.g. A module licensed under GPL terms would originate a `restricted` condition.
|
|
type LicenseCondition struct {
|
|
name string
|
|
origin *TargetNode
|
|
}
|
|
|
|
// Name returns the name of the condition. e.g. "restricted" or "notice"
|
|
func (lc LicenseCondition) Name() string {
|
|
return lc.name
|
|
}
|
|
|
|
// Origin identifies the TargetNode where the condition originates.
|
|
func (lc LicenseCondition) Origin() *TargetNode {
|
|
return lc.origin
|
|
}
|
|
|
|
// asString returns a string representation of a license condition:
|
|
// origin+separator+condition.
|
|
func (lc LicenseCondition) asString(separator string) string {
|
|
return lc.origin.name + separator + lc.name
|
|
}
|
|
|
|
// ConditionList implements introspection methods to arrays of LicenseCondition.
|
|
type ConditionList []LicenseCondition
|
|
|
|
|
|
// ConditionList orders arrays of LicenseCondition by Origin and Name.
|
|
|
|
// Len returns the length of the list.
|
|
func (l ConditionList) Len() int { return len(l) }
|
|
|
|
// Swap rearranges 2 elements in the list so each occupies the other's former position.
|
|
func (l ConditionList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
|
|
|
|
// Less returns true when the `i`th element is lexicographically less than tht `j`th element.
|
|
func (l ConditionList) Less(i, j int) bool {
|
|
if l[i].origin.name == l[j].origin.name {
|
|
return l[i].name < l[j].name
|
|
}
|
|
return l[i].origin.name < l[j].origin.name
|
|
}
|
|
|
|
// String returns a string representation of the set.
|
|
func (cl ConditionList) String() string {
|
|
var sb strings.Builder
|
|
fmt.Fprintf(&sb, "[")
|
|
sep := ""
|
|
for _, lc := range cl {
|
|
fmt.Fprintf(&sb, "%s%s:%s", sep, lc.origin.name, lc.name)
|
|
sep = ", "
|
|
}
|
|
fmt.Fprintf(&sb, "]")
|
|
return sb.String()
|
|
}
|
|
|
|
// Names returns the list of the conditions' names.
|
|
func (cl ConditionList) Names() []string {
|
|
result := make([]string, 0, len(cl))
|
|
for _, lc := range cl {
|
|
result = append(result, lc.name)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// HasByName returns true if the list contains any condition matching `name`.
|
|
func (cl ConditionList) HasByName(name ConditionNames) bool {
|
|
for _, lc := range cl {
|
|
if name.Contains(lc.name) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ByName returns the sublist of conditions that match `name`.
|
|
func (cl ConditionList) ByName(name ConditionNames) ConditionList {
|
|
result := make(ConditionList, 0, cl.CountByName(name))
|
|
for _, lc := range cl {
|
|
if name.Contains(lc.name) {
|
|
result = append(result, lc)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// CountByName returns the size of the sublist of conditions that match `name`.
|
|
func (cl ConditionList) CountByName(name ConditionNames) int {
|
|
size := 0
|
|
for _, lc := range cl {
|
|
if name.Contains(lc.name) {
|
|
size++
|
|
}
|
|
}
|
|
return size
|
|
}
|
|
|
|
// HasByOrigin returns true if the list contains any condition originating at `origin`.
|
|
func (cl ConditionList) HasByOrigin(origin *TargetNode) bool {
|
|
for _, lc := range cl {
|
|
if lc.origin.name == origin.name {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ByOrigin returns the sublist of conditions that originate at `origin`.
|
|
func (cl ConditionList) ByOrigin(origin *TargetNode) ConditionList {
|
|
result := make(ConditionList, 0, cl.CountByOrigin(origin))
|
|
for _, lc := range cl {
|
|
if lc.origin.name == origin.name {
|
|
result = append(result, lc)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// CountByOrigin returns the size of the sublist of conditions that originate at `origin`.
|
|
func (cl ConditionList) CountByOrigin(origin *TargetNode) int {
|
|
size := 0
|
|
for _, lc := range cl {
|
|
if lc.origin.name == origin.name {
|
|
size++
|
|
}
|
|
}
|
|
return size
|
|
}
|
|
|
|
// ConditionNames implements the Contains predicate for slices of condition
|
|
// name strings.
|
|
type ConditionNames []string
|
|
|
|
// Contains returns true if the name matches one of the ConditionNames.
|
|
func (cn ConditionNames) Contains(name string) bool {
|
|
for _, cname := range cn {
|
|
if cname == name {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|