mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 18:13:42 +08:00 
			
		
		
		
	Update the buildflags cty code to handle unknown values. When hcl decodes a value with an invalid variable name, it appends a diagnostic for the error and then returns an unknown value so it can continue processing the file and finding more errors. The iteration code has now been changed to use a rangefunc from go 1.23 and it skips empty or unknown values. Empty values are valid when they are skipped and unknown values will have a diagnostic for itself. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
		
			
				
	
	
		
			74 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package buildflags
 | 
						|
 | 
						|
import (
 | 
						|
	"iter"
 | 
						|
 | 
						|
	"github.com/zclconf/go-cty/cty"
 | 
						|
	"github.com/zclconf/go-cty/cty/gocty"
 | 
						|
)
 | 
						|
 | 
						|
type comparable[E any] interface {
 | 
						|
	Equal(other E) bool
 | 
						|
}
 | 
						|
 | 
						|
func removeDupes[E comparable[E]](s []E) []E {
 | 
						|
	// Move backwards through the slice.
 | 
						|
	// For each element, any elements after the current element are unique.
 | 
						|
	// If we find our current element conflicts with an existing element,
 | 
						|
	// then we swap the offender with the end of the slice and chop it off.
 | 
						|
 | 
						|
	// Start at the second to last element.
 | 
						|
	// The last element is always unique.
 | 
						|
	for i := len(s) - 2; i >= 0; i-- {
 | 
						|
		elem := s[i]
 | 
						|
		// Check for duplicates after our current element.
 | 
						|
		for j := i + 1; j < len(s); j++ {
 | 
						|
			if elem.Equal(s[j]) {
 | 
						|
				// Found a duplicate, exchange the
 | 
						|
				// duplicate with the last element.
 | 
						|
				s[j], s[len(s)-1] = s[len(s)-1], s[j]
 | 
						|
				s = s[:len(s)-1]
 | 
						|
				break
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return s
 | 
						|
}
 | 
						|
 | 
						|
func getAndDelete(m map[string]cty.Value, attr string, gv interface{}) error {
 | 
						|
	if v, ok := m[attr]; ok && v.IsKnown() {
 | 
						|
		delete(m, attr)
 | 
						|
		return gocty.FromCtyValue(v, gv)
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func asMap(m map[string]cty.Value) map[string]string {
 | 
						|
	out := make(map[string]string, len(m))
 | 
						|
	for k, v := range m {
 | 
						|
		if v.IsKnown() {
 | 
						|
			out[k] = v.AsString()
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return out
 | 
						|
}
 | 
						|
 | 
						|
func isEmptyOrUnknown(v cty.Value) bool {
 | 
						|
	return !v.IsKnown() || (v.Type() == cty.String && v.AsString() == "")
 | 
						|
}
 | 
						|
 | 
						|
func eachElement(in cty.Value) iter.Seq[cty.Value] {
 | 
						|
	return func(yield func(v cty.Value) bool) {
 | 
						|
		for elem := in.ElementIterator(); elem.Next(); {
 | 
						|
			_, value := elem.Element()
 | 
						|
			if isEmptyOrUnknown(value) {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
 | 
						|
			if !yield(value) {
 | 
						|
				return
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |