mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-10-31 16:13:45 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2017 Google Inc. All Rights Reserved.
 | |
| //
 | |
| // 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 compiler
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"os/exec"
 | |
| 
 | |
| 	"strings"
 | |
| 
 | |
| 	"errors"
 | |
| 
 | |
| 	"github.com/golang/protobuf/proto"
 | |
| 	"github.com/golang/protobuf/ptypes/any"
 | |
| 	ext_plugin "github.com/googleapis/gnostic/extensions"
 | |
| 	yaml "gopkg.in/yaml.v2"
 | |
| )
 | |
| 
 | |
| // ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.
 | |
| type ExtensionHandler struct {
 | |
| 	Name string
 | |
| }
 | |
| 
 | |
| // HandleExtension calls a binary extension handler.
 | |
| func HandleExtension(context *Context, in interface{}, extensionName string) (bool, *any.Any, error) {
 | |
| 	handled := false
 | |
| 	var errFromPlugin error
 | |
| 	var outFromPlugin *any.Any
 | |
| 
 | |
| 	if context != nil && context.ExtensionHandlers != nil && len(*(context.ExtensionHandlers)) != 0 {
 | |
| 		for _, customAnyProtoGenerator := range *(context.ExtensionHandlers) {
 | |
| 			outFromPlugin, errFromPlugin = customAnyProtoGenerator.handle(in, extensionName)
 | |
| 			if outFromPlugin == nil {
 | |
| 				continue
 | |
| 			} else {
 | |
| 				handled = true
 | |
| 				break
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return handled, outFromPlugin, errFromPlugin
 | |
| }
 | |
| 
 | |
| func (extensionHandlers *ExtensionHandler) handle(in interface{}, extensionName string) (*any.Any, error) {
 | |
| 	if extensionHandlers.Name != "" {
 | |
| 		binary, _ := yaml.Marshal(in)
 | |
| 
 | |
| 		request := &ext_plugin.ExtensionHandlerRequest{}
 | |
| 
 | |
| 		version := &ext_plugin.Version{}
 | |
| 		version.Major = 0
 | |
| 		version.Minor = 1
 | |
| 		version.Patch = 0
 | |
| 		request.CompilerVersion = version
 | |
| 
 | |
| 		request.Wrapper = &ext_plugin.Wrapper{}
 | |
| 
 | |
| 		request.Wrapper.Version = "v2"
 | |
| 		request.Wrapper.Yaml = string(binary)
 | |
| 		request.Wrapper.ExtensionName = extensionName
 | |
| 
 | |
| 		requestBytes, _ := proto.Marshal(request)
 | |
| 		cmd := exec.Command(extensionHandlers.Name)
 | |
| 		cmd.Stdin = bytes.NewReader(requestBytes)
 | |
| 		output, err := cmd.Output()
 | |
| 
 | |
| 		if err != nil {
 | |
| 			fmt.Printf("Error: %+v\n", err)
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		response := &ext_plugin.ExtensionHandlerResponse{}
 | |
| 		err = proto.Unmarshal(output, response)
 | |
| 		if err != nil {
 | |
| 			fmt.Printf("Error: %+v\n", err)
 | |
| 			fmt.Printf("%s\n", string(output))
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		if !response.Handled {
 | |
| 			return nil, nil
 | |
| 		}
 | |
| 		if len(response.Error) != 0 {
 | |
| 			message := fmt.Sprintf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Error, ","))
 | |
| 			return nil, errors.New(message)
 | |
| 		}
 | |
| 		return response.Value, nil
 | |
| 	}
 | |
| 	return nil, nil
 | |
| }
 | 
