Files
build/tools/compliance/policy/walk.go
Bob Badour 9ee7d03e1c compliance package policy and resolves
package to read, consume, and analyze license metadata and dependency
graph.

Bug: 68860345
Bug: 151177513
Bug: 151953481

Change-Id: Ic08406fa2250a08ad26f2167d934f841c95d9148
2021-12-03 15:52:48 -08:00

77 lines
2.2 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
// VisitNode is called for each root and for each walked dependency node by
// WalkTopDown. When VisitNode returns true, WalkTopDown will proceed to walk
// down the dependences of the node
type VisitNode func(*LicenseGraph, *TargetNode, TargetEdgePath) bool
// WalkTopDown does a top-down walk of `lg` calling `visit` and descending
// into depenencies when `visit` returns true.
func WalkTopDown(lg *LicenseGraph, visit VisitNode) {
path := NewTargetEdgePath(32)
// must be indexed for fast lookup
lg.indexForward()
var walk func(f string)
walk = func(f string) {
visitChildren := visit(lg, lg.targets[f], *path)
if !visitChildren {
return
}
for _, edge := range lg.index[f] {
path.Push(TargetEdge{lg, edge})
walk(edge.dependency)
path.Pop()
}
}
for _, r := range lg.rootFiles {
path.Clear()
walk(r)
}
}
// WalkResolutionsForCondition performs a top-down walk of the LicenseGraph
// resolving all distributed works for condition `names`.
func WalkResolutionsForCondition(lg *LicenseGraph, rs *ResolutionSet, names ConditionNames) *ResolutionSet {
shipped := ShippedNodes(lg)
// rmap maps 'attachesTo' targets to the `actsOn` targets and applicable conditions
//
// rmap is the resulting ResolutionSet
rmap := make(map[*TargetNode]actionSet)
WalkTopDown(lg, func(lg *LicenseGraph, tn *TargetNode, _ TargetEdgePath) bool {
if _, ok := rmap[tn]; ok {
return false
}
if !shipped.Contains(tn) {
return false
}
if as, ok := rs.resolutions[tn]; ok {
fas := as.byActsOn(shipped).byName(names)
if !fas.isEmpty() {
rmap[tn] = fas
}
}
return tn.IsContainer() // descend into containers
})
return &ResolutionSet{rmap}
}