1// Copyright 2020 Google Inc. 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 classifier 16 17import ( 18 "fmt" 19 "strings" 20) 21 22// This file contains routines for a simple trace execution mechanism. 23 24// TraceConfiguration specifies the configuration for tracing execution of the 25// license classifier. 26type TraceConfiguration struct { 27 // Comma-separated list of phases to be traced. Can use * for all phases. 28 TracePhases string 29 // Comma-separated list of licenses to be traced. Can use * as a suffix to 30 // match prefixes, or by itself to match all licenses. 31 TraceLicenses string 32 33 // Tracer specifies a TraceFunc used to capture tracing information. 34 // If not supplied, emits using fmt.Printf 35 Tracer TraceFunc 36 tracePhases map[string]bool 37 traceLicenses map[string]bool 38} 39 40func (t *TraceConfiguration) init() { 41 if t == nil { 42 return 43 } 44 // Sample the config values to create the lookup maps 45 t.traceLicenses = make(map[string]bool) 46 t.tracePhases = make(map[string]bool) 47 48 if len(t.TraceLicenses) > 0 { 49 for _, lic := range strings.Split(t.TraceLicenses, ",") { 50 t.traceLicenses[lic] = true 51 } 52 } 53 54 if len(t.TracePhases) > 0 { 55 for _, phase := range strings.Split(t.TracePhases, ",") { 56 t.tracePhases[phase] = true 57 } 58 } 59} 60 61var traceLicenses map[string]bool 62var tracePhases map[string]bool 63 64func (t *TraceConfiguration) shouldTrace(phase string) bool { 65 if t == nil { 66 return false 67 } 68 if t.tracePhases["*"] { 69 return true 70 } 71 return t.tracePhases[phase] 72} 73 74func (t *TraceConfiguration) isTraceLicense(lic string) bool { 75 if t == nil { 76 return false 77 } 78 if t.traceLicenses[lic] { 79 return true 80 } 81 82 for e := range t.traceLicenses { 83 if idx := strings.Index(e, "*"); idx != -1 { 84 if strings.HasPrefix(lic, e[0:idx]) { 85 return true 86 } 87 } 88 } 89 90 return false 91} 92 93func (t *TraceConfiguration) trace(f string, args ...interface{}) { 94 if t == nil || t.Tracer == nil { 95 fmt.Printf(f, args...) 96 fmt.Println() 97 return 98 } 99 100 t.Tracer(f, args...) 101} 102 103func (t *TraceConfiguration) traceSearchset(lic string) bool { 104 return t.isTraceLicense(lic) && t.shouldTrace("searchset") 105} 106 107func (t *TraceConfiguration) traceTokenize(lic string) bool { 108 return t.isTraceLicense(lic) && t.shouldTrace("tokenize") 109} 110 111func (t *TraceConfiguration) traceScoring(lic string) bool { 112 return t.isTraceLicense(lic) && t.shouldTrace("score") 113} 114 115func (t *TraceConfiguration) traceFrequency(lic string) bool { 116 return t.isTraceLicense(lic) && t.shouldTrace("frequency") 117} 118 119// TraceFunc works like fmt.Printf to emit tracing data for the 120// classifier. 121type TraceFunc func(string, ...interface{}) 122