»Passing Values Between Components

To pass values between components, you can ask Waypoint to inject a previous component's Output Value. For example, the next component after the Builder is the Registry component. The following code snippet shows that by defining a parameter for the Binary type, Waypoint automatically injects the reference to the Binary type that was output from the Builder component.

func (r *Registry) PushFunc() interface{} {
  return r.push
}

func (r *Registry) push(
  ctx context.Context,
  log hclog.Logger,
  ui terminal.UI,
  b *build.Binary,
) (*Artifact, error) {
  return nil, nil
}

Output Values like build.Binary returned by the push function need to be serializable to the Protocol Buffer binary format. To enable this, rather than define data models as structs in Go, you create Protocol Buffer definitions and generate the Go code using the protoc tool.

Let’s look at build.Binary and see how it is defined. Protocol Buffer files are commonly defined in files with the extension .proto.

The first line in a Protocol Buffer file is the syntax definition; this is set to proto3 to use the Protocol Buffers version three.

syntax = "proto3";

Then you define the Protocol Buffers package; in this example, the package is set to builder, which is the same package as the component.

package builder;

You can then specify the go_package; this again is set to the same package where the component is defined but uses the full go package reference.

option go_package = "github.com/hashicorp/waypoint-plugin-examples/golang/builder";

Finally, you can define the message, if you have not used Protocol Buffers before, conceptually a struct in Go is a message in Protocol Buffers. Defining the build.Binary Output Value looks like the following. A message Binary is defined, which has a single field path.

message Binary {
  string path = 1;
}

When the Go code a generated, the previous message will create a Go struct, which looks like the following.

type Binary struct {
  Path string
}

The full example can be seen below.

syntax = "proto3";

package builder;

option go_package = "github.com/hashicorp/waypoint-plugin-examples/golang/builder";

message Binary {
  string path = 1;
}

To generate the Go code you use the protoc command setting the correct flags. The --go_opt=plugins=grpc:./ flag specifies that you want to use the Go gRPC plugin to generate the code, and that the output directory for the generated code will be .

By default the go plugin for gRPC uses the go_package path and the output directory specfied in the -go_opt flag as the location for the generated code. You can change this behaviour by setting the flag --go_opt=paths=source_relative. The generated code will now be created at a path relative to the intput proto file.

Finally, you specify the proto files you would like to generate code for; this is the plugin.proto file in the current directory.

protoc -I . --go_out=plugins=grpc:. --go_opt=paths=source_relative ./output.proto

If successful, the command will not output any text but generates a file called output.pb.go in the same directory as the output.proto file.

The output.proto file contains the struct definition for the Binary message and the code that enables the serialization of the model to the Protocol Buffer binary format. This file should never be manually edited, if you need to make changes to your Output Type, you should always modify the .proto file and regenerate the Go code using the protoc command.

Full information on defining messages using Protocol Buffers can be found in the following document.

https://developers.google.com/protocol-buffers/docs/proto3