github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/pkg/plugintest/utils.go (about)

     1  package plugintest
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/bazelbuild/bazel-gazelle/label"
    11  	"github.com/bazelbuild/bazel-gazelle/rule"
    12  	"github.com/stackb/rules_proto/pkg/protoc"
    13  )
    14  
    15  // PluginConfigurationOption modifies a configuration in-place
    16  type PluginConfigurationOption func(c *protoc.PluginConfiguration)
    17  
    18  // WithConfiguration creates a new PluginConfiguration and applies all the given
    19  // options.
    20  func WithConfiguration(options ...PluginConfigurationOption) *protoc.PluginConfiguration {
    21  	c := &protoc.PluginConfiguration{}
    22  	for _, opt := range options {
    23  		opt(c)
    24  	}
    25  	return c
    26  }
    27  
    28  // WithOutputs assigns the Outputs field.
    29  func WithOutputs(outputs ...string) PluginConfigurationOption {
    30  	return func(c *protoc.PluginConfiguration) {
    31  		c.Outputs = outputs
    32  	}
    33  }
    34  
    35  // WithOptions assigns the Options field.
    36  func WithOptions(options ...string) PluginConfigurationOption {
    37  	return func(c *protoc.PluginConfiguration) {
    38  		c.Options = options
    39  	}
    40  }
    41  
    42  // WithOut assigns the Out field.
    43  func WithOut(out string) PluginConfigurationOption {
    44  	return func(c *protoc.PluginConfiguration) {
    45  		c.Out = out
    46  	}
    47  }
    48  
    49  // WithLabel assigns the Label field.
    50  func WithLabel(t *testing.T, raw string) PluginConfigurationOption {
    51  	return func(c *protoc.PluginConfiguration) {
    52  		lbl, err := label.Parse(raw)
    53  		if err != nil {
    54  			t.Fatalf("bad label %q: %v", raw, err)
    55  		}
    56  		c.Label = lbl
    57  	}
    58  }
    59  
    60  // WithDirectives assigns rule Directives.
    61  func WithDirectives(items ...string) (d []rule.Directive) {
    62  	if len(items)%2 != 0 {
    63  		panic("directive list must be a sequence of key/value pairs")
    64  	}
    65  	if len(items) < 2 {
    66  		return
    67  	}
    68  	for i := 1; i < len(items); i = i + 2 {
    69  		d = append(d, rule.Directive{Key: items[i-1], Value: items[i]})
    70  	}
    71  	return
    72  }
    73  
    74  func mustExecProtoc(t *testing.T, protoc, dir string, env []string, args ...string) {
    75  	cmd := exec.Command(protoc, args...)
    76  	cmd.Dir = dir
    77  	cmd.Env = env
    78  	out, err := cmd.CombinedOutput()
    79  	if err != nil {
    80  		t.Fatalf("protoc exec error: %v\n\n%s", err, out)
    81  	}
    82  }
    83  
    84  // mustListFiles - convenience debugging function to log the files under a given
    85  // dir, excluding proto files and the extra binaries here.
    86  func mustListFiles(t *testing.T, dir string) []string {
    87  	files := make([]string, 0)
    88  
    89  	if err := filepath.Walk(dir, func(relname string, info os.FileInfo, err error) error {
    90  		if err != nil {
    91  			t.Fatal(err)
    92  		}
    93  		if info.IsDir() {
    94  			return nil
    95  		}
    96  		if filepath.Ext(relname) == ".proto" {
    97  			return nil
    98  		}
    99  		files = append(files, relname)
   100  		return nil
   101  	}); err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	return files
   106  }
   107  
   108  // fileExists checks if a file exists and is not a directory before we try using
   109  // it to prevent further errors.
   110  func fileExists(filename string) bool {
   111  	info, err := os.Stat(filename)
   112  	if os.IsNotExist(err) {
   113  		return false
   114  	}
   115  	if info == nil {
   116  		return false
   117  	}
   118  	return !info.IsDir()
   119  }
   120  
   121  // listFiles - convenience debugging function to log the files under a given dir
   122  func listFiles(dir string) error {
   123  	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
   124  		if err != nil {
   125  			log.Printf("%v\n", err)
   126  			return err
   127  		}
   128  		if info.Mode()&os.ModeSymlink > 0 {
   129  			link, err := os.Readlink(path)
   130  			if err != nil {
   131  				return err
   132  			}
   133  			log.Printf("%s -> %s", path, link)
   134  			return nil
   135  		}
   136  
   137  		log.Println(path)
   138  		return nil
   139  	})
   140  }